diff options
author | Lin Jen-Shin <godfat@godfat.org> | 2017-03-07 16:55:03 +0800 |
---|---|---|
committer | Lin Jen-Shin <godfat@godfat.org> | 2017-03-07 16:55:03 +0800 |
commit | fb167787f2c470649195a5d623f489ec2c3a9117 (patch) | |
tree | ad60222b53a11ee2b29131f57e24ba66dd823c3d /app/assets | |
parent | 7c9cff3a744a64848207bfde1aedcfe652f07dce (diff) | |
parent | 24f1ee5e9b1f4d9bc8cff581419b091756da8deb (diff) | |
download | gitlab-ce-fb167787f2c470649195a5d623f489ec2c3a9117.tar.gz |
Merge remote-tracking branch 'upstream/master' into set-default-cache-key-for-jobs
* upstream/master: (289 commits)
re-add Assign to Me link on new MR/Issue forms
thinner bottom header border
make header match old 16px padding of body contents
Update font-awesome-rails to 4.7.0.1
Relax font-awesome-rails dependency to ~> 4.7
Restore keyboard shortcuts for "Activity" and "Charts"
fix border radius bottom for header
match padding for mr-widget sections
Update changelog
Fix project-last-commit alignment
Docs: update GL Pages IP on GL.com
Fix up @DouweM review
Remove readme-only project view preference
Add `uploads` to known models for Import/Export spec
Add `has_many` associations for models that can have Upload records
Handle relative and absolute Upload paths in the Uploaders
Change the default CarrierWave root path for tests
Fix Projects::UploadService spec
Add a Project::UploadsController spec to ensure an Upload is created
Add `RecordsUploads` module to record Upload records via callbacks
...
Diffstat (limited to 'app/assets')
2064 files changed, 8820 insertions, 8079 deletions
diff --git a/app/assets/images/emoji.png b/app/assets/images/emoji.png Binary files differindex 6f1a34a5591..5dcd9c09b70 100644 --- a/app/assets/images/emoji.png +++ b/app/assets/images/emoji.png diff --git a/app/assets/images/emoji/100.png b/app/assets/images/emoji/100.png Binary files differnew file mode 100644 index 00000000000..6903ff0304a --- /dev/null +++ b/app/assets/images/emoji/100.png diff --git a/app/assets/images/emoji/1234.png b/app/assets/images/emoji/1234.png Binary files differnew file mode 100644 index 00000000000..248dc7e55b6 --- /dev/null +++ b/app/assets/images/emoji/1234.png diff --git a/app/assets/images/emoji/1F627.png b/app/assets/images/emoji/1F627.png Binary files differnew file mode 100644 index 00000000000..f99026a3bc7 --- /dev/null +++ b/app/assets/images/emoji/1F627.png diff --git a/app/assets/images/emoji/8ball.png b/app/assets/images/emoji/8ball.png Binary files differnew file mode 100644 index 00000000000..38ca662eded --- /dev/null +++ b/app/assets/images/emoji/8ball.png diff --git a/app/assets/images/emoji/a.png b/app/assets/images/emoji/a.png Binary files differnew file mode 100644 index 00000000000..8603ff05a17 --- /dev/null +++ b/app/assets/images/emoji/a.png diff --git a/app/assets/images/emoji/ab.png b/app/assets/images/emoji/ab.png Binary files differnew file mode 100644 index 00000000000..d9f2d17dea0 --- /dev/null +++ b/app/assets/images/emoji/ab.png diff --git a/app/assets/images/emoji/abc.png b/app/assets/images/emoji/abc.png Binary files differnew file mode 100644 index 00000000000..7688de692a9 --- /dev/null +++ b/app/assets/images/emoji/abc.png diff --git a/app/assets/images/emoji/abcd.png b/app/assets/images/emoji/abcd.png Binary files differnew file mode 100644 index 00000000000..0996a870570 --- /dev/null +++ b/app/assets/images/emoji/abcd.png diff --git a/app/assets/images/emoji/accept.png b/app/assets/images/emoji/accept.png Binary files differnew file mode 100644 index 00000000000..8afd7ce99cf --- /dev/null +++ b/app/assets/images/emoji/accept.png diff --git a/app/assets/images/emoji/aerial_tramway.png b/app/assets/images/emoji/aerial_tramway.png Binary files differnew file mode 100644 index 00000000000..3eb4b61bf1d --- /dev/null +++ b/app/assets/images/emoji/aerial_tramway.png diff --git a/app/assets/images/emoji/airplane.png b/app/assets/images/emoji/airplane.png Binary files differnew file mode 100644 index 00000000000..268d2ac3c8e --- /dev/null +++ b/app/assets/images/emoji/airplane.png diff --git a/app/assets/images/emoji/airplane_arriving.png b/app/assets/images/emoji/airplane_arriving.png Binary files differnew file mode 100644 index 00000000000..d66841962f2 --- /dev/null +++ b/app/assets/images/emoji/airplane_arriving.png diff --git a/app/assets/images/emoji/airplane_departure.png b/app/assets/images/emoji/airplane_departure.png Binary files differnew file mode 100644 index 00000000000..a5766f9f4ae --- /dev/null +++ b/app/assets/images/emoji/airplane_departure.png diff --git a/app/assets/images/emoji/airplane_small.png b/app/assets/images/emoji/airplane_small.png Binary files differnew file mode 100644 index 00000000000..b731b15e3a8 --- /dev/null +++ b/app/assets/images/emoji/airplane_small.png diff --git a/app/assets/images/emoji/alarm_clock.png b/app/assets/images/emoji/alarm_clock.png Binary files differnew file mode 100644 index 00000000000..cdbc2fbb950 --- /dev/null +++ b/app/assets/images/emoji/alarm_clock.png diff --git a/app/assets/images/emoji/alembic.png b/app/assets/images/emoji/alembic.png Binary files differnew file mode 100644 index 00000000000..307a7324249 --- /dev/null +++ b/app/assets/images/emoji/alembic.png diff --git a/app/assets/images/emoji/alien.png b/app/assets/images/emoji/alien.png Binary files differnew file mode 100644 index 00000000000..3b90e97433b --- /dev/null +++ b/app/assets/images/emoji/alien.png diff --git a/app/assets/images/emoji/ambulance.png b/app/assets/images/emoji/ambulance.png Binary files differnew file mode 100644 index 00000000000..6fb8076d766 --- /dev/null +++ b/app/assets/images/emoji/ambulance.png diff --git a/app/assets/images/emoji/amphora.png b/app/assets/images/emoji/amphora.png Binary files differnew file mode 100644 index 00000000000..96de5056059 --- /dev/null +++ b/app/assets/images/emoji/amphora.png diff --git a/app/assets/images/emoji/anchor.png b/app/assets/images/emoji/anchor.png Binary files differnew file mode 100644 index 00000000000..b036f70a00b --- /dev/null +++ b/app/assets/images/emoji/anchor.png diff --git a/app/assets/images/emoji/angel.png b/app/assets/images/emoji/angel.png Binary files differnew file mode 100644 index 00000000000..66ea97a3b99 --- /dev/null +++ b/app/assets/images/emoji/angel.png diff --git a/app/assets/images/emoji/angel_tone1.png b/app/assets/images/emoji/angel_tone1.png Binary files differnew file mode 100644 index 00000000000..391694dc07e --- /dev/null +++ b/app/assets/images/emoji/angel_tone1.png diff --git a/app/assets/images/emoji/angel_tone2.png b/app/assets/images/emoji/angel_tone2.png Binary files differnew file mode 100644 index 00000000000..700cbe6ed2c --- /dev/null +++ b/app/assets/images/emoji/angel_tone2.png diff --git a/app/assets/images/emoji/angel_tone3.png b/app/assets/images/emoji/angel_tone3.png Binary files differnew file mode 100644 index 00000000000..be597437d25 --- /dev/null +++ b/app/assets/images/emoji/angel_tone3.png diff --git a/app/assets/images/emoji/angel_tone4.png b/app/assets/images/emoji/angel_tone4.png Binary files differnew file mode 100644 index 00000000000..b06d3c853ef --- /dev/null +++ b/app/assets/images/emoji/angel_tone4.png diff --git a/app/assets/images/emoji/angel_tone5.png b/app/assets/images/emoji/angel_tone5.png Binary files differnew file mode 100644 index 00000000000..17bd677e334 --- /dev/null +++ b/app/assets/images/emoji/angel_tone5.png diff --git a/app/assets/images/emoji/anger.png b/app/assets/images/emoji/anger.png Binary files differnew file mode 100644 index 00000000000..d63c2e000e4 --- /dev/null +++ b/app/assets/images/emoji/anger.png diff --git a/app/assets/images/emoji/anger_right.png b/app/assets/images/emoji/anger_right.png Binary files differnew file mode 100644 index 00000000000..f5c97c4d297 --- /dev/null +++ b/app/assets/images/emoji/anger_right.png diff --git a/app/assets/images/emoji/angry.png b/app/assets/images/emoji/angry.png Binary files differnew file mode 100644 index 00000000000..cfc4a6ecde5 --- /dev/null +++ b/app/assets/images/emoji/angry.png diff --git a/app/assets/images/emoji/ant.png b/app/assets/images/emoji/ant.png Binary files differnew file mode 100644 index 00000000000..994127ed6b3 --- /dev/null +++ b/app/assets/images/emoji/ant.png diff --git a/app/assets/images/emoji/apple.png b/app/assets/images/emoji/apple.png Binary files differnew file mode 100644 index 00000000000..da650c60f62 --- /dev/null +++ b/app/assets/images/emoji/apple.png diff --git a/app/assets/images/emoji/aquarius.png b/app/assets/images/emoji/aquarius.png Binary files differnew file mode 100644 index 00000000000..641a4f68889 --- /dev/null +++ b/app/assets/images/emoji/aquarius.png diff --git a/app/assets/images/emoji/aries.png b/app/assets/images/emoji/aries.png Binary files differnew file mode 100644 index 00000000000..21a189d0ede --- /dev/null +++ b/app/assets/images/emoji/aries.png diff --git a/app/assets/images/emoji/arrow_backward.png b/app/assets/images/emoji/arrow_backward.png Binary files differnew file mode 100644 index 00000000000..ee38e3b038e --- /dev/null +++ b/app/assets/images/emoji/arrow_backward.png diff --git a/app/assets/images/emoji/arrow_double_down.png b/app/assets/images/emoji/arrow_double_down.png Binary files differnew file mode 100644 index 00000000000..90193bfcb40 --- /dev/null +++ b/app/assets/images/emoji/arrow_double_down.png diff --git a/app/assets/images/emoji/arrow_double_up.png b/app/assets/images/emoji/arrow_double_up.png Binary files differnew file mode 100644 index 00000000000..13543d5eef2 --- /dev/null +++ b/app/assets/images/emoji/arrow_double_up.png diff --git a/app/assets/images/emoji/arrow_down.png b/app/assets/images/emoji/arrow_down.png Binary files differnew file mode 100644 index 00000000000..b8eefd0b19f --- /dev/null +++ b/app/assets/images/emoji/arrow_down.png diff --git a/app/assets/images/emoji/arrow_down_small.png b/app/assets/images/emoji/arrow_down_small.png Binary files differnew file mode 100644 index 00000000000..5870b9a2241 --- /dev/null +++ b/app/assets/images/emoji/arrow_down_small.png diff --git a/app/assets/images/emoji/arrow_forward.png b/app/assets/images/emoji/arrow_forward.png Binary files differnew file mode 100644 index 00000000000..4e2b682857c --- /dev/null +++ b/app/assets/images/emoji/arrow_forward.png diff --git a/app/assets/images/emoji/arrow_heading_down.png b/app/assets/images/emoji/arrow_heading_down.png Binary files differnew file mode 100644 index 00000000000..2d9d24bca80 --- /dev/null +++ b/app/assets/images/emoji/arrow_heading_down.png diff --git a/app/assets/images/emoji/arrow_heading_up.png b/app/assets/images/emoji/arrow_heading_up.png Binary files differnew file mode 100644 index 00000000000..f29bfcfc0de --- /dev/null +++ b/app/assets/images/emoji/arrow_heading_up.png diff --git a/app/assets/images/emoji/arrow_left.png b/app/assets/images/emoji/arrow_left.png Binary files differnew file mode 100644 index 00000000000..8c685e0a81b --- /dev/null +++ b/app/assets/images/emoji/arrow_left.png diff --git a/app/assets/images/emoji/arrow_lower_left.png b/app/assets/images/emoji/arrow_lower_left.png Binary files differnew file mode 100644 index 00000000000..88b37716078 --- /dev/null +++ b/app/assets/images/emoji/arrow_lower_left.png diff --git a/app/assets/images/emoji/arrow_lower_right.png b/app/assets/images/emoji/arrow_lower_right.png Binary files differnew file mode 100644 index 00000000000..7e807da7392 --- /dev/null +++ b/app/assets/images/emoji/arrow_lower_right.png diff --git a/app/assets/images/emoji/arrow_right.png b/app/assets/images/emoji/arrow_right.png Binary files differnew file mode 100644 index 00000000000..4755670b5cc --- /dev/null +++ b/app/assets/images/emoji/arrow_right.png diff --git a/app/assets/images/emoji/arrow_right_hook.png b/app/assets/images/emoji/arrow_right_hook.png Binary files differnew file mode 100644 index 00000000000..e7258ad3268 --- /dev/null +++ b/app/assets/images/emoji/arrow_right_hook.png diff --git a/app/assets/images/emoji/arrow_up.png b/app/assets/images/emoji/arrow_up.png Binary files differnew file mode 100644 index 00000000000..af8218a87f7 --- /dev/null +++ b/app/assets/images/emoji/arrow_up.png diff --git a/app/assets/images/emoji/arrow_up_down.png b/app/assets/images/emoji/arrow_up_down.png Binary files differnew file mode 100644 index 00000000000..dfa32b97186 --- /dev/null +++ b/app/assets/images/emoji/arrow_up_down.png diff --git a/app/assets/images/emoji/arrow_up_small.png b/app/assets/images/emoji/arrow_up_small.png Binary files differnew file mode 100644 index 00000000000..20a13dcd5cd --- /dev/null +++ b/app/assets/images/emoji/arrow_up_small.png diff --git a/app/assets/images/emoji/arrow_upper_left.png b/app/assets/images/emoji/arrow_upper_left.png Binary files differnew file mode 100644 index 00000000000..f38718fbe34 --- /dev/null +++ b/app/assets/images/emoji/arrow_upper_left.png diff --git a/app/assets/images/emoji/arrow_upper_right.png b/app/assets/images/emoji/arrow_upper_right.png Binary files differnew file mode 100644 index 00000000000..c43e12d0f64 --- /dev/null +++ b/app/assets/images/emoji/arrow_upper_right.png diff --git a/app/assets/images/emoji/arrows_clockwise.png b/app/assets/images/emoji/arrows_clockwise.png Binary files differnew file mode 100644 index 00000000000..26e49c38388 --- /dev/null +++ b/app/assets/images/emoji/arrows_clockwise.png diff --git a/app/assets/images/emoji/arrows_counterclockwise.png b/app/assets/images/emoji/arrows_counterclockwise.png Binary files differnew file mode 100644 index 00000000000..8d06d8e0912 --- /dev/null +++ b/app/assets/images/emoji/arrows_counterclockwise.png diff --git a/app/assets/images/emoji/art.png b/app/assets/images/emoji/art.png Binary files differnew file mode 100644 index 00000000000..bd6afe9ff06 --- /dev/null +++ b/app/assets/images/emoji/art.png diff --git a/app/assets/images/emoji/articulated_lorry.png b/app/assets/images/emoji/articulated_lorry.png Binary files differnew file mode 100644 index 00000000000..c8217317132 --- /dev/null +++ b/app/assets/images/emoji/articulated_lorry.png diff --git a/app/assets/images/emoji/asterisk.png b/app/assets/images/emoji/asterisk.png Binary files differnew file mode 100644 index 00000000000..2f8e5113803 --- /dev/null +++ b/app/assets/images/emoji/asterisk.png diff --git a/app/assets/images/emoji/astonished.png b/app/assets/images/emoji/astonished.png Binary files differnew file mode 100644 index 00000000000..bd0ac55ec8e --- /dev/null +++ b/app/assets/images/emoji/astonished.png diff --git a/app/assets/images/emoji/athletic_shoe.png b/app/assets/images/emoji/athletic_shoe.png Binary files differnew file mode 100644 index 00000000000..423fa07dd5d --- /dev/null +++ b/app/assets/images/emoji/athletic_shoe.png diff --git a/app/assets/images/emoji/atm.png b/app/assets/images/emoji/atm.png Binary files differnew file mode 100644 index 00000000000..4d935307b94 --- /dev/null +++ b/app/assets/images/emoji/atm.png diff --git a/app/assets/images/emoji/atom.png b/app/assets/images/emoji/atom.png Binary files differnew file mode 100644 index 00000000000..5f4567aa093 --- /dev/null +++ b/app/assets/images/emoji/atom.png diff --git a/app/assets/images/emoji/avocado.png b/app/assets/images/emoji/avocado.png Binary files differnew file mode 100644 index 00000000000..06f0d124aed --- /dev/null +++ b/app/assets/images/emoji/avocado.png diff --git a/app/assets/images/emoji/b.png b/app/assets/images/emoji/b.png Binary files differnew file mode 100644 index 00000000000..25875bc6a14 --- /dev/null +++ b/app/assets/images/emoji/b.png diff --git a/app/assets/images/emoji/baby.png b/app/assets/images/emoji/baby.png Binary files differnew file mode 100644 index 00000000000..a4af92c63c7 --- /dev/null +++ b/app/assets/images/emoji/baby.png diff --git a/app/assets/images/emoji/baby_bottle.png b/app/assets/images/emoji/baby_bottle.png Binary files differnew file mode 100644 index 00000000000..2bd10524180 --- /dev/null +++ b/app/assets/images/emoji/baby_bottle.png diff --git a/app/assets/images/emoji/baby_chick.png b/app/assets/images/emoji/baby_chick.png Binary files differnew file mode 100644 index 00000000000..dccd96576ea --- /dev/null +++ b/app/assets/images/emoji/baby_chick.png diff --git a/app/assets/images/emoji/baby_symbol.png b/app/assets/images/emoji/baby_symbol.png Binary files differnew file mode 100644 index 00000000000..64a10b71710 --- /dev/null +++ b/app/assets/images/emoji/baby_symbol.png diff --git a/app/assets/images/emoji/baby_tone1.png b/app/assets/images/emoji/baby_tone1.png Binary files differnew file mode 100644 index 00000000000..d20911d40db --- /dev/null +++ b/app/assets/images/emoji/baby_tone1.png diff --git a/app/assets/images/emoji/baby_tone2.png b/app/assets/images/emoji/baby_tone2.png Binary files differnew file mode 100644 index 00000000000..b0a9b30ed17 --- /dev/null +++ b/app/assets/images/emoji/baby_tone2.png diff --git a/app/assets/images/emoji/baby_tone3.png b/app/assets/images/emoji/baby_tone3.png Binary files differnew file mode 100644 index 00000000000..7de5286fac1 --- /dev/null +++ b/app/assets/images/emoji/baby_tone3.png diff --git a/app/assets/images/emoji/baby_tone4.png b/app/assets/images/emoji/baby_tone4.png Binary files differnew file mode 100644 index 00000000000..9b7a86ac615 --- /dev/null +++ b/app/assets/images/emoji/baby_tone4.png diff --git a/app/assets/images/emoji/baby_tone5.png b/app/assets/images/emoji/baby_tone5.png Binary files differnew file mode 100644 index 00000000000..fe1be34cb88 --- /dev/null +++ b/app/assets/images/emoji/baby_tone5.png diff --git a/app/assets/images/emoji/back.png b/app/assets/images/emoji/back.png Binary files differnew file mode 100644 index 00000000000..d32c5d4f17f --- /dev/null +++ b/app/assets/images/emoji/back.png diff --git a/app/assets/images/emoji/bacon.png b/app/assets/images/emoji/bacon.png Binary files differnew file mode 100644 index 00000000000..f38a485fbe4 --- /dev/null +++ b/app/assets/images/emoji/bacon.png diff --git a/app/assets/images/emoji/badminton.png b/app/assets/images/emoji/badminton.png Binary files differnew file mode 100644 index 00000000000..7ba15708990 --- /dev/null +++ b/app/assets/images/emoji/badminton.png diff --git a/app/assets/images/emoji/baggage_claim.png b/app/assets/images/emoji/baggage_claim.png Binary files differnew file mode 100644 index 00000000000..409b593e78a --- /dev/null +++ b/app/assets/images/emoji/baggage_claim.png diff --git a/app/assets/images/emoji/balloon.png b/app/assets/images/emoji/balloon.png Binary files differnew file mode 100644 index 00000000000..07916fe6df1 --- /dev/null +++ b/app/assets/images/emoji/balloon.png diff --git a/app/assets/images/emoji/ballot_box.png b/app/assets/images/emoji/ballot_box.png Binary files differnew file mode 100644 index 00000000000..9b6767aea9e --- /dev/null +++ b/app/assets/images/emoji/ballot_box.png diff --git a/app/assets/images/emoji/ballot_box_with_check.png b/app/assets/images/emoji/ballot_box_with_check.png Binary files differnew file mode 100644 index 00000000000..284d9573847 --- /dev/null +++ b/app/assets/images/emoji/ballot_box_with_check.png diff --git a/app/assets/images/emoji/bamboo.png b/app/assets/images/emoji/bamboo.png Binary files differnew file mode 100644 index 00000000000..5d5e0e728a0 --- /dev/null +++ b/app/assets/images/emoji/bamboo.png diff --git a/app/assets/images/emoji/banana.png b/app/assets/images/emoji/banana.png Binary files differnew file mode 100644 index 00000000000..f4987279580 --- /dev/null +++ b/app/assets/images/emoji/banana.png diff --git a/app/assets/images/emoji/bangbang.png b/app/assets/images/emoji/bangbang.png Binary files differnew file mode 100644 index 00000000000..58a9c528fca --- /dev/null +++ b/app/assets/images/emoji/bangbang.png diff --git a/app/assets/images/emoji/bank.png b/app/assets/images/emoji/bank.png Binary files differnew file mode 100644 index 00000000000..dffdcef36a1 --- /dev/null +++ b/app/assets/images/emoji/bank.png diff --git a/app/assets/images/emoji/bar_chart.png b/app/assets/images/emoji/bar_chart.png Binary files differnew file mode 100644 index 00000000000..53c89455008 --- /dev/null +++ b/app/assets/images/emoji/bar_chart.png diff --git a/app/assets/images/emoji/barber.png b/app/assets/images/emoji/barber.png Binary files differnew file mode 100644 index 00000000000..896f4d716cf --- /dev/null +++ b/app/assets/images/emoji/barber.png diff --git a/app/assets/images/emoji/baseball.png b/app/assets/images/emoji/baseball.png Binary files differnew file mode 100644 index 00000000000..f8463f1538b --- /dev/null +++ b/app/assets/images/emoji/baseball.png diff --git a/app/assets/images/emoji/basketball.png b/app/assets/images/emoji/basketball.png Binary files differnew file mode 100644 index 00000000000..64c76b79c6d --- /dev/null +++ b/app/assets/images/emoji/basketball.png diff --git a/app/assets/images/emoji/basketball_player.png b/app/assets/images/emoji/basketball_player.png Binary files differnew file mode 100644 index 00000000000..8ce90c5cad6 --- /dev/null +++ b/app/assets/images/emoji/basketball_player.png diff --git a/app/assets/images/emoji/basketball_player_tone1.png b/app/assets/images/emoji/basketball_player_tone1.png Binary files differnew file mode 100644 index 00000000000..cd12c7ab9bf --- /dev/null +++ b/app/assets/images/emoji/basketball_player_tone1.png diff --git a/app/assets/images/emoji/basketball_player_tone2.png b/app/assets/images/emoji/basketball_player_tone2.png Binary files differnew file mode 100644 index 00000000000..f892fd596da --- /dev/null +++ b/app/assets/images/emoji/basketball_player_tone2.png diff --git a/app/assets/images/emoji/basketball_player_tone3.png b/app/assets/images/emoji/basketball_player_tone3.png Binary files differnew file mode 100644 index 00000000000..e109997a91a --- /dev/null +++ b/app/assets/images/emoji/basketball_player_tone3.png diff --git a/app/assets/images/emoji/basketball_player_tone4.png b/app/assets/images/emoji/basketball_player_tone4.png Binary files differnew file mode 100644 index 00000000000..3b90b946af4 --- /dev/null +++ b/app/assets/images/emoji/basketball_player_tone4.png diff --git a/app/assets/images/emoji/basketball_player_tone5.png b/app/assets/images/emoji/basketball_player_tone5.png Binary files differnew file mode 100644 index 00000000000..bafed7828a7 --- /dev/null +++ b/app/assets/images/emoji/basketball_player_tone5.png diff --git a/app/assets/images/emoji/bat.png b/app/assets/images/emoji/bat.png Binary files differnew file mode 100644 index 00000000000..3152c047e00 --- /dev/null +++ b/app/assets/images/emoji/bat.png diff --git a/app/assets/images/emoji/bath.png b/app/assets/images/emoji/bath.png Binary files differnew file mode 100644 index 00000000000..43fba5c8a28 --- /dev/null +++ b/app/assets/images/emoji/bath.png diff --git a/app/assets/images/emoji/bath_tone1.png b/app/assets/images/emoji/bath_tone1.png Binary files differnew file mode 100644 index 00000000000..2152eabf2f5 --- /dev/null +++ b/app/assets/images/emoji/bath_tone1.png diff --git a/app/assets/images/emoji/bath_tone2.png b/app/assets/images/emoji/bath_tone2.png Binary files differnew file mode 100644 index 00000000000..2102e6133e3 --- /dev/null +++ b/app/assets/images/emoji/bath_tone2.png diff --git a/app/assets/images/emoji/bath_tone3.png b/app/assets/images/emoji/bath_tone3.png Binary files differnew file mode 100644 index 00000000000..fae66181e9f --- /dev/null +++ b/app/assets/images/emoji/bath_tone3.png diff --git a/app/assets/images/emoji/bath_tone4.png b/app/assets/images/emoji/bath_tone4.png Binary files differnew file mode 100644 index 00000000000..1f8959d0d99 --- /dev/null +++ b/app/assets/images/emoji/bath_tone4.png diff --git a/app/assets/images/emoji/bath_tone5.png b/app/assets/images/emoji/bath_tone5.png Binary files differnew file mode 100644 index 00000000000..c8a08e84f25 --- /dev/null +++ b/app/assets/images/emoji/bath_tone5.png diff --git a/app/assets/images/emoji/bathtub.png b/app/assets/images/emoji/bathtub.png Binary files differnew file mode 100644 index 00000000000..9a5f09361eb --- /dev/null +++ b/app/assets/images/emoji/bathtub.png diff --git a/app/assets/images/emoji/battery.png b/app/assets/images/emoji/battery.png Binary files differnew file mode 100644 index 00000000000..f593e2bdb65 --- /dev/null +++ b/app/assets/images/emoji/battery.png diff --git a/app/assets/images/emoji/beach.png b/app/assets/images/emoji/beach.png Binary files differnew file mode 100644 index 00000000000..69108c8ea10 --- /dev/null +++ b/app/assets/images/emoji/beach.png diff --git a/app/assets/images/emoji/beach_umbrella.png b/app/assets/images/emoji/beach_umbrella.png Binary files differnew file mode 100644 index 00000000000..220a74f8132 --- /dev/null +++ b/app/assets/images/emoji/beach_umbrella.png diff --git a/app/assets/images/emoji/bear.png b/app/assets/images/emoji/bear.png Binary files differnew file mode 100644 index 00000000000..272d56bbbcc --- /dev/null +++ b/app/assets/images/emoji/bear.png diff --git a/app/assets/images/emoji/bed.png b/app/assets/images/emoji/bed.png Binary files differnew file mode 100644 index 00000000000..86f964e245d --- /dev/null +++ b/app/assets/images/emoji/bed.png diff --git a/app/assets/images/emoji/bee.png b/app/assets/images/emoji/bee.png Binary files differnew file mode 100644 index 00000000000..46156060096 --- /dev/null +++ b/app/assets/images/emoji/bee.png diff --git a/app/assets/images/emoji/beer.png b/app/assets/images/emoji/beer.png Binary files differnew file mode 100644 index 00000000000..b6d73dc0b7a --- /dev/null +++ b/app/assets/images/emoji/beer.png diff --git a/app/assets/images/emoji/beers.png b/app/assets/images/emoji/beers.png Binary files differnew file mode 100644 index 00000000000..b55deb66b41 --- /dev/null +++ b/app/assets/images/emoji/beers.png diff --git a/app/assets/images/emoji/beetle.png b/app/assets/images/emoji/beetle.png Binary files differnew file mode 100644 index 00000000000..3d93174d7fc --- /dev/null +++ b/app/assets/images/emoji/beetle.png diff --git a/app/assets/images/emoji/beginner.png b/app/assets/images/emoji/beginner.png Binary files differnew file mode 100644 index 00000000000..bc434fb7cb5 --- /dev/null +++ b/app/assets/images/emoji/beginner.png diff --git a/app/assets/images/emoji/bell.png b/app/assets/images/emoji/bell.png Binary files differnew file mode 100644 index 00000000000..5b3b0461999 --- /dev/null +++ b/app/assets/images/emoji/bell.png diff --git a/app/assets/images/emoji/bellhop.png b/app/assets/images/emoji/bellhop.png Binary files differnew file mode 100644 index 00000000000..6b3297ceaf7 --- /dev/null +++ b/app/assets/images/emoji/bellhop.png diff --git a/app/assets/images/emoji/bento.png b/app/assets/images/emoji/bento.png Binary files differnew file mode 100644 index 00000000000..83d41ca7eb9 --- /dev/null +++ b/app/assets/images/emoji/bento.png diff --git a/app/assets/images/emoji/bicyclist.png b/app/assets/images/emoji/bicyclist.png Binary files differnew file mode 100644 index 00000000000..9274da11048 --- /dev/null +++ b/app/assets/images/emoji/bicyclist.png diff --git a/app/assets/images/emoji/bicyclist_tone1.png b/app/assets/images/emoji/bicyclist_tone1.png Binary files differnew file mode 100644 index 00000000000..decc2f728fe --- /dev/null +++ b/app/assets/images/emoji/bicyclist_tone1.png diff --git a/app/assets/images/emoji/bicyclist_tone2.png b/app/assets/images/emoji/bicyclist_tone2.png Binary files differnew file mode 100644 index 00000000000..0067717b80a --- /dev/null +++ b/app/assets/images/emoji/bicyclist_tone2.png diff --git a/app/assets/images/emoji/bicyclist_tone3.png b/app/assets/images/emoji/bicyclist_tone3.png Binary files differnew file mode 100644 index 00000000000..a4f7b5e2776 --- /dev/null +++ b/app/assets/images/emoji/bicyclist_tone3.png diff --git a/app/assets/images/emoji/bicyclist_tone4.png b/app/assets/images/emoji/bicyclist_tone4.png Binary files differnew file mode 100644 index 00000000000..a3c8a797db4 --- /dev/null +++ b/app/assets/images/emoji/bicyclist_tone4.png diff --git a/app/assets/images/emoji/bicyclist_tone5.png b/app/assets/images/emoji/bicyclist_tone5.png Binary files differnew file mode 100644 index 00000000000..1606a874051 --- /dev/null +++ b/app/assets/images/emoji/bicyclist_tone5.png diff --git a/app/assets/images/emoji/bike.png b/app/assets/images/emoji/bike.png Binary files differnew file mode 100644 index 00000000000..556ed70f1a7 --- /dev/null +++ b/app/assets/images/emoji/bike.png diff --git a/app/assets/images/emoji/bikini.png b/app/assets/images/emoji/bikini.png Binary files differnew file mode 100644 index 00000000000..77a8a0aae5b --- /dev/null +++ b/app/assets/images/emoji/bikini.png diff --git a/app/assets/images/emoji/biohazard.png b/app/assets/images/emoji/biohazard.png Binary files differnew file mode 100644 index 00000000000..007b4fc2d85 --- /dev/null +++ b/app/assets/images/emoji/biohazard.png diff --git a/app/assets/images/emoji/bird.png b/app/assets/images/emoji/bird.png Binary files differnew file mode 100644 index 00000000000..e201c22be33 --- /dev/null +++ b/app/assets/images/emoji/bird.png diff --git a/app/assets/images/emoji/birthday.png b/app/assets/images/emoji/birthday.png Binary files differnew file mode 100644 index 00000000000..317e9a41949 --- /dev/null +++ b/app/assets/images/emoji/birthday.png diff --git a/app/assets/images/emoji/black_circle.png b/app/assets/images/emoji/black_circle.png Binary files differnew file mode 100644 index 00000000000..b62b87170e8 --- /dev/null +++ b/app/assets/images/emoji/black_circle.png diff --git a/app/assets/images/emoji/black_heart.png b/app/assets/images/emoji/black_heart.png Binary files differnew file mode 100644 index 00000000000..b4068c3e6e8 --- /dev/null +++ b/app/assets/images/emoji/black_heart.png diff --git a/app/assets/images/emoji/black_joker.png b/app/assets/images/emoji/black_joker.png Binary files differnew file mode 100644 index 00000000000..3d0924b68aa --- /dev/null +++ b/app/assets/images/emoji/black_joker.png diff --git a/app/assets/images/emoji/black_large_square.png b/app/assets/images/emoji/black_large_square.png Binary files differnew file mode 100644 index 00000000000..162f2bb4290 --- /dev/null +++ b/app/assets/images/emoji/black_large_square.png diff --git a/app/assets/images/emoji/black_medium_small_square.png b/app/assets/images/emoji/black_medium_small_square.png Binary files differnew file mode 100644 index 00000000000..39765bba610 --- /dev/null +++ b/app/assets/images/emoji/black_medium_small_square.png diff --git a/app/assets/images/emoji/black_medium_square.png b/app/assets/images/emoji/black_medium_square.png Binary files differnew file mode 100644 index 00000000000..05a30a6aa2d --- /dev/null +++ b/app/assets/images/emoji/black_medium_square.png diff --git a/app/assets/images/emoji/black_nib.png b/app/assets/images/emoji/black_nib.png Binary files differnew file mode 100644 index 00000000000..872d0ae1598 --- /dev/null +++ b/app/assets/images/emoji/black_nib.png diff --git a/app/assets/images/emoji/black_small_square.png b/app/assets/images/emoji/black_small_square.png Binary files differnew file mode 100644 index 00000000000..48595d3e1a9 --- /dev/null +++ b/app/assets/images/emoji/black_small_square.png diff --git a/app/assets/images/emoji/black_square_button.png b/app/assets/images/emoji/black_square_button.png Binary files differnew file mode 100644 index 00000000000..a78fc2f6b63 --- /dev/null +++ b/app/assets/images/emoji/black_square_button.png diff --git a/app/assets/images/emoji/blossom.png b/app/assets/images/emoji/blossom.png Binary files differnew file mode 100644 index 00000000000..4083026c157 --- /dev/null +++ b/app/assets/images/emoji/blossom.png diff --git a/app/assets/images/emoji/blowfish.png b/app/assets/images/emoji/blowfish.png Binary files differnew file mode 100644 index 00000000000..a10f4f84e35 --- /dev/null +++ b/app/assets/images/emoji/blowfish.png diff --git a/app/assets/images/emoji/blue_book.png b/app/assets/images/emoji/blue_book.png Binary files differnew file mode 100644 index 00000000000..e1e455401cc --- /dev/null +++ b/app/assets/images/emoji/blue_book.png diff --git a/app/assets/images/emoji/blue_car.png b/app/assets/images/emoji/blue_car.png Binary files differnew file mode 100644 index 00000000000..e8ba817d393 --- /dev/null +++ b/app/assets/images/emoji/blue_car.png diff --git a/app/assets/images/emoji/blue_heart.png b/app/assets/images/emoji/blue_heart.png Binary files differnew file mode 100644 index 00000000000..bdf1287e55e --- /dev/null +++ b/app/assets/images/emoji/blue_heart.png diff --git a/app/assets/images/emoji/blush.png b/app/assets/images/emoji/blush.png Binary files differnew file mode 100644 index 00000000000..aac1a424ad4 --- /dev/null +++ b/app/assets/images/emoji/blush.png diff --git a/app/assets/images/emoji/boar.png b/app/assets/images/emoji/boar.png Binary files differnew file mode 100644 index 00000000000..fead972633c --- /dev/null +++ b/app/assets/images/emoji/boar.png diff --git a/app/assets/images/emoji/bomb.png b/app/assets/images/emoji/bomb.png Binary files differnew file mode 100644 index 00000000000..c7f8f81c939 --- /dev/null +++ b/app/assets/images/emoji/bomb.png diff --git a/app/assets/images/emoji/book.png b/app/assets/images/emoji/book.png Binary files differnew file mode 100644 index 00000000000..0f4447ed396 --- /dev/null +++ b/app/assets/images/emoji/book.png diff --git a/app/assets/images/emoji/bookmark.png b/app/assets/images/emoji/bookmark.png Binary files differnew file mode 100644 index 00000000000..bbb444611f0 --- /dev/null +++ b/app/assets/images/emoji/bookmark.png diff --git a/app/assets/images/emoji/bookmark_tabs.png b/app/assets/images/emoji/bookmark_tabs.png Binary files differnew file mode 100644 index 00000000000..f8d9e01b428 --- /dev/null +++ b/app/assets/images/emoji/bookmark_tabs.png diff --git a/app/assets/images/emoji/books.png b/app/assets/images/emoji/books.png Binary files differnew file mode 100644 index 00000000000..59a8bafeb0d --- /dev/null +++ b/app/assets/images/emoji/books.png diff --git a/app/assets/images/emoji/boom.png b/app/assets/images/emoji/boom.png Binary files differnew file mode 100644 index 00000000000..9b0f027b1a8 --- /dev/null +++ b/app/assets/images/emoji/boom.png diff --git a/app/assets/images/emoji/boot.png b/app/assets/images/emoji/boot.png Binary files differnew file mode 100644 index 00000000000..11f1065ed07 --- /dev/null +++ b/app/assets/images/emoji/boot.png diff --git a/app/assets/images/emoji/bouquet.png b/app/assets/images/emoji/bouquet.png Binary files differnew file mode 100644 index 00000000000..11455af6df4 --- /dev/null +++ b/app/assets/images/emoji/bouquet.png diff --git a/app/assets/images/emoji/bow.png b/app/assets/images/emoji/bow.png Binary files differnew file mode 100644 index 00000000000..d8f793088dc --- /dev/null +++ b/app/assets/images/emoji/bow.png diff --git a/app/assets/images/emoji/bow_and_arrow.png b/app/assets/images/emoji/bow_and_arrow.png Binary files differnew file mode 100644 index 00000000000..6a538bf475f --- /dev/null +++ b/app/assets/images/emoji/bow_and_arrow.png diff --git a/app/assets/images/emoji/bow_tone1.png b/app/assets/images/emoji/bow_tone1.png Binary files differnew file mode 100644 index 00000000000..87afb7b54cf --- /dev/null +++ b/app/assets/images/emoji/bow_tone1.png diff --git a/app/assets/images/emoji/bow_tone2.png b/app/assets/images/emoji/bow_tone2.png Binary files differnew file mode 100644 index 00000000000..3ccf7dc0850 --- /dev/null +++ b/app/assets/images/emoji/bow_tone2.png diff --git a/app/assets/images/emoji/bow_tone3.png b/app/assets/images/emoji/bow_tone3.png Binary files differnew file mode 100644 index 00000000000..8b9eb64f926 --- /dev/null +++ b/app/assets/images/emoji/bow_tone3.png diff --git a/app/assets/images/emoji/bow_tone4.png b/app/assets/images/emoji/bow_tone4.png Binary files differnew file mode 100644 index 00000000000..683795ff40d --- /dev/null +++ b/app/assets/images/emoji/bow_tone4.png diff --git a/app/assets/images/emoji/bow_tone5.png b/app/assets/images/emoji/bow_tone5.png Binary files differnew file mode 100644 index 00000000000..7969d971752 --- /dev/null +++ b/app/assets/images/emoji/bow_tone5.png diff --git a/app/assets/images/emoji/bowling.png b/app/assets/images/emoji/bowling.png Binary files differnew file mode 100644 index 00000000000..63add89e53b --- /dev/null +++ b/app/assets/images/emoji/bowling.png diff --git a/app/assets/images/emoji/boxing_glove.png b/app/assets/images/emoji/boxing_glove.png Binary files differnew file mode 100644 index 00000000000..9838f24e51a --- /dev/null +++ b/app/assets/images/emoji/boxing_glove.png diff --git a/app/assets/images/emoji/boy.png b/app/assets/images/emoji/boy.png Binary files differnew file mode 100644 index 00000000000..8ecfb0a4e92 --- /dev/null +++ b/app/assets/images/emoji/boy.png diff --git a/app/assets/images/emoji/boy_tone1.png b/app/assets/images/emoji/boy_tone1.png Binary files differnew file mode 100644 index 00000000000..2fc436ea512 --- /dev/null +++ b/app/assets/images/emoji/boy_tone1.png diff --git a/app/assets/images/emoji/boy_tone2.png b/app/assets/images/emoji/boy_tone2.png Binary files differnew file mode 100644 index 00000000000..09a5f18d360 --- /dev/null +++ b/app/assets/images/emoji/boy_tone2.png diff --git a/app/assets/images/emoji/boy_tone3.png b/app/assets/images/emoji/boy_tone3.png Binary files differnew file mode 100644 index 00000000000..3cfe675dd3a --- /dev/null +++ b/app/assets/images/emoji/boy_tone3.png diff --git a/app/assets/images/emoji/boy_tone4.png b/app/assets/images/emoji/boy_tone4.png Binary files differnew file mode 100644 index 00000000000..780be0ace36 --- /dev/null +++ b/app/assets/images/emoji/boy_tone4.png diff --git a/app/assets/images/emoji/boy_tone5.png b/app/assets/images/emoji/boy_tone5.png Binary files differnew file mode 100644 index 00000000000..f32fe22e35c --- /dev/null +++ b/app/assets/images/emoji/boy_tone5.png diff --git a/app/assets/images/emoji/bread.png b/app/assets/images/emoji/bread.png Binary files differnew file mode 100644 index 00000000000..6676510aaa5 --- /dev/null +++ b/app/assets/images/emoji/bread.png diff --git a/app/assets/images/emoji/bride_with_veil.png b/app/assets/images/emoji/bride_with_veil.png Binary files differnew file mode 100644 index 00000000000..eaf4bd97890 --- /dev/null +++ b/app/assets/images/emoji/bride_with_veil.png diff --git a/app/assets/images/emoji/bride_with_veil_tone1.png b/app/assets/images/emoji/bride_with_veil_tone1.png Binary files differnew file mode 100644 index 00000000000..c4fb141ae8f --- /dev/null +++ b/app/assets/images/emoji/bride_with_veil_tone1.png diff --git a/app/assets/images/emoji/bride_with_veil_tone2.png b/app/assets/images/emoji/bride_with_veil_tone2.png Binary files differnew file mode 100644 index 00000000000..c248769fc06 --- /dev/null +++ b/app/assets/images/emoji/bride_with_veil_tone2.png diff --git a/app/assets/images/emoji/bride_with_veil_tone3.png b/app/assets/images/emoji/bride_with_veil_tone3.png Binary files differnew file mode 100644 index 00000000000..962c0a6eedb --- /dev/null +++ b/app/assets/images/emoji/bride_with_veil_tone3.png diff --git a/app/assets/images/emoji/bride_with_veil_tone4.png b/app/assets/images/emoji/bride_with_veil_tone4.png Binary files differnew file mode 100644 index 00000000000..740ca208cd4 --- /dev/null +++ b/app/assets/images/emoji/bride_with_veil_tone4.png diff --git a/app/assets/images/emoji/bride_with_veil_tone5.png b/app/assets/images/emoji/bride_with_veil_tone5.png Binary files differnew file mode 100644 index 00000000000..5cc5598587d --- /dev/null +++ b/app/assets/images/emoji/bride_with_veil_tone5.png diff --git a/app/assets/images/emoji/bridge_at_night.png b/app/assets/images/emoji/bridge_at_night.png Binary files differnew file mode 100644 index 00000000000..1d444e0be65 --- /dev/null +++ b/app/assets/images/emoji/bridge_at_night.png diff --git a/app/assets/images/emoji/briefcase.png b/app/assets/images/emoji/briefcase.png Binary files differnew file mode 100644 index 00000000000..b9912ba2148 --- /dev/null +++ b/app/assets/images/emoji/briefcase.png diff --git a/app/assets/images/emoji/broken_heart.png b/app/assets/images/emoji/broken_heart.png Binary files differnew file mode 100644 index 00000000000..718e26ee122 --- /dev/null +++ b/app/assets/images/emoji/broken_heart.png diff --git a/app/assets/images/emoji/bug.png b/app/assets/images/emoji/bug.png Binary files differnew file mode 100644 index 00000000000..e64e72f259a --- /dev/null +++ b/app/assets/images/emoji/bug.png diff --git a/app/assets/images/emoji/bulb.png b/app/assets/images/emoji/bulb.png Binary files differnew file mode 100644 index 00000000000..38e32e02d9f --- /dev/null +++ b/app/assets/images/emoji/bulb.png diff --git a/app/assets/images/emoji/bullettrain_front.png b/app/assets/images/emoji/bullettrain_front.png Binary files differnew file mode 100644 index 00000000000..4f698e056fa --- /dev/null +++ b/app/assets/images/emoji/bullettrain_front.png diff --git a/app/assets/images/emoji/bullettrain_side.png b/app/assets/images/emoji/bullettrain_side.png Binary files differnew file mode 100644 index 00000000000..ed61c67bf07 --- /dev/null +++ b/app/assets/images/emoji/bullettrain_side.png diff --git a/app/assets/images/emoji/burrito.png b/app/assets/images/emoji/burrito.png Binary files differnew file mode 100644 index 00000000000..02bd5601df7 --- /dev/null +++ b/app/assets/images/emoji/burrito.png diff --git a/app/assets/images/emoji/bus.png b/app/assets/images/emoji/bus.png Binary files differnew file mode 100644 index 00000000000..641ddc56ca7 --- /dev/null +++ b/app/assets/images/emoji/bus.png diff --git a/app/assets/images/emoji/busstop.png b/app/assets/images/emoji/busstop.png Binary files differnew file mode 100644 index 00000000000..b2b62208bfd --- /dev/null +++ b/app/assets/images/emoji/busstop.png diff --git a/app/assets/images/emoji/bust_in_silhouette.png b/app/assets/images/emoji/bust_in_silhouette.png Binary files differnew file mode 100644 index 00000000000..123b2cbe1fb --- /dev/null +++ b/app/assets/images/emoji/bust_in_silhouette.png diff --git a/app/assets/images/emoji/busts_in_silhouette.png b/app/assets/images/emoji/busts_in_silhouette.png Binary files differnew file mode 100644 index 00000000000..d7656860a1c --- /dev/null +++ b/app/assets/images/emoji/busts_in_silhouette.png diff --git a/app/assets/images/emoji/butterfly.png b/app/assets/images/emoji/butterfly.png Binary files differnew file mode 100644 index 00000000000..5631fe99226 --- /dev/null +++ b/app/assets/images/emoji/butterfly.png diff --git a/app/assets/images/emoji/cactus.png b/app/assets/images/emoji/cactus.png Binary files differnew file mode 100644 index 00000000000..9b48ccf3d0c --- /dev/null +++ b/app/assets/images/emoji/cactus.png diff --git a/app/assets/images/emoji/cake.png b/app/assets/images/emoji/cake.png Binary files differnew file mode 100644 index 00000000000..4368177be9a --- /dev/null +++ b/app/assets/images/emoji/cake.png diff --git a/app/assets/images/emoji/calendar.png b/app/assets/images/emoji/calendar.png Binary files differnew file mode 100644 index 00000000000..47353b74447 --- /dev/null +++ b/app/assets/images/emoji/calendar.png diff --git a/app/assets/images/emoji/calendar_spiral.png b/app/assets/images/emoji/calendar_spiral.png Binary files differnew file mode 100644 index 00000000000..dec8d49bfa8 --- /dev/null +++ b/app/assets/images/emoji/calendar_spiral.png diff --git a/app/assets/images/emoji/call_me.png b/app/assets/images/emoji/call_me.png Binary files differnew file mode 100644 index 00000000000..a10c59ba711 --- /dev/null +++ b/app/assets/images/emoji/call_me.png diff --git a/app/assets/images/emoji/call_me_tone1.png b/app/assets/images/emoji/call_me_tone1.png Binary files differnew file mode 100644 index 00000000000..2c93201181a --- /dev/null +++ b/app/assets/images/emoji/call_me_tone1.png diff --git a/app/assets/images/emoji/call_me_tone2.png b/app/assets/images/emoji/call_me_tone2.png Binary files differnew file mode 100644 index 00000000000..c39f45a41ed --- /dev/null +++ b/app/assets/images/emoji/call_me_tone2.png diff --git a/app/assets/images/emoji/call_me_tone3.png b/app/assets/images/emoji/call_me_tone3.png Binary files differnew file mode 100644 index 00000000000..83a57f63c29 --- /dev/null +++ b/app/assets/images/emoji/call_me_tone3.png diff --git a/app/assets/images/emoji/call_me_tone4.png b/app/assets/images/emoji/call_me_tone4.png Binary files differnew file mode 100644 index 00000000000..65b3468fe44 --- /dev/null +++ b/app/assets/images/emoji/call_me_tone4.png diff --git a/app/assets/images/emoji/call_me_tone5.png b/app/assets/images/emoji/call_me_tone5.png Binary files differnew file mode 100644 index 00000000000..94ef68ff3b3 --- /dev/null +++ b/app/assets/images/emoji/call_me_tone5.png diff --git a/app/assets/images/emoji/calling.png b/app/assets/images/emoji/calling.png Binary files differnew file mode 100644 index 00000000000..e2f308f8e46 --- /dev/null +++ b/app/assets/images/emoji/calling.png diff --git a/app/assets/images/emoji/camel.png b/app/assets/images/emoji/camel.png Binary files differnew file mode 100644 index 00000000000..b421d07a805 --- /dev/null +++ b/app/assets/images/emoji/camel.png diff --git a/app/assets/images/emoji/camera.png b/app/assets/images/emoji/camera.png Binary files differnew file mode 100644 index 00000000000..0a3429f72ef --- /dev/null +++ b/app/assets/images/emoji/camera.png diff --git a/app/assets/images/emoji/camera_with_flash.png b/app/assets/images/emoji/camera_with_flash.png Binary files differnew file mode 100644 index 00000000000..27471da2029 --- /dev/null +++ b/app/assets/images/emoji/camera_with_flash.png diff --git a/app/assets/images/emoji/camping.png b/app/assets/images/emoji/camping.png Binary files differnew file mode 100644 index 00000000000..d589cc1f44b --- /dev/null +++ b/app/assets/images/emoji/camping.png diff --git a/app/assets/images/emoji/cancer.png b/app/assets/images/emoji/cancer.png Binary files differnew file mode 100644 index 00000000000..a64af07cb5f --- /dev/null +++ b/app/assets/images/emoji/cancer.png diff --git a/app/assets/images/emoji/candle.png b/app/assets/images/emoji/candle.png Binary files differnew file mode 100644 index 00000000000..0b56444e355 --- /dev/null +++ b/app/assets/images/emoji/candle.png diff --git a/app/assets/images/emoji/candy.png b/app/assets/images/emoji/candy.png Binary files differnew file mode 100644 index 00000000000..8c67ace3a35 --- /dev/null +++ b/app/assets/images/emoji/candy.png diff --git a/app/assets/images/emoji/canoe.png b/app/assets/images/emoji/canoe.png Binary files differnew file mode 100644 index 00000000000..e26cdb9da69 --- /dev/null +++ b/app/assets/images/emoji/canoe.png diff --git a/app/assets/images/emoji/capital_abcd.png b/app/assets/images/emoji/capital_abcd.png Binary files differnew file mode 100644 index 00000000000..fe9482d2d8a --- /dev/null +++ b/app/assets/images/emoji/capital_abcd.png diff --git a/app/assets/images/emoji/capricorn.png b/app/assets/images/emoji/capricorn.png Binary files differnew file mode 100644 index 00000000000..6293d31d4b1 --- /dev/null +++ b/app/assets/images/emoji/capricorn.png diff --git a/app/assets/images/emoji/card_box.png b/app/assets/images/emoji/card_box.png Binary files differnew file mode 100644 index 00000000000..f2e764ce59d --- /dev/null +++ b/app/assets/images/emoji/card_box.png diff --git a/app/assets/images/emoji/card_index.png b/app/assets/images/emoji/card_index.png Binary files differnew file mode 100644 index 00000000000..151e11cb3b4 --- /dev/null +++ b/app/assets/images/emoji/card_index.png diff --git a/app/assets/images/emoji/carousel_horse.png b/app/assets/images/emoji/carousel_horse.png Binary files differnew file mode 100644 index 00000000000..a17074edf05 --- /dev/null +++ b/app/assets/images/emoji/carousel_horse.png diff --git a/app/assets/images/emoji/carrot.png b/app/assets/images/emoji/carrot.png Binary files differnew file mode 100644 index 00000000000..c68829b58e7 --- /dev/null +++ b/app/assets/images/emoji/carrot.png diff --git a/app/assets/images/emoji/cartwheel.png b/app/assets/images/emoji/cartwheel.png Binary files differnew file mode 100644 index 00000000000..cbcaa578253 --- /dev/null +++ b/app/assets/images/emoji/cartwheel.png diff --git a/app/assets/images/emoji/cartwheel_tone1.png b/app/assets/images/emoji/cartwheel_tone1.png Binary files differnew file mode 100644 index 00000000000..db6d65895fb --- /dev/null +++ b/app/assets/images/emoji/cartwheel_tone1.png diff --git a/app/assets/images/emoji/cartwheel_tone2.png b/app/assets/images/emoji/cartwheel_tone2.png Binary files differnew file mode 100644 index 00000000000..e00ffbc27a8 --- /dev/null +++ b/app/assets/images/emoji/cartwheel_tone2.png diff --git a/app/assets/images/emoji/cartwheel_tone3.png b/app/assets/images/emoji/cartwheel_tone3.png Binary files differnew file mode 100644 index 00000000000..49321be391f --- /dev/null +++ b/app/assets/images/emoji/cartwheel_tone3.png diff --git a/app/assets/images/emoji/cartwheel_tone4.png b/app/assets/images/emoji/cartwheel_tone4.png Binary files differnew file mode 100644 index 00000000000..d4562b5e3dd --- /dev/null +++ b/app/assets/images/emoji/cartwheel_tone4.png diff --git a/app/assets/images/emoji/cartwheel_tone5.png b/app/assets/images/emoji/cartwheel_tone5.png Binary files differnew file mode 100644 index 00000000000..6e09a870767 --- /dev/null +++ b/app/assets/images/emoji/cartwheel_tone5.png diff --git a/app/assets/images/emoji/cat.png b/app/assets/images/emoji/cat.png Binary files differnew file mode 100644 index 00000000000..efd82c2abf3 --- /dev/null +++ b/app/assets/images/emoji/cat.png diff --git a/app/assets/images/emoji/cat2.png b/app/assets/images/emoji/cat2.png Binary files differnew file mode 100644 index 00000000000..46abe8cbc14 --- /dev/null +++ b/app/assets/images/emoji/cat2.png diff --git a/app/assets/images/emoji/cd.png b/app/assets/images/emoji/cd.png Binary files differnew file mode 100644 index 00000000000..e6b01449cd9 --- /dev/null +++ b/app/assets/images/emoji/cd.png diff --git a/app/assets/images/emoji/chains.png b/app/assets/images/emoji/chains.png Binary files differnew file mode 100644 index 00000000000..57f46139a06 --- /dev/null +++ b/app/assets/images/emoji/chains.png diff --git a/app/assets/images/emoji/champagne.png b/app/assets/images/emoji/champagne.png Binary files differnew file mode 100644 index 00000000000..285a79a93d0 --- /dev/null +++ b/app/assets/images/emoji/champagne.png diff --git a/app/assets/images/emoji/champagne_glass.png b/app/assets/images/emoji/champagne_glass.png Binary files differnew file mode 100644 index 00000000000..31937ae9392 --- /dev/null +++ b/app/assets/images/emoji/champagne_glass.png diff --git a/app/assets/images/emoji/chart.png b/app/assets/images/emoji/chart.png Binary files differnew file mode 100644 index 00000000000..9773f03be22 --- /dev/null +++ b/app/assets/images/emoji/chart.png diff --git a/app/assets/images/emoji/chart_with_downwards_trend.png b/app/assets/images/emoji/chart_with_downwards_trend.png Binary files differnew file mode 100644 index 00000000000..5222ec72d85 --- /dev/null +++ b/app/assets/images/emoji/chart_with_downwards_trend.png diff --git a/app/assets/images/emoji/chart_with_upwards_trend.png b/app/assets/images/emoji/chart_with_upwards_trend.png Binary files differnew file mode 100644 index 00000000000..f13cfcf9956 --- /dev/null +++ b/app/assets/images/emoji/chart_with_upwards_trend.png diff --git a/app/assets/images/emoji/checkered_flag.png b/app/assets/images/emoji/checkered_flag.png Binary files differnew file mode 100644 index 00000000000..5a71eecb89b --- /dev/null +++ b/app/assets/images/emoji/checkered_flag.png diff --git a/app/assets/images/emoji/cheese.png b/app/assets/images/emoji/cheese.png Binary files differnew file mode 100644 index 00000000000..00e99762286 --- /dev/null +++ b/app/assets/images/emoji/cheese.png diff --git a/app/assets/images/emoji/cherries.png b/app/assets/images/emoji/cherries.png Binary files differnew file mode 100644 index 00000000000..9b10cbaac5e --- /dev/null +++ b/app/assets/images/emoji/cherries.png diff --git a/app/assets/images/emoji/cherry_blossom.png b/app/assets/images/emoji/cherry_blossom.png Binary files differnew file mode 100644 index 00000000000..282f3e7bc81 --- /dev/null +++ b/app/assets/images/emoji/cherry_blossom.png diff --git a/app/assets/images/emoji/chestnut.png b/app/assets/images/emoji/chestnut.png Binary files differnew file mode 100644 index 00000000000..e9fb40468ed --- /dev/null +++ b/app/assets/images/emoji/chestnut.png diff --git a/app/assets/images/emoji/chicken.png b/app/assets/images/emoji/chicken.png Binary files differnew file mode 100644 index 00000000000..9a6992e55ba --- /dev/null +++ b/app/assets/images/emoji/chicken.png diff --git a/app/assets/images/emoji/children_crossing.png b/app/assets/images/emoji/children_crossing.png Binary files differnew file mode 100644 index 00000000000..fa4c091c7c3 --- /dev/null +++ b/app/assets/images/emoji/children_crossing.png diff --git a/app/assets/images/emoji/chipmunk.png b/app/assets/images/emoji/chipmunk.png Binary files differnew file mode 100644 index 00000000000..2aac560cb22 --- /dev/null +++ b/app/assets/images/emoji/chipmunk.png diff --git a/app/assets/images/emoji/chocolate_bar.png b/app/assets/images/emoji/chocolate_bar.png Binary files differnew file mode 100644 index 00000000000..318bbd40ef9 --- /dev/null +++ b/app/assets/images/emoji/chocolate_bar.png diff --git a/app/assets/images/emoji/christmas_tree.png b/app/assets/images/emoji/christmas_tree.png Binary files differnew file mode 100644 index 00000000000..4197d37a52b --- /dev/null +++ b/app/assets/images/emoji/christmas_tree.png diff --git a/app/assets/images/emoji/church.png b/app/assets/images/emoji/church.png Binary files differnew file mode 100644 index 00000000000..8242fd272b3 --- /dev/null +++ b/app/assets/images/emoji/church.png diff --git a/app/assets/images/emoji/cinema.png b/app/assets/images/emoji/cinema.png Binary files differnew file mode 100644 index 00000000000..65f27b386f2 --- /dev/null +++ b/app/assets/images/emoji/cinema.png diff --git a/app/assets/images/emoji/circus_tent.png b/app/assets/images/emoji/circus_tent.png Binary files differnew file mode 100644 index 00000000000..b0379775b12 --- /dev/null +++ b/app/assets/images/emoji/circus_tent.png diff --git a/app/assets/images/emoji/city_dusk.png b/app/assets/images/emoji/city_dusk.png Binary files differnew file mode 100644 index 00000000000..80cdff7cf5d --- /dev/null +++ b/app/assets/images/emoji/city_dusk.png diff --git a/app/assets/images/emoji/city_sunset.png b/app/assets/images/emoji/city_sunset.png Binary files differnew file mode 100644 index 00000000000..7cded0ba55b --- /dev/null +++ b/app/assets/images/emoji/city_sunset.png diff --git a/app/assets/images/emoji/cityscape.png b/app/assets/images/emoji/cityscape.png Binary files differnew file mode 100644 index 00000000000..d7b9844a0b4 --- /dev/null +++ b/app/assets/images/emoji/cityscape.png diff --git a/app/assets/images/emoji/cl.png b/app/assets/images/emoji/cl.png Binary files differnew file mode 100644 index 00000000000..8b01b4343e2 --- /dev/null +++ b/app/assets/images/emoji/cl.png diff --git a/app/assets/images/emoji/clap.png b/app/assets/images/emoji/clap.png Binary files differnew file mode 100644 index 00000000000..b0ffe928920 --- /dev/null +++ b/app/assets/images/emoji/clap.png diff --git a/app/assets/images/emoji/clap_tone1.png b/app/assets/images/emoji/clap_tone1.png Binary files differnew file mode 100644 index 00000000000..de4bc837b96 --- /dev/null +++ b/app/assets/images/emoji/clap_tone1.png diff --git a/app/assets/images/emoji/clap_tone2.png b/app/assets/images/emoji/clap_tone2.png Binary files differnew file mode 100644 index 00000000000..1323de775ba --- /dev/null +++ b/app/assets/images/emoji/clap_tone2.png diff --git a/app/assets/images/emoji/clap_tone3.png b/app/assets/images/emoji/clap_tone3.png Binary files differnew file mode 100644 index 00000000000..d448ca19dde --- /dev/null +++ b/app/assets/images/emoji/clap_tone3.png diff --git a/app/assets/images/emoji/clap_tone4.png b/app/assets/images/emoji/clap_tone4.png Binary files differnew file mode 100644 index 00000000000..c49f44ee91d --- /dev/null +++ b/app/assets/images/emoji/clap_tone4.png diff --git a/app/assets/images/emoji/clap_tone5.png b/app/assets/images/emoji/clap_tone5.png Binary files differnew file mode 100644 index 00000000000..29ee9bdf37c --- /dev/null +++ b/app/assets/images/emoji/clap_tone5.png diff --git a/app/assets/images/emoji/clapper.png b/app/assets/images/emoji/clapper.png Binary files differnew file mode 100644 index 00000000000..81390883111 --- /dev/null +++ b/app/assets/images/emoji/clapper.png diff --git a/app/assets/images/emoji/classical_building.png b/app/assets/images/emoji/classical_building.png Binary files differnew file mode 100644 index 00000000000..de7b559daaf --- /dev/null +++ b/app/assets/images/emoji/classical_building.png diff --git a/app/assets/images/emoji/clipboard.png b/app/assets/images/emoji/clipboard.png Binary files differnew file mode 100644 index 00000000000..7edcfc52509 --- /dev/null +++ b/app/assets/images/emoji/clipboard.png diff --git a/app/assets/images/emoji/clock.png b/app/assets/images/emoji/clock.png Binary files differnew file mode 100644 index 00000000000..ffdb451e3a8 --- /dev/null +++ b/app/assets/images/emoji/clock.png diff --git a/app/assets/images/emoji/clock1.png b/app/assets/images/emoji/clock1.png Binary files differnew file mode 100644 index 00000000000..d6e34941f23 --- /dev/null +++ b/app/assets/images/emoji/clock1.png diff --git a/app/assets/images/emoji/clock10.png b/app/assets/images/emoji/clock10.png Binary files differnew file mode 100644 index 00000000000..e62b245cdbe --- /dev/null +++ b/app/assets/images/emoji/clock10.png diff --git a/app/assets/images/emoji/clock1030.png b/app/assets/images/emoji/clock1030.png Binary files differnew file mode 100644 index 00000000000..0802b3c65b9 --- /dev/null +++ b/app/assets/images/emoji/clock1030.png diff --git a/app/assets/images/emoji/clock11.png b/app/assets/images/emoji/clock11.png Binary files differnew file mode 100644 index 00000000000..0983345273b --- /dev/null +++ b/app/assets/images/emoji/clock11.png diff --git a/app/assets/images/emoji/clock1130.png b/app/assets/images/emoji/clock1130.png Binary files differnew file mode 100644 index 00000000000..d970d03b809 --- /dev/null +++ b/app/assets/images/emoji/clock1130.png diff --git a/app/assets/images/emoji/clock12.png b/app/assets/images/emoji/clock12.png Binary files differnew file mode 100644 index 00000000000..e61caa4b3e2 --- /dev/null +++ b/app/assets/images/emoji/clock12.png diff --git a/app/assets/images/emoji/clock1230.png b/app/assets/images/emoji/clock1230.png Binary files differnew file mode 100644 index 00000000000..f2b1d261721 --- /dev/null +++ b/app/assets/images/emoji/clock1230.png diff --git a/app/assets/images/emoji/clock130.png b/app/assets/images/emoji/clock130.png Binary files differnew file mode 100644 index 00000000000..86b7689b84e --- /dev/null +++ b/app/assets/images/emoji/clock130.png diff --git a/app/assets/images/emoji/clock2.png b/app/assets/images/emoji/clock2.png Binary files differnew file mode 100644 index 00000000000..a54253d7d57 --- /dev/null +++ b/app/assets/images/emoji/clock2.png diff --git a/app/assets/images/emoji/clock230.png b/app/assets/images/emoji/clock230.png Binary files differnew file mode 100644 index 00000000000..7a787e018e6 --- /dev/null +++ b/app/assets/images/emoji/clock230.png diff --git a/app/assets/images/emoji/clock3.png b/app/assets/images/emoji/clock3.png Binary files differnew file mode 100644 index 00000000000..27ec4b1f514 --- /dev/null +++ b/app/assets/images/emoji/clock3.png diff --git a/app/assets/images/emoji/clock330.png b/app/assets/images/emoji/clock330.png Binary files differnew file mode 100644 index 00000000000..c6860395cec --- /dev/null +++ b/app/assets/images/emoji/clock330.png diff --git a/app/assets/images/emoji/clock4.png b/app/assets/images/emoji/clock4.png Binary files differnew file mode 100644 index 00000000000..60a1ef4cc13 --- /dev/null +++ b/app/assets/images/emoji/clock4.png diff --git a/app/assets/images/emoji/clock430.png b/app/assets/images/emoji/clock430.png Binary files differnew file mode 100644 index 00000000000..3c05b362122 --- /dev/null +++ b/app/assets/images/emoji/clock430.png diff --git a/app/assets/images/emoji/clock5.png b/app/assets/images/emoji/clock5.png Binary files differnew file mode 100644 index 00000000000..c9382d1e094 --- /dev/null +++ b/app/assets/images/emoji/clock5.png diff --git a/app/assets/images/emoji/clock530.png b/app/assets/images/emoji/clock530.png Binary files differnew file mode 100644 index 00000000000..c21fa926db2 --- /dev/null +++ b/app/assets/images/emoji/clock530.png diff --git a/app/assets/images/emoji/clock6.png b/app/assets/images/emoji/clock6.png Binary files differnew file mode 100644 index 00000000000..8fd5d3f5bd7 --- /dev/null +++ b/app/assets/images/emoji/clock6.png diff --git a/app/assets/images/emoji/clock630.png b/app/assets/images/emoji/clock630.png Binary files differnew file mode 100644 index 00000000000..2aec87fefcf --- /dev/null +++ b/app/assets/images/emoji/clock630.png diff --git a/app/assets/images/emoji/clock7.png b/app/assets/images/emoji/clock7.png Binary files differnew file mode 100644 index 00000000000..8c7084036f2 --- /dev/null +++ b/app/assets/images/emoji/clock7.png diff --git a/app/assets/images/emoji/clock730.png b/app/assets/images/emoji/clock730.png Binary files differnew file mode 100644 index 00000000000..f7a1135e03f --- /dev/null +++ b/app/assets/images/emoji/clock730.png diff --git a/app/assets/images/emoji/clock8.png b/app/assets/images/emoji/clock8.png Binary files differnew file mode 100644 index 00000000000..fcddf722e95 --- /dev/null +++ b/app/assets/images/emoji/clock8.png diff --git a/app/assets/images/emoji/clock830.png b/app/assets/images/emoji/clock830.png Binary files differnew file mode 100644 index 00000000000..799b4aebc08 --- /dev/null +++ b/app/assets/images/emoji/clock830.png diff --git a/app/assets/images/emoji/clock9.png b/app/assets/images/emoji/clock9.png Binary files differnew file mode 100644 index 00000000000..dfbe0117981 --- /dev/null +++ b/app/assets/images/emoji/clock9.png diff --git a/app/assets/images/emoji/clock930.png b/app/assets/images/emoji/clock930.png Binary files differnew file mode 100644 index 00000000000..4a2092ee6f0 --- /dev/null +++ b/app/assets/images/emoji/clock930.png diff --git a/app/assets/images/emoji/closed_book.png b/app/assets/images/emoji/closed_book.png Binary files differnew file mode 100644 index 00000000000..6395cf2151e --- /dev/null +++ b/app/assets/images/emoji/closed_book.png diff --git a/app/assets/images/emoji/closed_lock_with_key.png b/app/assets/images/emoji/closed_lock_with_key.png Binary files differnew file mode 100644 index 00000000000..1c1cd5d0741 --- /dev/null +++ b/app/assets/images/emoji/closed_lock_with_key.png diff --git a/app/assets/images/emoji/closed_umbrella.png b/app/assets/images/emoji/closed_umbrella.png Binary files differnew file mode 100644 index 00000000000..ecefba9e446 --- /dev/null +++ b/app/assets/images/emoji/closed_umbrella.png diff --git a/app/assets/images/emoji/cloud.png b/app/assets/images/emoji/cloud.png Binary files differnew file mode 100644 index 00000000000..5b4f57f77ba --- /dev/null +++ b/app/assets/images/emoji/cloud.png diff --git a/app/assets/images/emoji/cloud_lightning.png b/app/assets/images/emoji/cloud_lightning.png Binary files differnew file mode 100644 index 00000000000..0831e88aa31 --- /dev/null +++ b/app/assets/images/emoji/cloud_lightning.png diff --git a/app/assets/images/emoji/cloud_rain.png b/app/assets/images/emoji/cloud_rain.png Binary files differnew file mode 100644 index 00000000000..385685e0512 --- /dev/null +++ b/app/assets/images/emoji/cloud_rain.png diff --git a/app/assets/images/emoji/cloud_snow.png b/app/assets/images/emoji/cloud_snow.png Binary files differnew file mode 100644 index 00000000000..9720384eb99 --- /dev/null +++ b/app/assets/images/emoji/cloud_snow.png diff --git a/app/assets/images/emoji/cloud_tornado.png b/app/assets/images/emoji/cloud_tornado.png Binary files differnew file mode 100644 index 00000000000..4821c89da1e --- /dev/null +++ b/app/assets/images/emoji/cloud_tornado.png diff --git a/app/assets/images/emoji/clown.png b/app/assets/images/emoji/clown.png Binary files differnew file mode 100644 index 00000000000..02b7ff70049 --- /dev/null +++ b/app/assets/images/emoji/clown.png diff --git a/app/assets/images/emoji/clubs.png b/app/assets/images/emoji/clubs.png Binary files differnew file mode 100644 index 00000000000..4f2abf791ca --- /dev/null +++ b/app/assets/images/emoji/clubs.png diff --git a/app/assets/images/emoji/cocktail.png b/app/assets/images/emoji/cocktail.png Binary files differnew file mode 100644 index 00000000000..2e50c57e98d --- /dev/null +++ b/app/assets/images/emoji/cocktail.png diff --git a/app/assets/images/emoji/coffee.png b/app/assets/images/emoji/coffee.png Binary files differnew file mode 100644 index 00000000000..553061471b1 --- /dev/null +++ b/app/assets/images/emoji/coffee.png diff --git a/app/assets/images/emoji/coffin.png b/app/assets/images/emoji/coffin.png Binary files differnew file mode 100644 index 00000000000..fb2932aa5f6 --- /dev/null +++ b/app/assets/images/emoji/coffin.png diff --git a/app/assets/images/emoji/cold_sweat.png b/app/assets/images/emoji/cold_sweat.png Binary files differnew file mode 100644 index 00000000000..85b2231bbf6 --- /dev/null +++ b/app/assets/images/emoji/cold_sweat.png diff --git a/app/assets/images/emoji/comet.png b/app/assets/images/emoji/comet.png Binary files differnew file mode 100644 index 00000000000..a99751f79be --- /dev/null +++ b/app/assets/images/emoji/comet.png diff --git a/app/assets/images/emoji/compression.png b/app/assets/images/emoji/compression.png Binary files differnew file mode 100644 index 00000000000..d7eda7f362a --- /dev/null +++ b/app/assets/images/emoji/compression.png diff --git a/app/assets/images/emoji/computer.png b/app/assets/images/emoji/computer.png Binary files differnew file mode 100644 index 00000000000..c1fee27e3a9 --- /dev/null +++ b/app/assets/images/emoji/computer.png diff --git a/app/assets/images/emoji/confetti_ball.png b/app/assets/images/emoji/confetti_ball.png Binary files differnew file mode 100644 index 00000000000..ba4fd9b12be --- /dev/null +++ b/app/assets/images/emoji/confetti_ball.png diff --git a/app/assets/images/emoji/confounded.png b/app/assets/images/emoji/confounded.png Binary files differnew file mode 100644 index 00000000000..aa4b29e9375 --- /dev/null +++ b/app/assets/images/emoji/confounded.png diff --git a/app/assets/images/emoji/confused.png b/app/assets/images/emoji/confused.png Binary files differnew file mode 100644 index 00000000000..502b6bf0e0b --- /dev/null +++ b/app/assets/images/emoji/confused.png diff --git a/app/assets/images/emoji/congratulations.png b/app/assets/images/emoji/congratulations.png Binary files differnew file mode 100644 index 00000000000..ba8c89d95ee --- /dev/null +++ b/app/assets/images/emoji/congratulations.png diff --git a/app/assets/images/emoji/construction.png b/app/assets/images/emoji/construction.png Binary files differnew file mode 100644 index 00000000000..ef8db5f471c --- /dev/null +++ b/app/assets/images/emoji/construction.png diff --git a/app/assets/images/emoji/construction_site.png b/app/assets/images/emoji/construction_site.png Binary files differnew file mode 100644 index 00000000000..8206a20f63f --- /dev/null +++ b/app/assets/images/emoji/construction_site.png diff --git a/app/assets/images/emoji/construction_worker.png b/app/assets/images/emoji/construction_worker.png Binary files differnew file mode 100644 index 00000000000..a9970a89005 --- /dev/null +++ b/app/assets/images/emoji/construction_worker.png diff --git a/app/assets/images/emoji/construction_worker_tone1.png b/app/assets/images/emoji/construction_worker_tone1.png Binary files differnew file mode 100644 index 00000000000..2f24a2bab24 --- /dev/null +++ b/app/assets/images/emoji/construction_worker_tone1.png diff --git a/app/assets/images/emoji/construction_worker_tone2.png b/app/assets/images/emoji/construction_worker_tone2.png Binary files differnew file mode 100644 index 00000000000..93c8fec5a75 --- /dev/null +++ b/app/assets/images/emoji/construction_worker_tone2.png diff --git a/app/assets/images/emoji/construction_worker_tone3.png b/app/assets/images/emoji/construction_worker_tone3.png Binary files differnew file mode 100644 index 00000000000..abc1f2af2e0 --- /dev/null +++ b/app/assets/images/emoji/construction_worker_tone3.png diff --git a/app/assets/images/emoji/construction_worker_tone4.png b/app/assets/images/emoji/construction_worker_tone4.png Binary files differnew file mode 100644 index 00000000000..eed83289aeb --- /dev/null +++ b/app/assets/images/emoji/construction_worker_tone4.png diff --git a/app/assets/images/emoji/construction_worker_tone5.png b/app/assets/images/emoji/construction_worker_tone5.png Binary files differnew file mode 100644 index 00000000000..acbb220b8bb --- /dev/null +++ b/app/assets/images/emoji/construction_worker_tone5.png diff --git a/app/assets/images/emoji/control_knobs.png b/app/assets/images/emoji/control_knobs.png Binary files differnew file mode 100644 index 00000000000..6635ac93b50 --- /dev/null +++ b/app/assets/images/emoji/control_knobs.png diff --git a/app/assets/images/emoji/convenience_store.png b/app/assets/images/emoji/convenience_store.png Binary files differnew file mode 100644 index 00000000000..26b53b5669e --- /dev/null +++ b/app/assets/images/emoji/convenience_store.png diff --git a/app/assets/images/emoji/cookie.png b/app/assets/images/emoji/cookie.png Binary files differnew file mode 100644 index 00000000000..1b6bcb1554f --- /dev/null +++ b/app/assets/images/emoji/cookie.png diff --git a/app/assets/images/emoji/cooking.png b/app/assets/images/emoji/cooking.png Binary files differnew file mode 100644 index 00000000000..918c980577a --- /dev/null +++ b/app/assets/images/emoji/cooking.png diff --git a/app/assets/images/emoji/cool.png b/app/assets/images/emoji/cool.png Binary files differnew file mode 100644 index 00000000000..74674978d00 --- /dev/null +++ b/app/assets/images/emoji/cool.png diff --git a/app/assets/images/emoji/cop.png b/app/assets/images/emoji/cop.png Binary files differnew file mode 100644 index 00000000000..0b16d7c17b7 --- /dev/null +++ b/app/assets/images/emoji/cop.png diff --git a/app/assets/images/emoji/cop_tone1.png b/app/assets/images/emoji/cop_tone1.png Binary files differnew file mode 100644 index 00000000000..6ccba3879dc --- /dev/null +++ b/app/assets/images/emoji/cop_tone1.png diff --git a/app/assets/images/emoji/cop_tone2.png b/app/assets/images/emoji/cop_tone2.png Binary files differnew file mode 100644 index 00000000000..7814ea9f52d --- /dev/null +++ b/app/assets/images/emoji/cop_tone2.png diff --git a/app/assets/images/emoji/cop_tone3.png b/app/assets/images/emoji/cop_tone3.png Binary files differnew file mode 100644 index 00000000000..d78e88ec872 --- /dev/null +++ b/app/assets/images/emoji/cop_tone3.png diff --git a/app/assets/images/emoji/cop_tone4.png b/app/assets/images/emoji/cop_tone4.png Binary files differnew file mode 100644 index 00000000000..2e13c508315 --- /dev/null +++ b/app/assets/images/emoji/cop_tone4.png diff --git a/app/assets/images/emoji/cop_tone5.png b/app/assets/images/emoji/cop_tone5.png Binary files differnew file mode 100644 index 00000000000..2980d61cc2e --- /dev/null +++ b/app/assets/images/emoji/cop_tone5.png diff --git a/app/assets/images/emoji/copyright.png b/app/assets/images/emoji/copyright.png Binary files differnew file mode 100644 index 00000000000..6b9a6adbfd2 --- /dev/null +++ b/app/assets/images/emoji/copyright.png diff --git a/app/assets/images/emoji/corn.png b/app/assets/images/emoji/corn.png Binary files differnew file mode 100644 index 00000000000..36e20127931 --- /dev/null +++ b/app/assets/images/emoji/corn.png diff --git a/app/assets/images/emoji/couch.png b/app/assets/images/emoji/couch.png Binary files differnew file mode 100644 index 00000000000..27b19b13bb0 --- /dev/null +++ b/app/assets/images/emoji/couch.png diff --git a/app/assets/images/emoji/couple.png b/app/assets/images/emoji/couple.png Binary files differnew file mode 100644 index 00000000000..960323f3c16 --- /dev/null +++ b/app/assets/images/emoji/couple.png diff --git a/app/assets/images/emoji/couple_mm.png b/app/assets/images/emoji/couple_mm.png Binary files differnew file mode 100644 index 00000000000..8759fa5db87 --- /dev/null +++ b/app/assets/images/emoji/couple_mm.png diff --git a/app/assets/images/emoji/couple_with_heart.png b/app/assets/images/emoji/couple_with_heart.png Binary files differnew file mode 100644 index 00000000000..62111601b36 --- /dev/null +++ b/app/assets/images/emoji/couple_with_heart.png diff --git a/app/assets/images/emoji/couple_ww.png b/app/assets/images/emoji/couple_ww.png Binary files differnew file mode 100644 index 00000000000..08fdabcdc5c --- /dev/null +++ b/app/assets/images/emoji/couple_ww.png diff --git a/app/assets/images/emoji/couplekiss.png b/app/assets/images/emoji/couplekiss.png Binary files differnew file mode 100644 index 00000000000..9aa519da9e8 --- /dev/null +++ b/app/assets/images/emoji/couplekiss.png diff --git a/app/assets/images/emoji/cow.png b/app/assets/images/emoji/cow.png Binary files differnew file mode 100644 index 00000000000..718a3986d64 --- /dev/null +++ b/app/assets/images/emoji/cow.png diff --git a/app/assets/images/emoji/cow2.png b/app/assets/images/emoji/cow2.png Binary files differnew file mode 100644 index 00000000000..4d0ca534ff1 --- /dev/null +++ b/app/assets/images/emoji/cow2.png diff --git a/app/assets/images/emoji/cowboy.png b/app/assets/images/emoji/cowboy.png Binary files differnew file mode 100644 index 00000000000..70dd5d0d9d1 --- /dev/null +++ b/app/assets/images/emoji/cowboy.png diff --git a/app/assets/images/emoji/crab.png b/app/assets/images/emoji/crab.png Binary files differnew file mode 100644 index 00000000000..19f3047ab61 --- /dev/null +++ b/app/assets/images/emoji/crab.png diff --git a/app/assets/images/emoji/crayon.png b/app/assets/images/emoji/crayon.png Binary files differnew file mode 100644 index 00000000000..8d7b427aaa3 --- /dev/null +++ b/app/assets/images/emoji/crayon.png diff --git a/app/assets/images/emoji/credit_card.png b/app/assets/images/emoji/credit_card.png Binary files differnew file mode 100644 index 00000000000..372777d5c61 --- /dev/null +++ b/app/assets/images/emoji/credit_card.png diff --git a/app/assets/images/emoji/crescent_moon.png b/app/assets/images/emoji/crescent_moon.png Binary files differnew file mode 100644 index 00000000000..765420ecec7 --- /dev/null +++ b/app/assets/images/emoji/crescent_moon.png diff --git a/app/assets/images/emoji/cricket.png b/app/assets/images/emoji/cricket.png Binary files differnew file mode 100644 index 00000000000..d602294a2cd --- /dev/null +++ b/app/assets/images/emoji/cricket.png diff --git a/app/assets/images/emoji/crocodile.png b/app/assets/images/emoji/crocodile.png Binary files differnew file mode 100644 index 00000000000..3005c46f176 --- /dev/null +++ b/app/assets/images/emoji/crocodile.png diff --git a/app/assets/images/emoji/croissant.png b/app/assets/images/emoji/croissant.png Binary files differnew file mode 100644 index 00000000000..fb33feb1a38 --- /dev/null +++ b/app/assets/images/emoji/croissant.png diff --git a/app/assets/images/emoji/cross.png b/app/assets/images/emoji/cross.png Binary files differnew file mode 100644 index 00000000000..42b10e82257 --- /dev/null +++ b/app/assets/images/emoji/cross.png diff --git a/app/assets/images/emoji/crossed_flags.png b/app/assets/images/emoji/crossed_flags.png Binary files differnew file mode 100644 index 00000000000..273bd0f0fe5 --- /dev/null +++ b/app/assets/images/emoji/crossed_flags.png diff --git a/app/assets/images/emoji/crossed_swords.png b/app/assets/images/emoji/crossed_swords.png Binary files differnew file mode 100644 index 00000000000..907e9607134 --- /dev/null +++ b/app/assets/images/emoji/crossed_swords.png diff --git a/app/assets/images/emoji/crown.png b/app/assets/images/emoji/crown.png Binary files differnew file mode 100644 index 00000000000..93b82d92f04 --- /dev/null +++ b/app/assets/images/emoji/crown.png diff --git a/app/assets/images/emoji/cruise_ship.png b/app/assets/images/emoji/cruise_ship.png Binary files differnew file mode 100644 index 00000000000..19d4acbe40c --- /dev/null +++ b/app/assets/images/emoji/cruise_ship.png diff --git a/app/assets/images/emoji/cry.png b/app/assets/images/emoji/cry.png Binary files differnew file mode 100644 index 00000000000..b7877f8a173 --- /dev/null +++ b/app/assets/images/emoji/cry.png diff --git a/app/assets/images/emoji/crying_cat_face.png b/app/assets/images/emoji/crying_cat_face.png Binary files differnew file mode 100644 index 00000000000..b4f49715e00 --- /dev/null +++ b/app/assets/images/emoji/crying_cat_face.png diff --git a/app/assets/images/emoji/crystal_ball.png b/app/assets/images/emoji/crystal_ball.png Binary files differnew file mode 100644 index 00000000000..485d5c888f1 --- /dev/null +++ b/app/assets/images/emoji/crystal_ball.png diff --git a/app/assets/images/emoji/cucumber.png b/app/assets/images/emoji/cucumber.png Binary files differnew file mode 100644 index 00000000000..500807059d2 --- /dev/null +++ b/app/assets/images/emoji/cucumber.png diff --git a/app/assets/images/emoji/cupid.png b/app/assets/images/emoji/cupid.png Binary files differnew file mode 100644 index 00000000000..2df0078ddd1 --- /dev/null +++ b/app/assets/images/emoji/cupid.png diff --git a/app/assets/images/emoji/curly_loop.png b/app/assets/images/emoji/curly_loop.png Binary files differnew file mode 100644 index 00000000000..440aa56d50e --- /dev/null +++ b/app/assets/images/emoji/curly_loop.png diff --git a/app/assets/images/emoji/currency_exchange.png b/app/assets/images/emoji/currency_exchange.png Binary files differnew file mode 100644 index 00000000000..4d46c6050e7 --- /dev/null +++ b/app/assets/images/emoji/currency_exchange.png diff --git a/app/assets/images/emoji/curry.png b/app/assets/images/emoji/curry.png Binary files differnew file mode 100644 index 00000000000..69657ca8103 --- /dev/null +++ b/app/assets/images/emoji/curry.png diff --git a/app/assets/images/emoji/custard.png b/app/assets/images/emoji/custard.png Binary files differnew file mode 100644 index 00000000000..fa3df67b8f6 --- /dev/null +++ b/app/assets/images/emoji/custard.png diff --git a/app/assets/images/emoji/customs.png b/app/assets/images/emoji/customs.png Binary files differnew file mode 100644 index 00000000000..21b7ce2c69e --- /dev/null +++ b/app/assets/images/emoji/customs.png diff --git a/app/assets/images/emoji/cyclone.png b/app/assets/images/emoji/cyclone.png Binary files differnew file mode 100644 index 00000000000..ff00b1afe70 --- /dev/null +++ b/app/assets/images/emoji/cyclone.png diff --git a/app/assets/images/emoji/dagger.png b/app/assets/images/emoji/dagger.png Binary files differnew file mode 100644 index 00000000000..66e97b0aa25 --- /dev/null +++ b/app/assets/images/emoji/dagger.png diff --git a/app/assets/images/emoji/dancer.png b/app/assets/images/emoji/dancer.png Binary files differnew file mode 100644 index 00000000000..04b166991cb --- /dev/null +++ b/app/assets/images/emoji/dancer.png diff --git a/app/assets/images/emoji/dancer_tone1.png b/app/assets/images/emoji/dancer_tone1.png Binary files differnew file mode 100644 index 00000000000..2c7b11c3a6e --- /dev/null +++ b/app/assets/images/emoji/dancer_tone1.png diff --git a/app/assets/images/emoji/dancer_tone2.png b/app/assets/images/emoji/dancer_tone2.png Binary files differnew file mode 100644 index 00000000000..cb04b1f907e --- /dev/null +++ b/app/assets/images/emoji/dancer_tone2.png diff --git a/app/assets/images/emoji/dancer_tone3.png b/app/assets/images/emoji/dancer_tone3.png Binary files differnew file mode 100644 index 00000000000..98c5bca7b64 --- /dev/null +++ b/app/assets/images/emoji/dancer_tone3.png diff --git a/app/assets/images/emoji/dancer_tone4.png b/app/assets/images/emoji/dancer_tone4.png Binary files differnew file mode 100644 index 00000000000..fdb1e00cbba --- /dev/null +++ b/app/assets/images/emoji/dancer_tone4.png diff --git a/app/assets/images/emoji/dancer_tone5.png b/app/assets/images/emoji/dancer_tone5.png Binary files differnew file mode 100644 index 00000000000..0e34e0e23f0 --- /dev/null +++ b/app/assets/images/emoji/dancer_tone5.png diff --git a/app/assets/images/emoji/dancers.png b/app/assets/images/emoji/dancers.png Binary files differnew file mode 100644 index 00000000000..67e6ffacb76 --- /dev/null +++ b/app/assets/images/emoji/dancers.png diff --git a/app/assets/images/emoji/dango.png b/app/assets/images/emoji/dango.png Binary files differnew file mode 100644 index 00000000000..f73f37b01c7 --- /dev/null +++ b/app/assets/images/emoji/dango.png diff --git a/app/assets/images/emoji/dark_sunglasses.png b/app/assets/images/emoji/dark_sunglasses.png Binary files differnew file mode 100644 index 00000000000..b1b6db0acff --- /dev/null +++ b/app/assets/images/emoji/dark_sunglasses.png diff --git a/app/assets/images/emoji/dart.png b/app/assets/images/emoji/dart.png Binary files differnew file mode 100644 index 00000000000..f6704aeb8ba --- /dev/null +++ b/app/assets/images/emoji/dart.png diff --git a/app/assets/images/emoji/dash.png b/app/assets/images/emoji/dash.png Binary files differnew file mode 100644 index 00000000000..064b8525c12 --- /dev/null +++ b/app/assets/images/emoji/dash.png diff --git a/app/assets/images/emoji/date.png b/app/assets/images/emoji/date.png Binary files differnew file mode 100644 index 00000000000..f05b3da97b8 --- /dev/null +++ b/app/assets/images/emoji/date.png diff --git a/app/assets/images/emoji/deciduous_tree.png b/app/assets/images/emoji/deciduous_tree.png Binary files differnew file mode 100644 index 00000000000..785fc1c30ea --- /dev/null +++ b/app/assets/images/emoji/deciduous_tree.png diff --git a/app/assets/images/emoji/deer.png b/app/assets/images/emoji/deer.png Binary files differnew file mode 100644 index 00000000000..d8698195ff0 --- /dev/null +++ b/app/assets/images/emoji/deer.png diff --git a/app/assets/images/emoji/department_store.png b/app/assets/images/emoji/department_store.png Binary files differnew file mode 100644 index 00000000000..58867c7a6e1 --- /dev/null +++ b/app/assets/images/emoji/department_store.png diff --git a/app/assets/images/emoji/desert.png b/app/assets/images/emoji/desert.png Binary files differnew file mode 100644 index 00000000000..e9966ff8c65 --- /dev/null +++ b/app/assets/images/emoji/desert.png diff --git a/app/assets/images/emoji/desktop.png b/app/assets/images/emoji/desktop.png Binary files differnew file mode 100644 index 00000000000..909bd42b5e1 --- /dev/null +++ b/app/assets/images/emoji/desktop.png diff --git a/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png b/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png Binary files differnew file mode 100644 index 00000000000..2a22a26d1e2 --- /dev/null +++ b/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png diff --git a/app/assets/images/emoji/diamonds.png b/app/assets/images/emoji/diamonds.png Binary files differnew file mode 100644 index 00000000000..1f25f51f97a --- /dev/null +++ b/app/assets/images/emoji/diamonds.png diff --git a/app/assets/images/emoji/disappointed.png b/app/assets/images/emoji/disappointed.png Binary files differnew file mode 100644 index 00000000000..efe4e67e23c --- /dev/null +++ b/app/assets/images/emoji/disappointed.png diff --git a/app/assets/images/emoji/disappointed_relieved.png b/app/assets/images/emoji/disappointed_relieved.png Binary files differnew file mode 100644 index 00000000000..aef864d2b3d --- /dev/null +++ b/app/assets/images/emoji/disappointed_relieved.png diff --git a/app/assets/images/emoji/dividers.png b/app/assets/images/emoji/dividers.png Binary files differnew file mode 100644 index 00000000000..46a7e403f9d --- /dev/null +++ b/app/assets/images/emoji/dividers.png diff --git a/app/assets/images/emoji/dizzy.png b/app/assets/images/emoji/dizzy.png Binary files differnew file mode 100644 index 00000000000..85f52efad24 --- /dev/null +++ b/app/assets/images/emoji/dizzy.png diff --git a/app/assets/images/emoji/dizzy_face.png b/app/assets/images/emoji/dizzy_face.png Binary files differnew file mode 100644 index 00000000000..3120316ab5e --- /dev/null +++ b/app/assets/images/emoji/dizzy_face.png diff --git a/app/assets/images/emoji/do_not_litter.png b/app/assets/images/emoji/do_not_litter.png Binary files differnew file mode 100644 index 00000000000..341d2575f4f --- /dev/null +++ b/app/assets/images/emoji/do_not_litter.png diff --git a/app/assets/images/emoji/dog.png b/app/assets/images/emoji/dog.png Binary files differnew file mode 100644 index 00000000000..281b81d58bd --- /dev/null +++ b/app/assets/images/emoji/dog.png diff --git a/app/assets/images/emoji/dog2.png b/app/assets/images/emoji/dog2.png Binary files differnew file mode 100644 index 00000000000..976143dbdbe --- /dev/null +++ b/app/assets/images/emoji/dog2.png diff --git a/app/assets/images/emoji/dollar.png b/app/assets/images/emoji/dollar.png Binary files differnew file mode 100644 index 00000000000..a9904c28293 --- /dev/null +++ b/app/assets/images/emoji/dollar.png diff --git a/app/assets/images/emoji/dolls.png b/app/assets/images/emoji/dolls.png Binary files differnew file mode 100644 index 00000000000..10955615110 --- /dev/null +++ b/app/assets/images/emoji/dolls.png diff --git a/app/assets/images/emoji/dolphin.png b/app/assets/images/emoji/dolphin.png Binary files differnew file mode 100644 index 00000000000..81434809003 --- /dev/null +++ b/app/assets/images/emoji/dolphin.png diff --git a/app/assets/images/emoji/door.png b/app/assets/images/emoji/door.png Binary files differnew file mode 100644 index 00000000000..36ae3e27494 --- /dev/null +++ b/app/assets/images/emoji/door.png diff --git a/app/assets/images/emoji/doughnut.png b/app/assets/images/emoji/doughnut.png Binary files differnew file mode 100644 index 00000000000..0ca4cd0bde8 --- /dev/null +++ b/app/assets/images/emoji/doughnut.png diff --git a/app/assets/images/emoji/dove.png b/app/assets/images/emoji/dove.png Binary files differnew file mode 100644 index 00000000000..9580c4917d7 --- /dev/null +++ b/app/assets/images/emoji/dove.png diff --git a/app/assets/images/emoji/dragon.png b/app/assets/images/emoji/dragon.png Binary files differnew file mode 100644 index 00000000000..d6311cf5429 --- /dev/null +++ b/app/assets/images/emoji/dragon.png diff --git a/app/assets/images/emoji/dragon_face.png b/app/assets/images/emoji/dragon_face.png Binary files differnew file mode 100644 index 00000000000..3c2720446c6 --- /dev/null +++ b/app/assets/images/emoji/dragon_face.png diff --git a/app/assets/images/emoji/dress.png b/app/assets/images/emoji/dress.png Binary files differnew file mode 100644 index 00000000000..a697ca5c57d --- /dev/null +++ b/app/assets/images/emoji/dress.png diff --git a/app/assets/images/emoji/dromedary_camel.png b/app/assets/images/emoji/dromedary_camel.png Binary files differnew file mode 100644 index 00000000000..5271637c7c4 --- /dev/null +++ b/app/assets/images/emoji/dromedary_camel.png diff --git a/app/assets/images/emoji/drooling_face.png b/app/assets/images/emoji/drooling_face.png Binary files differnew file mode 100644 index 00000000000..a5460532597 --- /dev/null +++ b/app/assets/images/emoji/drooling_face.png diff --git a/app/assets/images/emoji/droplet.png b/app/assets/images/emoji/droplet.png Binary files differnew file mode 100644 index 00000000000..71241ec3061 --- /dev/null +++ b/app/assets/images/emoji/droplet.png diff --git a/app/assets/images/emoji/drum.png b/app/assets/images/emoji/drum.png Binary files differnew file mode 100644 index 00000000000..b038727cc99 --- /dev/null +++ b/app/assets/images/emoji/drum.png diff --git a/app/assets/images/emoji/duck.png b/app/assets/images/emoji/duck.png Binary files differnew file mode 100644 index 00000000000..74330b77ca3 --- /dev/null +++ b/app/assets/images/emoji/duck.png diff --git a/app/assets/images/emoji/dvd.png b/app/assets/images/emoji/dvd.png Binary files differnew file mode 100644 index 00000000000..045a6f7a08d --- /dev/null +++ b/app/assets/images/emoji/dvd.png diff --git a/app/assets/images/emoji/e-mail.png b/app/assets/images/emoji/e-mail.png Binary files differnew file mode 100644 index 00000000000..d22e654a20b --- /dev/null +++ b/app/assets/images/emoji/e-mail.png diff --git a/app/assets/images/emoji/eagle.png b/app/assets/images/emoji/eagle.png Binary files differnew file mode 100644 index 00000000000..4f277debeef --- /dev/null +++ b/app/assets/images/emoji/eagle.png diff --git a/app/assets/images/emoji/ear.png b/app/assets/images/emoji/ear.png Binary files differnew file mode 100644 index 00000000000..f84f9ff154a --- /dev/null +++ b/app/assets/images/emoji/ear.png diff --git a/app/assets/images/emoji/ear_of_rice.png b/app/assets/images/emoji/ear_of_rice.png Binary files differnew file mode 100644 index 00000000000..3564d9d643a --- /dev/null +++ b/app/assets/images/emoji/ear_of_rice.png diff --git a/app/assets/images/emoji/ear_tone1.png b/app/assets/images/emoji/ear_tone1.png Binary files differnew file mode 100644 index 00000000000..d09e1e41996 --- /dev/null +++ b/app/assets/images/emoji/ear_tone1.png diff --git a/app/assets/images/emoji/ear_tone2.png b/app/assets/images/emoji/ear_tone2.png Binary files differnew file mode 100644 index 00000000000..300d60a9948 --- /dev/null +++ b/app/assets/images/emoji/ear_tone2.png diff --git a/app/assets/images/emoji/ear_tone3.png b/app/assets/images/emoji/ear_tone3.png Binary files differnew file mode 100644 index 00000000000..2a56eebe445 --- /dev/null +++ b/app/assets/images/emoji/ear_tone3.png diff --git a/app/assets/images/emoji/ear_tone4.png b/app/assets/images/emoji/ear_tone4.png Binary files differnew file mode 100644 index 00000000000..bd270f7763e --- /dev/null +++ b/app/assets/images/emoji/ear_tone4.png diff --git a/app/assets/images/emoji/ear_tone5.png b/app/assets/images/emoji/ear_tone5.png Binary files differnew file mode 100644 index 00000000000..b96bb441dff --- /dev/null +++ b/app/assets/images/emoji/ear_tone5.png diff --git a/app/assets/images/emoji/earth_africa.png b/app/assets/images/emoji/earth_africa.png Binary files differnew file mode 100644 index 00000000000..66c3348c23a --- /dev/null +++ b/app/assets/images/emoji/earth_africa.png diff --git a/app/assets/images/emoji/earth_americas.png b/app/assets/images/emoji/earth_americas.png Binary files differnew file mode 100644 index 00000000000..538c3cddd68 --- /dev/null +++ b/app/assets/images/emoji/earth_americas.png diff --git a/app/assets/images/emoji/earth_asia.png b/app/assets/images/emoji/earth_asia.png Binary files differnew file mode 100644 index 00000000000..d8df97fec3c --- /dev/null +++ b/app/assets/images/emoji/earth_asia.png diff --git a/app/assets/images/emoji/egg.png b/app/assets/images/emoji/egg.png Binary files differnew file mode 100644 index 00000000000..c171974d993 --- /dev/null +++ b/app/assets/images/emoji/egg.png diff --git a/app/assets/images/emoji/eggplant.png b/app/assets/images/emoji/eggplant.png Binary files differnew file mode 100644 index 00000000000..fafd7c1a14c --- /dev/null +++ b/app/assets/images/emoji/eggplant.png diff --git a/app/assets/images/emoji/eight.png b/app/assets/images/emoji/eight.png Binary files differnew file mode 100644 index 00000000000..8c95874d4c5 --- /dev/null +++ b/app/assets/images/emoji/eight.png diff --git a/app/assets/images/emoji/eight_pointed_black_star.png b/app/assets/images/emoji/eight_pointed_black_star.png Binary files differnew file mode 100644 index 00000000000..820179bda50 --- /dev/null +++ b/app/assets/images/emoji/eight_pointed_black_star.png diff --git a/app/assets/images/emoji/eight_spoked_asterisk.png b/app/assets/images/emoji/eight_spoked_asterisk.png Binary files differnew file mode 100644 index 00000000000..3307ffa62ee --- /dev/null +++ b/app/assets/images/emoji/eight_spoked_asterisk.png diff --git a/app/assets/images/emoji/eject.png b/app/assets/images/emoji/eject.png Binary files differnew file mode 100644 index 00000000000..ec5cfc48973 --- /dev/null +++ b/app/assets/images/emoji/eject.png diff --git a/app/assets/images/emoji/electric_plug.png b/app/assets/images/emoji/electric_plug.png Binary files differnew file mode 100644 index 00000000000..31d1eb215b4 --- /dev/null +++ b/app/assets/images/emoji/electric_plug.png diff --git a/app/assets/images/emoji/elephant.png b/app/assets/images/emoji/elephant.png Binary files differnew file mode 100644 index 00000000000..b8a6d140595 --- /dev/null +++ b/app/assets/images/emoji/elephant.png diff --git a/app/assets/images/emoji/end.png b/app/assets/images/emoji/end.png Binary files differnew file mode 100644 index 00000000000..ef3ccd5f367 --- /dev/null +++ b/app/assets/images/emoji/end.png diff --git a/app/assets/images/emoji/envelope.png b/app/assets/images/emoji/envelope.png Binary files differnew file mode 100644 index 00000000000..ec77ac375a4 --- /dev/null +++ b/app/assets/images/emoji/envelope.png diff --git a/app/assets/images/emoji/envelope_with_arrow.png b/app/assets/images/emoji/envelope_with_arrow.png Binary files differnew file mode 100644 index 00000000000..7448a6b7673 --- /dev/null +++ b/app/assets/images/emoji/envelope_with_arrow.png diff --git a/app/assets/images/emoji/euro.png b/app/assets/images/emoji/euro.png Binary files differnew file mode 100644 index 00000000000..a49020820e1 --- /dev/null +++ b/app/assets/images/emoji/euro.png diff --git a/app/assets/images/emoji/european_castle.png b/app/assets/images/emoji/european_castle.png Binary files differnew file mode 100644 index 00000000000..888d11332ce --- /dev/null +++ b/app/assets/images/emoji/european_castle.png diff --git a/app/assets/images/emoji/european_post_office.png b/app/assets/images/emoji/european_post_office.png Binary files differnew file mode 100644 index 00000000000..3745aff8dd2 --- /dev/null +++ b/app/assets/images/emoji/european_post_office.png diff --git a/app/assets/images/emoji/evergreen_tree.png b/app/assets/images/emoji/evergreen_tree.png Binary files differnew file mode 100644 index 00000000000..f679d8dd772 --- /dev/null +++ b/app/assets/images/emoji/evergreen_tree.png diff --git a/app/assets/images/emoji/exclamation.png b/app/assets/images/emoji/exclamation.png Binary files differnew file mode 100644 index 00000000000..2c14406422f --- /dev/null +++ b/app/assets/images/emoji/exclamation.png diff --git a/app/assets/images/emoji/expressionless.png b/app/assets/images/emoji/expressionless.png Binary files differnew file mode 100644 index 00000000000..2954017f6c2 --- /dev/null +++ b/app/assets/images/emoji/expressionless.png diff --git a/app/assets/images/emoji/eye.png b/app/assets/images/emoji/eye.png Binary files differnew file mode 100644 index 00000000000..9d989cdd375 --- /dev/null +++ b/app/assets/images/emoji/eye.png diff --git a/app/assets/images/emoji/eye_in_speech_bubble.png b/app/assets/images/emoji/eye_in_speech_bubble.png Binary files differnew file mode 100644 index 00000000000..21bd22bbcce --- /dev/null +++ b/app/assets/images/emoji/eye_in_speech_bubble.png diff --git a/app/assets/images/emoji/eyeglasses.png b/app/assets/images/emoji/eyeglasses.png Binary files differnew file mode 100644 index 00000000000..865d8274acf --- /dev/null +++ b/app/assets/images/emoji/eyeglasses.png diff --git a/app/assets/images/emoji/eyes.png b/app/assets/images/emoji/eyes.png Binary files differnew file mode 100644 index 00000000000..2102ada7e09 --- /dev/null +++ b/app/assets/images/emoji/eyes.png diff --git a/app/assets/images/emoji/face_palm.png b/app/assets/images/emoji/face_palm.png Binary files differnew file mode 100644 index 00000000000..defc796cf16 --- /dev/null +++ b/app/assets/images/emoji/face_palm.png diff --git a/app/assets/images/emoji/face_palm_tone1.png b/app/assets/images/emoji/face_palm_tone1.png Binary files differnew file mode 100644 index 00000000000..2f4b010bb40 --- /dev/null +++ b/app/assets/images/emoji/face_palm_tone1.png diff --git a/app/assets/images/emoji/face_palm_tone2.png b/app/assets/images/emoji/face_palm_tone2.png Binary files differnew file mode 100644 index 00000000000..97fb6831687 --- /dev/null +++ b/app/assets/images/emoji/face_palm_tone2.png diff --git a/app/assets/images/emoji/face_palm_tone3.png b/app/assets/images/emoji/face_palm_tone3.png Binary files differnew file mode 100644 index 00000000000..b5b5c1e5306 --- /dev/null +++ b/app/assets/images/emoji/face_palm_tone3.png diff --git a/app/assets/images/emoji/face_palm_tone4.png b/app/assets/images/emoji/face_palm_tone4.png Binary files differnew file mode 100644 index 00000000000..2840b113483 --- /dev/null +++ b/app/assets/images/emoji/face_palm_tone4.png diff --git a/app/assets/images/emoji/face_palm_tone5.png b/app/assets/images/emoji/face_palm_tone5.png Binary files differnew file mode 100644 index 00000000000..6f070db98be --- /dev/null +++ b/app/assets/images/emoji/face_palm_tone5.png diff --git a/app/assets/images/emoji/factory.png b/app/assets/images/emoji/factory.png Binary files differnew file mode 100644 index 00000000000..e1d2ddf4a27 --- /dev/null +++ b/app/assets/images/emoji/factory.png diff --git a/app/assets/images/emoji/fallen_leaf.png b/app/assets/images/emoji/fallen_leaf.png Binary files differnew file mode 100644 index 00000000000..0d60e7bdf2d --- /dev/null +++ b/app/assets/images/emoji/fallen_leaf.png diff --git a/app/assets/images/emoji/family.png b/app/assets/images/emoji/family.png Binary files differnew file mode 100644 index 00000000000..26421965791 --- /dev/null +++ b/app/assets/images/emoji/family.png diff --git a/app/assets/images/emoji/family_mmb.png b/app/assets/images/emoji/family_mmb.png Binary files differnew file mode 100644 index 00000000000..7a2e4e2c491 --- /dev/null +++ b/app/assets/images/emoji/family_mmb.png diff --git a/app/assets/images/emoji/family_mmbb.png b/app/assets/images/emoji/family_mmbb.png Binary files differnew file mode 100644 index 00000000000..81e6c0fc0ee --- /dev/null +++ b/app/assets/images/emoji/family_mmbb.png diff --git a/app/assets/images/emoji/family_mmg.png b/app/assets/images/emoji/family_mmg.png Binary files differnew file mode 100644 index 00000000000..932a85e1fe5 --- /dev/null +++ b/app/assets/images/emoji/family_mmg.png diff --git a/app/assets/images/emoji/family_mmgb.png b/app/assets/images/emoji/family_mmgb.png Binary files differnew file mode 100644 index 00000000000..41e35166670 --- /dev/null +++ b/app/assets/images/emoji/family_mmgb.png diff --git a/app/assets/images/emoji/family_mmgg.png b/app/assets/images/emoji/family_mmgg.png Binary files differnew file mode 100644 index 00000000000..8e8ccfe6c7f --- /dev/null +++ b/app/assets/images/emoji/family_mmgg.png diff --git a/app/assets/images/emoji/family_mwbb.png b/app/assets/images/emoji/family_mwbb.png Binary files differnew file mode 100644 index 00000000000..b544fbe573f --- /dev/null +++ b/app/assets/images/emoji/family_mwbb.png diff --git a/app/assets/images/emoji/family_mwg.png b/app/assets/images/emoji/family_mwg.png Binary files differnew file mode 100644 index 00000000000..71d2681c32a --- /dev/null +++ b/app/assets/images/emoji/family_mwg.png diff --git a/app/assets/images/emoji/family_mwgb.png b/app/assets/images/emoji/family_mwgb.png Binary files differnew file mode 100644 index 00000000000..40dbf1f7a18 --- /dev/null +++ b/app/assets/images/emoji/family_mwgb.png diff --git a/app/assets/images/emoji/family_mwgg.png b/app/assets/images/emoji/family_mwgg.png Binary files differnew file mode 100644 index 00000000000..bfefa4879cb --- /dev/null +++ b/app/assets/images/emoji/family_mwgg.png diff --git a/app/assets/images/emoji/family_wwb.png b/app/assets/images/emoji/family_wwb.png Binary files differnew file mode 100644 index 00000000000..836feae7c78 --- /dev/null +++ b/app/assets/images/emoji/family_wwb.png diff --git a/app/assets/images/emoji/family_wwbb.png b/app/assets/images/emoji/family_wwbb.png Binary files differnew file mode 100644 index 00000000000..6c6ba45e7bb --- /dev/null +++ b/app/assets/images/emoji/family_wwbb.png diff --git a/app/assets/images/emoji/family_wwg.png b/app/assets/images/emoji/family_wwg.png Binary files differnew file mode 100644 index 00000000000..41225c6fa5a --- /dev/null +++ b/app/assets/images/emoji/family_wwg.png diff --git a/app/assets/images/emoji/family_wwgb.png b/app/assets/images/emoji/family_wwgb.png Binary files differnew file mode 100644 index 00000000000..284d29ab5da --- /dev/null +++ b/app/assets/images/emoji/family_wwgb.png diff --git a/app/assets/images/emoji/family_wwgg.png b/app/assets/images/emoji/family_wwgg.png Binary files differnew file mode 100644 index 00000000000..d8d3f49b85f --- /dev/null +++ b/app/assets/images/emoji/family_wwgg.png diff --git a/app/assets/images/emoji/fast_forward.png b/app/assets/images/emoji/fast_forward.png Binary files differnew file mode 100644 index 00000000000..c406fedfdb1 --- /dev/null +++ b/app/assets/images/emoji/fast_forward.png diff --git a/app/assets/images/emoji/fax.png b/app/assets/images/emoji/fax.png Binary files differnew file mode 100644 index 00000000000..6f929e294c2 --- /dev/null +++ b/app/assets/images/emoji/fax.png diff --git a/app/assets/images/emoji/fearful.png b/app/assets/images/emoji/fearful.png Binary files differnew file mode 100644 index 00000000000..eb8b347cef9 --- /dev/null +++ b/app/assets/images/emoji/fearful.png diff --git a/app/assets/images/emoji/feet.png b/app/assets/images/emoji/feet.png Binary files differnew file mode 100644 index 00000000000..5fe568cee93 --- /dev/null +++ b/app/assets/images/emoji/feet.png diff --git a/app/assets/images/emoji/fencer.png b/app/assets/images/emoji/fencer.png Binary files differnew file mode 100644 index 00000000000..5288c920eb9 --- /dev/null +++ b/app/assets/images/emoji/fencer.png diff --git a/app/assets/images/emoji/ferris_wheel.png b/app/assets/images/emoji/ferris_wheel.png Binary files differnew file mode 100644 index 00000000000..55c8ff0475b --- /dev/null +++ b/app/assets/images/emoji/ferris_wheel.png diff --git a/app/assets/images/emoji/ferry.png b/app/assets/images/emoji/ferry.png Binary files differnew file mode 100644 index 00000000000..41816b3ae34 --- /dev/null +++ b/app/assets/images/emoji/ferry.png diff --git a/app/assets/images/emoji/field_hockey.png b/app/assets/images/emoji/field_hockey.png Binary files differnew file mode 100644 index 00000000000..839637716ee --- /dev/null +++ b/app/assets/images/emoji/field_hockey.png diff --git a/app/assets/images/emoji/file_cabinet.png b/app/assets/images/emoji/file_cabinet.png Binary files differnew file mode 100644 index 00000000000..fddc65dde96 --- /dev/null +++ b/app/assets/images/emoji/file_cabinet.png diff --git a/app/assets/images/emoji/file_folder.png b/app/assets/images/emoji/file_folder.png Binary files differnew file mode 100644 index 00000000000..addedaf0870 --- /dev/null +++ b/app/assets/images/emoji/file_folder.png diff --git a/app/assets/images/emoji/film_frames.png b/app/assets/images/emoji/film_frames.png Binary files differnew file mode 100644 index 00000000000..30143aedbe6 --- /dev/null +++ b/app/assets/images/emoji/film_frames.png diff --git a/app/assets/images/emoji/fingers_crossed.png b/app/assets/images/emoji/fingers_crossed.png Binary files differnew file mode 100644 index 00000000000..4cd18514ea3 --- /dev/null +++ b/app/assets/images/emoji/fingers_crossed.png diff --git a/app/assets/images/emoji/fingers_crossed_tone1.png b/app/assets/images/emoji/fingers_crossed_tone1.png Binary files differnew file mode 100644 index 00000000000..dd2384a6cd5 --- /dev/null +++ b/app/assets/images/emoji/fingers_crossed_tone1.png diff --git a/app/assets/images/emoji/fingers_crossed_tone2.png b/app/assets/images/emoji/fingers_crossed_tone2.png Binary files differnew file mode 100644 index 00000000000..6228401befe --- /dev/null +++ b/app/assets/images/emoji/fingers_crossed_tone2.png diff --git a/app/assets/images/emoji/fingers_crossed_tone3.png b/app/assets/images/emoji/fingers_crossed_tone3.png Binary files differnew file mode 100644 index 00000000000..b1074da15f5 --- /dev/null +++ b/app/assets/images/emoji/fingers_crossed_tone3.png diff --git a/app/assets/images/emoji/fingers_crossed_tone4.png b/app/assets/images/emoji/fingers_crossed_tone4.png Binary files differnew file mode 100644 index 00000000000..75e05e4d332 --- /dev/null +++ b/app/assets/images/emoji/fingers_crossed_tone4.png diff --git a/app/assets/images/emoji/fingers_crossed_tone5.png b/app/assets/images/emoji/fingers_crossed_tone5.png Binary files differnew file mode 100644 index 00000000000..761aebdc30f --- /dev/null +++ b/app/assets/images/emoji/fingers_crossed_tone5.png diff --git a/app/assets/images/emoji/fire.png b/app/assets/images/emoji/fire.png Binary files differnew file mode 100644 index 00000000000..bd3775a460b --- /dev/null +++ b/app/assets/images/emoji/fire.png diff --git a/app/assets/images/emoji/fire_engine.png b/app/assets/images/emoji/fire_engine.png Binary files differnew file mode 100644 index 00000000000..2cd45b7cf7e --- /dev/null +++ b/app/assets/images/emoji/fire_engine.png diff --git a/app/assets/images/emoji/fireworks.png b/app/assets/images/emoji/fireworks.png Binary files differnew file mode 100644 index 00000000000..176c8b58265 --- /dev/null +++ b/app/assets/images/emoji/fireworks.png diff --git a/app/assets/images/emoji/first_place.png b/app/assets/images/emoji/first_place.png Binary files differnew file mode 100644 index 00000000000..15612b66492 --- /dev/null +++ b/app/assets/images/emoji/first_place.png diff --git a/app/assets/images/emoji/first_quarter_moon.png b/app/assets/images/emoji/first_quarter_moon.png Binary files differnew file mode 100644 index 00000000000..5dccaf72a4f --- /dev/null +++ b/app/assets/images/emoji/first_quarter_moon.png diff --git a/app/assets/images/emoji/first_quarter_moon_with_face.png b/app/assets/images/emoji/first_quarter_moon_with_face.png Binary files differnew file mode 100644 index 00000000000..cd8a3d7acd8 --- /dev/null +++ b/app/assets/images/emoji/first_quarter_moon_with_face.png diff --git a/app/assets/images/emoji/fish.png b/app/assets/images/emoji/fish.png Binary files differnew file mode 100644 index 00000000000..c2d2faaacd4 --- /dev/null +++ b/app/assets/images/emoji/fish.png diff --git a/app/assets/images/emoji/fish_cake.png b/app/assets/images/emoji/fish_cake.png Binary files differnew file mode 100644 index 00000000000..157bded65db --- /dev/null +++ b/app/assets/images/emoji/fish_cake.png diff --git a/app/assets/images/emoji/fishing_pole_and_fish.png b/app/assets/images/emoji/fishing_pole_and_fish.png Binary files differnew file mode 100644 index 00000000000..dfcdf07eb50 --- /dev/null +++ b/app/assets/images/emoji/fishing_pole_and_fish.png diff --git a/app/assets/images/emoji/fist.png b/app/assets/images/emoji/fist.png Binary files differnew file mode 100644 index 00000000000..de33592bf98 --- /dev/null +++ b/app/assets/images/emoji/fist.png diff --git a/app/assets/images/emoji/fist_tone1.png b/app/assets/images/emoji/fist_tone1.png Binary files differnew file mode 100644 index 00000000000..02809e2dd68 --- /dev/null +++ b/app/assets/images/emoji/fist_tone1.png diff --git a/app/assets/images/emoji/fist_tone2.png b/app/assets/images/emoji/fist_tone2.png Binary files differnew file mode 100644 index 00000000000..5de34810383 --- /dev/null +++ b/app/assets/images/emoji/fist_tone2.png diff --git a/app/assets/images/emoji/fist_tone3.png b/app/assets/images/emoji/fist_tone3.png Binary files differnew file mode 100644 index 00000000000..0d5240129b1 --- /dev/null +++ b/app/assets/images/emoji/fist_tone3.png diff --git a/app/assets/images/emoji/fist_tone4.png b/app/assets/images/emoji/fist_tone4.png Binary files differnew file mode 100644 index 00000000000..a95c0dd634b --- /dev/null +++ b/app/assets/images/emoji/fist_tone4.png diff --git a/app/assets/images/emoji/fist_tone5.png b/app/assets/images/emoji/fist_tone5.png Binary files differnew file mode 100644 index 00000000000..a2f092fd8c7 --- /dev/null +++ b/app/assets/images/emoji/fist_tone5.png diff --git a/app/assets/images/emoji/five.png b/app/assets/images/emoji/five.png Binary files differnew file mode 100644 index 00000000000..d14371f3f27 --- /dev/null +++ b/app/assets/images/emoji/five.png diff --git a/app/assets/images/emoji/flag_ac.png b/app/assets/images/emoji/flag_ac.png Binary files differnew file mode 100644 index 00000000000..286239920c7 --- /dev/null +++ b/app/assets/images/emoji/flag_ac.png diff --git a/app/assets/images/emoji/flag_ad.png b/app/assets/images/emoji/flag_ad.png Binary files differnew file mode 100644 index 00000000000..20f4b14e8ad --- /dev/null +++ b/app/assets/images/emoji/flag_ad.png diff --git a/app/assets/images/emoji/flag_ae.png b/app/assets/images/emoji/flag_ae.png Binary files differnew file mode 100644 index 00000000000..d16ffe4b862 --- /dev/null +++ b/app/assets/images/emoji/flag_ae.png diff --git a/app/assets/images/emoji/flag_af.png b/app/assets/images/emoji/flag_af.png Binary files differnew file mode 100644 index 00000000000..a51533b554d --- /dev/null +++ b/app/assets/images/emoji/flag_af.png diff --git a/app/assets/images/emoji/flag_ag.png b/app/assets/images/emoji/flag_ag.png Binary files differnew file mode 100644 index 00000000000..07f2ce397d0 --- /dev/null +++ b/app/assets/images/emoji/flag_ag.png diff --git a/app/assets/images/emoji/flag_ai.png b/app/assets/images/emoji/flag_ai.png Binary files differnew file mode 100644 index 00000000000..500b5ab09fb --- /dev/null +++ b/app/assets/images/emoji/flag_ai.png diff --git a/app/assets/images/emoji/flag_al.png b/app/assets/images/emoji/flag_al.png Binary files differnew file mode 100644 index 00000000000..03a20132cc6 --- /dev/null +++ b/app/assets/images/emoji/flag_al.png diff --git a/app/assets/images/emoji/flag_am.png b/app/assets/images/emoji/flag_am.png Binary files differnew file mode 100644 index 00000000000..2ad60a273ec --- /dev/null +++ b/app/assets/images/emoji/flag_am.png diff --git a/app/assets/images/emoji/flag_ao.png b/app/assets/images/emoji/flag_ao.png Binary files differnew file mode 100644 index 00000000000..cb46c31f862 --- /dev/null +++ b/app/assets/images/emoji/flag_ao.png diff --git a/app/assets/images/emoji/flag_aq.png b/app/assets/images/emoji/flag_aq.png Binary files differnew file mode 100644 index 00000000000..b272021d375 --- /dev/null +++ b/app/assets/images/emoji/flag_aq.png diff --git a/app/assets/images/emoji/flag_ar.png b/app/assets/images/emoji/flag_ar.png Binary files differnew file mode 100644 index 00000000000..73136caf3b7 --- /dev/null +++ b/app/assets/images/emoji/flag_ar.png diff --git a/app/assets/images/emoji/flag_as.png b/app/assets/images/emoji/flag_as.png Binary files differnew file mode 100644 index 00000000000..3db45a0d9f3 --- /dev/null +++ b/app/assets/images/emoji/flag_as.png diff --git a/app/assets/images/emoji/flag_at.png b/app/assets/images/emoji/flag_at.png Binary files differnew file mode 100644 index 00000000000..c43769dcb19 --- /dev/null +++ b/app/assets/images/emoji/flag_at.png diff --git a/app/assets/images/emoji/flag_au.png b/app/assets/images/emoji/flag_au.png Binary files differnew file mode 100644 index 00000000000..7794309c78c --- /dev/null +++ b/app/assets/images/emoji/flag_au.png diff --git a/app/assets/images/emoji/flag_aw.png b/app/assets/images/emoji/flag_aw.png Binary files differnew file mode 100644 index 00000000000..02c840d12c9 --- /dev/null +++ b/app/assets/images/emoji/flag_aw.png diff --git a/app/assets/images/emoji/flag_ax.png b/app/assets/images/emoji/flag_ax.png Binary files differnew file mode 100644 index 00000000000..fc5466174bb --- /dev/null +++ b/app/assets/images/emoji/flag_ax.png diff --git a/app/assets/images/emoji/flag_az.png b/app/assets/images/emoji/flag_az.png Binary files differnew file mode 100644 index 00000000000..89d3d15fd9f --- /dev/null +++ b/app/assets/images/emoji/flag_az.png diff --git a/app/assets/images/emoji/flag_ba.png b/app/assets/images/emoji/flag_ba.png Binary files differnew file mode 100644 index 00000000000..25fe407e13c --- /dev/null +++ b/app/assets/images/emoji/flag_ba.png diff --git a/app/assets/images/emoji/flag_bb.png b/app/assets/images/emoji/flag_bb.png Binary files differnew file mode 100644 index 00000000000..bccd8c5c9b0 --- /dev/null +++ b/app/assets/images/emoji/flag_bb.png diff --git a/app/assets/images/emoji/flag_bd.png b/app/assets/images/emoji/flag_bd.png Binary files differnew file mode 100644 index 00000000000..b0597a3149b --- /dev/null +++ b/app/assets/images/emoji/flag_bd.png diff --git a/app/assets/images/emoji/flag_be.png b/app/assets/images/emoji/flag_be.png Binary files differnew file mode 100644 index 00000000000..551f086e3c4 --- /dev/null +++ b/app/assets/images/emoji/flag_be.png diff --git a/app/assets/images/emoji/flag_bf.png b/app/assets/images/emoji/flag_bf.png Binary files differnew file mode 100644 index 00000000000..444d4829f94 --- /dev/null +++ b/app/assets/images/emoji/flag_bf.png diff --git a/app/assets/images/emoji/flag_bg.png b/app/assets/images/emoji/flag_bg.png Binary files differnew file mode 100644 index 00000000000..821eee5e170 --- /dev/null +++ b/app/assets/images/emoji/flag_bg.png diff --git a/app/assets/images/emoji/flag_bh.png b/app/assets/images/emoji/flag_bh.png Binary files differnew file mode 100644 index 00000000000..f33724249f0 --- /dev/null +++ b/app/assets/images/emoji/flag_bh.png diff --git a/app/assets/images/emoji/flag_bi.png b/app/assets/images/emoji/flag_bi.png Binary files differnew file mode 100644 index 00000000000..ea20ac93211 --- /dev/null +++ b/app/assets/images/emoji/flag_bi.png diff --git a/app/assets/images/emoji/flag_bj.png b/app/assets/images/emoji/flag_bj.png Binary files differnew file mode 100644 index 00000000000..7cca4f80457 --- /dev/null +++ b/app/assets/images/emoji/flag_bj.png diff --git a/app/assets/images/emoji/flag_bl.png b/app/assets/images/emoji/flag_bl.png Binary files differnew file mode 100644 index 00000000000..1082e78999f --- /dev/null +++ b/app/assets/images/emoji/flag_bl.png diff --git a/app/assets/images/emoji/flag_black.png b/app/assets/images/emoji/flag_black.png Binary files differnew file mode 100644 index 00000000000..0e28d05d5ac --- /dev/null +++ b/app/assets/images/emoji/flag_black.png diff --git a/app/assets/images/emoji/flag_bm.png b/app/assets/images/emoji/flag_bm.png Binary files differnew file mode 100644 index 00000000000..ab8cafdac63 --- /dev/null +++ b/app/assets/images/emoji/flag_bm.png diff --git a/app/assets/images/emoji/flag_bn.png b/app/assets/images/emoji/flag_bn.png Binary files differnew file mode 100644 index 00000000000..caa9329a896 --- /dev/null +++ b/app/assets/images/emoji/flag_bn.png diff --git a/app/assets/images/emoji/flag_bo.png b/app/assets/images/emoji/flag_bo.png Binary files differnew file mode 100644 index 00000000000..98af62b3da7 --- /dev/null +++ b/app/assets/images/emoji/flag_bo.png diff --git a/app/assets/images/emoji/flag_bq.png b/app/assets/images/emoji/flag_bq.png Binary files differnew file mode 100644 index 00000000000..cb978ef9de9 --- /dev/null +++ b/app/assets/images/emoji/flag_bq.png diff --git a/app/assets/images/emoji/flag_br.png b/app/assets/images/emoji/flag_br.png Binary files differnew file mode 100644 index 00000000000..b139366a42b --- /dev/null +++ b/app/assets/images/emoji/flag_br.png diff --git a/app/assets/images/emoji/flag_bs.png b/app/assets/images/emoji/flag_bs.png Binary files differnew file mode 100644 index 00000000000..d36bcd2fb52 --- /dev/null +++ b/app/assets/images/emoji/flag_bs.png diff --git a/app/assets/images/emoji/flag_bt.png b/app/assets/images/emoji/flag_bt.png Binary files differnew file mode 100644 index 00000000000..ed57aa0360e --- /dev/null +++ b/app/assets/images/emoji/flag_bt.png diff --git a/app/assets/images/emoji/flag_bv.png b/app/assets/images/emoji/flag_bv.png Binary files differnew file mode 100644 index 00000000000..5884e648228 --- /dev/null +++ b/app/assets/images/emoji/flag_bv.png diff --git a/app/assets/images/emoji/flag_bw.png b/app/assets/images/emoji/flag_bw.png Binary files differnew file mode 100644 index 00000000000..cb12f34739d --- /dev/null +++ b/app/assets/images/emoji/flag_bw.png diff --git a/app/assets/images/emoji/flag_by.png b/app/assets/images/emoji/flag_by.png Binary files differnew file mode 100644 index 00000000000..859c05beb13 --- /dev/null +++ b/app/assets/images/emoji/flag_by.png diff --git a/app/assets/images/emoji/flag_bz.png b/app/assets/images/emoji/flag_bz.png Binary files differnew file mode 100644 index 00000000000..34761cd03d8 --- /dev/null +++ b/app/assets/images/emoji/flag_bz.png diff --git a/app/assets/images/emoji/flag_ca.png b/app/assets/images/emoji/flag_ca.png Binary files differnew file mode 100644 index 00000000000..7c5b390e85b --- /dev/null +++ b/app/assets/images/emoji/flag_ca.png diff --git a/app/assets/images/emoji/flag_cc.png b/app/assets/images/emoji/flag_cc.png Binary files differnew file mode 100644 index 00000000000..b6555a23d83 --- /dev/null +++ b/app/assets/images/emoji/flag_cc.png diff --git a/app/assets/images/emoji/flag_cd.png b/app/assets/images/emoji/flag_cd.png Binary files differnew file mode 100644 index 00000000000..fa92009771d --- /dev/null +++ b/app/assets/images/emoji/flag_cd.png diff --git a/app/assets/images/emoji/flag_cf.png b/app/assets/images/emoji/flag_cf.png Binary files differnew file mode 100644 index 00000000000..b969ae29ea9 --- /dev/null +++ b/app/assets/images/emoji/flag_cf.png diff --git a/app/assets/images/emoji/flag_cg.png b/app/assets/images/emoji/flag_cg.png Binary files differnew file mode 100644 index 00000000000..3a38a40a95e --- /dev/null +++ b/app/assets/images/emoji/flag_cg.png diff --git a/app/assets/images/emoji/flag_ch.png b/app/assets/images/emoji/flag_ch.png Binary files differnew file mode 100644 index 00000000000..5ff86b8a3b7 --- /dev/null +++ b/app/assets/images/emoji/flag_ch.png diff --git a/app/assets/images/emoji/flag_ci.png b/app/assets/images/emoji/flag_ci.png Binary files differnew file mode 100644 index 00000000000..e3b4d15c7f1 --- /dev/null +++ b/app/assets/images/emoji/flag_ci.png diff --git a/app/assets/images/emoji/flag_ck.png b/app/assets/images/emoji/flag_ck.png Binary files differnew file mode 100644 index 00000000000..b6b53dbc1c4 --- /dev/null +++ b/app/assets/images/emoji/flag_ck.png diff --git a/app/assets/images/emoji/flag_cl.png b/app/assets/images/emoji/flag_cl.png Binary files differnew file mode 100644 index 00000000000..c9390da5499 --- /dev/null +++ b/app/assets/images/emoji/flag_cl.png diff --git a/app/assets/images/emoji/flag_cm.png b/app/assets/images/emoji/flag_cm.png Binary files differnew file mode 100644 index 00000000000..2d3f6ec4518 --- /dev/null +++ b/app/assets/images/emoji/flag_cm.png diff --git a/app/assets/images/emoji/flag_cn.png b/app/assets/images/emoji/flag_cn.png Binary files differnew file mode 100644 index 00000000000..0a7f350a6d2 --- /dev/null +++ b/app/assets/images/emoji/flag_cn.png diff --git a/app/assets/images/emoji/flag_co.png b/app/assets/images/emoji/flag_co.png Binary files differnew file mode 100644 index 00000000000..7e0f5e0dc3c --- /dev/null +++ b/app/assets/images/emoji/flag_co.png diff --git a/app/assets/images/emoji/flag_cp.png b/app/assets/images/emoji/flag_cp.png Binary files differnew file mode 100644 index 00000000000..70c761036bd --- /dev/null +++ b/app/assets/images/emoji/flag_cp.png diff --git a/app/assets/images/emoji/flag_cr.png b/app/assets/images/emoji/flag_cr.png Binary files differnew file mode 100644 index 00000000000..a5fce126515 --- /dev/null +++ b/app/assets/images/emoji/flag_cr.png diff --git a/app/assets/images/emoji/flag_cu.png b/app/assets/images/emoji/flag_cu.png Binary files differnew file mode 100644 index 00000000000..447328f7dfd --- /dev/null +++ b/app/assets/images/emoji/flag_cu.png diff --git a/app/assets/images/emoji/flag_cv.png b/app/assets/images/emoji/flag_cv.png Binary files differnew file mode 100644 index 00000000000..43faf4d64d5 --- /dev/null +++ b/app/assets/images/emoji/flag_cv.png diff --git a/app/assets/images/emoji/flag_cw.png b/app/assets/images/emoji/flag_cw.png Binary files differnew file mode 100644 index 00000000000..eb39e8d0078 --- /dev/null +++ b/app/assets/images/emoji/flag_cw.png diff --git a/app/assets/images/emoji/flag_cx.png b/app/assets/images/emoji/flag_cx.png Binary files differnew file mode 100644 index 00000000000..09d21359f3a --- /dev/null +++ b/app/assets/images/emoji/flag_cx.png diff --git a/app/assets/images/emoji/flag_cy.png b/app/assets/images/emoji/flag_cy.png Binary files differnew file mode 100644 index 00000000000..154a7aa3176 --- /dev/null +++ b/app/assets/images/emoji/flag_cy.png diff --git a/app/assets/images/emoji/flag_cz.png b/app/assets/images/emoji/flag_cz.png Binary files differnew file mode 100644 index 00000000000..9737ca223c7 --- /dev/null +++ b/app/assets/images/emoji/flag_cz.png diff --git a/app/assets/images/emoji/flag_de.png b/app/assets/images/emoji/flag_de.png Binary files differnew file mode 100644 index 00000000000..98ed76b3bab --- /dev/null +++ b/app/assets/images/emoji/flag_de.png diff --git a/app/assets/images/emoji/flag_dg.png b/app/assets/images/emoji/flag_dg.png Binary files differnew file mode 100644 index 00000000000..aae927d14b8 --- /dev/null +++ b/app/assets/images/emoji/flag_dg.png diff --git a/app/assets/images/emoji/flag_dj.png b/app/assets/images/emoji/flag_dj.png Binary files differnew file mode 100644 index 00000000000..73c2a2acbd9 --- /dev/null +++ b/app/assets/images/emoji/flag_dj.png diff --git a/app/assets/images/emoji/flag_dk.png b/app/assets/images/emoji/flag_dk.png Binary files differnew file mode 100644 index 00000000000..e5a60b06256 --- /dev/null +++ b/app/assets/images/emoji/flag_dk.png diff --git a/app/assets/images/emoji/flag_dm.png b/app/assets/images/emoji/flag_dm.png Binary files differnew file mode 100644 index 00000000000..50f8a53981d --- /dev/null +++ b/app/assets/images/emoji/flag_dm.png diff --git a/app/assets/images/emoji/flag_do.png b/app/assets/images/emoji/flag_do.png Binary files differnew file mode 100644 index 00000000000..037a45d7c26 --- /dev/null +++ b/app/assets/images/emoji/flag_do.png diff --git a/app/assets/images/emoji/flag_dz.png b/app/assets/images/emoji/flag_dz.png Binary files differnew file mode 100644 index 00000000000..24945b10f2d --- /dev/null +++ b/app/assets/images/emoji/flag_dz.png diff --git a/app/assets/images/emoji/flag_ea.png b/app/assets/images/emoji/flag_ea.png Binary files differnew file mode 100644 index 00000000000..356ff347838 --- /dev/null +++ b/app/assets/images/emoji/flag_ea.png diff --git a/app/assets/images/emoji/flag_ec.png b/app/assets/images/emoji/flag_ec.png Binary files differnew file mode 100644 index 00000000000..13814594619 --- /dev/null +++ b/app/assets/images/emoji/flag_ec.png diff --git a/app/assets/images/emoji/flag_ee.png b/app/assets/images/emoji/flag_ee.png Binary files differnew file mode 100644 index 00000000000..84f317e7747 --- /dev/null +++ b/app/assets/images/emoji/flag_ee.png diff --git a/app/assets/images/emoji/flag_eg.png b/app/assets/images/emoji/flag_eg.png Binary files differnew file mode 100644 index 00000000000..57786064a95 --- /dev/null +++ b/app/assets/images/emoji/flag_eg.png diff --git a/app/assets/images/emoji/flag_eh.png b/app/assets/images/emoji/flag_eh.png Binary files differnew file mode 100644 index 00000000000..4d7a76687f6 --- /dev/null +++ b/app/assets/images/emoji/flag_eh.png diff --git a/app/assets/images/emoji/flag_er.png b/app/assets/images/emoji/flag_er.png Binary files differnew file mode 100644 index 00000000000..0c3c724c1fb --- /dev/null +++ b/app/assets/images/emoji/flag_er.png diff --git a/app/assets/images/emoji/flag_es.png b/app/assets/images/emoji/flag_es.png Binary files differnew file mode 100644 index 00000000000..3e73597a225 --- /dev/null +++ b/app/assets/images/emoji/flag_es.png diff --git a/app/assets/images/emoji/flag_et.png b/app/assets/images/emoji/flag_et.png Binary files differnew file mode 100644 index 00000000000..9560a134c97 --- /dev/null +++ b/app/assets/images/emoji/flag_et.png diff --git a/app/assets/images/emoji/flag_eu.png b/app/assets/images/emoji/flag_eu.png Binary files differnew file mode 100644 index 00000000000..0b456cf3330 --- /dev/null +++ b/app/assets/images/emoji/flag_eu.png diff --git a/app/assets/images/emoji/flag_fi.png b/app/assets/images/emoji/flag_fi.png Binary files differnew file mode 100644 index 00000000000..ebcf58abfc5 --- /dev/null +++ b/app/assets/images/emoji/flag_fi.png diff --git a/app/assets/images/emoji/flag_fj.png b/app/assets/images/emoji/flag_fj.png Binary files differnew file mode 100644 index 00000000000..9cc8c37fe37 --- /dev/null +++ b/app/assets/images/emoji/flag_fj.png diff --git a/app/assets/images/emoji/flag_fk.png b/app/assets/images/emoji/flag_fk.png Binary files differnew file mode 100644 index 00000000000..61372fd2549 --- /dev/null +++ b/app/assets/images/emoji/flag_fk.png diff --git a/app/assets/images/emoji/flag_fm.png b/app/assets/images/emoji/flag_fm.png Binary files differnew file mode 100644 index 00000000000..0889825c8e1 --- /dev/null +++ b/app/assets/images/emoji/flag_fm.png diff --git a/app/assets/images/emoji/flag_fo.png b/app/assets/images/emoji/flag_fo.png Binary files differnew file mode 100644 index 00000000000..9a4431b0831 --- /dev/null +++ b/app/assets/images/emoji/flag_fo.png diff --git a/app/assets/images/emoji/flag_fr.png b/app/assets/images/emoji/flag_fr.png Binary files differnew file mode 100644 index 00000000000..62ca19c3fcf --- /dev/null +++ b/app/assets/images/emoji/flag_fr.png diff --git a/app/assets/images/emoji/flag_ga.png b/app/assets/images/emoji/flag_ga.png Binary files differnew file mode 100644 index 00000000000..2e68e527a3e --- /dev/null +++ b/app/assets/images/emoji/flag_ga.png diff --git a/app/assets/images/emoji/flag_gb.png b/app/assets/images/emoji/flag_gb.png Binary files differnew file mode 100644 index 00000000000..3ed10f62347 --- /dev/null +++ b/app/assets/images/emoji/flag_gb.png diff --git a/app/assets/images/emoji/flag_gd.png b/app/assets/images/emoji/flag_gd.png Binary files differnew file mode 100644 index 00000000000..527aad33807 --- /dev/null +++ b/app/assets/images/emoji/flag_gd.png diff --git a/app/assets/images/emoji/flag_ge.png b/app/assets/images/emoji/flag_ge.png Binary files differnew file mode 100644 index 00000000000..a75d142480d --- /dev/null +++ b/app/assets/images/emoji/flag_ge.png diff --git a/app/assets/images/emoji/flag_gf.png b/app/assets/images/emoji/flag_gf.png Binary files differnew file mode 100644 index 00000000000..0cf96f327c0 --- /dev/null +++ b/app/assets/images/emoji/flag_gf.png diff --git a/app/assets/images/emoji/flag_gg.png b/app/assets/images/emoji/flag_gg.png Binary files differnew file mode 100644 index 00000000000..970002c7f76 --- /dev/null +++ b/app/assets/images/emoji/flag_gg.png diff --git a/app/assets/images/emoji/flag_gh.png b/app/assets/images/emoji/flag_gh.png Binary files differnew file mode 100644 index 00000000000..f31b5eb7b45 --- /dev/null +++ b/app/assets/images/emoji/flag_gh.png diff --git a/app/assets/images/emoji/flag_gi.png b/app/assets/images/emoji/flag_gi.png Binary files differnew file mode 100644 index 00000000000..e554a2a1d0c --- /dev/null +++ b/app/assets/images/emoji/flag_gi.png diff --git a/app/assets/images/emoji/flag_gl.png b/app/assets/images/emoji/flag_gl.png Binary files differnew file mode 100644 index 00000000000..2e795dd4e33 --- /dev/null +++ b/app/assets/images/emoji/flag_gl.png diff --git a/app/assets/images/emoji/flag_gm.png b/app/assets/images/emoji/flag_gm.png Binary files differnew file mode 100644 index 00000000000..bb69c0975a3 --- /dev/null +++ b/app/assets/images/emoji/flag_gm.png diff --git a/app/assets/images/emoji/flag_gn.png b/app/assets/images/emoji/flag_gn.png Binary files differnew file mode 100644 index 00000000000..1981f61dbf5 --- /dev/null +++ b/app/assets/images/emoji/flag_gn.png diff --git a/app/assets/images/emoji/flag_gp.png b/app/assets/images/emoji/flag_gp.png Binary files differnew file mode 100644 index 00000000000..10e42e672bd --- /dev/null +++ b/app/assets/images/emoji/flag_gp.png diff --git a/app/assets/images/emoji/flag_gq.png b/app/assets/images/emoji/flag_gq.png Binary files differnew file mode 100644 index 00000000000..11475e61eeb --- /dev/null +++ b/app/assets/images/emoji/flag_gq.png diff --git a/app/assets/images/emoji/flag_gr.png b/app/assets/images/emoji/flag_gr.png Binary files differnew file mode 100644 index 00000000000..0f6bb1b6b94 --- /dev/null +++ b/app/assets/images/emoji/flag_gr.png diff --git a/app/assets/images/emoji/flag_gs.png b/app/assets/images/emoji/flag_gs.png Binary files differnew file mode 100644 index 00000000000..6fc92780453 --- /dev/null +++ b/app/assets/images/emoji/flag_gs.png diff --git a/app/assets/images/emoji/flag_gt.png b/app/assets/images/emoji/flag_gt.png Binary files differnew file mode 100644 index 00000000000..7213d4139ed --- /dev/null +++ b/app/assets/images/emoji/flag_gt.png diff --git a/app/assets/images/emoji/flag_gu.png b/app/assets/images/emoji/flag_gu.png Binary files differnew file mode 100644 index 00000000000..4027549ca3c --- /dev/null +++ b/app/assets/images/emoji/flag_gu.png diff --git a/app/assets/images/emoji/flag_gw.png b/app/assets/images/emoji/flag_gw.png Binary files differnew file mode 100644 index 00000000000..6357f6225f4 --- /dev/null +++ b/app/assets/images/emoji/flag_gw.png diff --git a/app/assets/images/emoji/flag_gy.png b/app/assets/images/emoji/flag_gy.png Binary files differnew file mode 100644 index 00000000000..746e2fb7e44 --- /dev/null +++ b/app/assets/images/emoji/flag_gy.png diff --git a/app/assets/images/emoji/flag_hk.png b/app/assets/images/emoji/flag_hk.png Binary files differnew file mode 100644 index 00000000000..cf0c7151b56 --- /dev/null +++ b/app/assets/images/emoji/flag_hk.png diff --git a/app/assets/images/emoji/flag_hm.png b/app/assets/images/emoji/flag_hm.png Binary files differnew file mode 100644 index 00000000000..b613509e466 --- /dev/null +++ b/app/assets/images/emoji/flag_hm.png diff --git a/app/assets/images/emoji/flag_hn.png b/app/assets/images/emoji/flag_hn.png Binary files differnew file mode 100644 index 00000000000..402cdcefdf8 --- /dev/null +++ b/app/assets/images/emoji/flag_hn.png diff --git a/app/assets/images/emoji/flag_hr.png b/app/assets/images/emoji/flag_hr.png Binary files differnew file mode 100644 index 00000000000..46f4f06b4f2 --- /dev/null +++ b/app/assets/images/emoji/flag_hr.png diff --git a/app/assets/images/emoji/flag_ht.png b/app/assets/images/emoji/flag_ht.png Binary files differnew file mode 100644 index 00000000000..d8d0c888498 --- /dev/null +++ b/app/assets/images/emoji/flag_ht.png diff --git a/app/assets/images/emoji/flag_hu.png b/app/assets/images/emoji/flag_hu.png Binary files differnew file mode 100644 index 00000000000..a898de636a5 --- /dev/null +++ b/app/assets/images/emoji/flag_hu.png diff --git a/app/assets/images/emoji/flag_ic.png b/app/assets/images/emoji/flag_ic.png Binary files differnew file mode 100644 index 00000000000..69fd990aa95 --- /dev/null +++ b/app/assets/images/emoji/flag_ic.png diff --git a/app/assets/images/emoji/flag_id.png b/app/assets/images/emoji/flag_id.png Binary files differnew file mode 100644 index 00000000000..85b4c063a45 --- /dev/null +++ b/app/assets/images/emoji/flag_id.png diff --git a/app/assets/images/emoji/flag_ie.png b/app/assets/images/emoji/flag_ie.png Binary files differnew file mode 100644 index 00000000000..a28295838cc --- /dev/null +++ b/app/assets/images/emoji/flag_ie.png diff --git a/app/assets/images/emoji/flag_il.png b/app/assets/images/emoji/flag_il.png Binary files differnew file mode 100644 index 00000000000..85c410d45fb --- /dev/null +++ b/app/assets/images/emoji/flag_il.png diff --git a/app/assets/images/emoji/flag_im.png b/app/assets/images/emoji/flag_im.png Binary files differnew file mode 100644 index 00000000000..60a2458e38e --- /dev/null +++ b/app/assets/images/emoji/flag_im.png diff --git a/app/assets/images/emoji/flag_in.png b/app/assets/images/emoji/flag_in.png Binary files differnew file mode 100644 index 00000000000..feccc8952ce --- /dev/null +++ b/app/assets/images/emoji/flag_in.png diff --git a/app/assets/images/emoji/flag_io.png b/app/assets/images/emoji/flag_io.png Binary files differnew file mode 100644 index 00000000000..aae927d14b8 --- /dev/null +++ b/app/assets/images/emoji/flag_io.png diff --git a/app/assets/images/emoji/flag_iq.png b/app/assets/images/emoji/flag_iq.png Binary files differnew file mode 100644 index 00000000000..41fd1db6f86 --- /dev/null +++ b/app/assets/images/emoji/flag_iq.png diff --git a/app/assets/images/emoji/flag_ir.png b/app/assets/images/emoji/flag_ir.png Binary files differnew file mode 100644 index 00000000000..ff7aaf62ba6 --- /dev/null +++ b/app/assets/images/emoji/flag_ir.png diff --git a/app/assets/images/emoji/flag_is.png b/app/assets/images/emoji/flag_is.png Binary files differnew file mode 100644 index 00000000000..ad8d4131dd2 --- /dev/null +++ b/app/assets/images/emoji/flag_is.png diff --git a/app/assets/images/emoji/flag_it.png b/app/assets/images/emoji/flag_it.png Binary files differnew file mode 100644 index 00000000000..f21563ec533 --- /dev/null +++ b/app/assets/images/emoji/flag_it.png diff --git a/app/assets/images/emoji/flag_je.png b/app/assets/images/emoji/flag_je.png Binary files differnew file mode 100644 index 00000000000..198a918f6a4 --- /dev/null +++ b/app/assets/images/emoji/flag_je.png diff --git a/app/assets/images/emoji/flag_jm.png b/app/assets/images/emoji/flag_jm.png Binary files differnew file mode 100644 index 00000000000..f84e4f9e8db --- /dev/null +++ b/app/assets/images/emoji/flag_jm.png diff --git a/app/assets/images/emoji/flag_jo.png b/app/assets/images/emoji/flag_jo.png Binary files differnew file mode 100644 index 00000000000..20bfa147e3e --- /dev/null +++ b/app/assets/images/emoji/flag_jo.png diff --git a/app/assets/images/emoji/flag_jp.png b/app/assets/images/emoji/flag_jp.png Binary files differnew file mode 100644 index 00000000000..8d8838e4708 --- /dev/null +++ b/app/assets/images/emoji/flag_jp.png diff --git a/app/assets/images/emoji/flag_ke.png b/app/assets/images/emoji/flag_ke.png Binary files differnew file mode 100644 index 00000000000..9e417ab3009 --- /dev/null +++ b/app/assets/images/emoji/flag_ke.png diff --git a/app/assets/images/emoji/flag_kg.png b/app/assets/images/emoji/flag_kg.png Binary files differnew file mode 100644 index 00000000000..2f2d848fe58 --- /dev/null +++ b/app/assets/images/emoji/flag_kg.png diff --git a/app/assets/images/emoji/flag_kh.png b/app/assets/images/emoji/flag_kh.png Binary files differnew file mode 100644 index 00000000000..9a2877dd620 --- /dev/null +++ b/app/assets/images/emoji/flag_kh.png diff --git a/app/assets/images/emoji/flag_ki.png b/app/assets/images/emoji/flag_ki.png Binary files differnew file mode 100644 index 00000000000..10e507e3245 --- /dev/null +++ b/app/assets/images/emoji/flag_ki.png diff --git a/app/assets/images/emoji/flag_km.png b/app/assets/images/emoji/flag_km.png Binary files differnew file mode 100644 index 00000000000..bd5a0588e03 --- /dev/null +++ b/app/assets/images/emoji/flag_km.png diff --git a/app/assets/images/emoji/flag_kn.png b/app/assets/images/emoji/flag_kn.png Binary files differnew file mode 100644 index 00000000000..776207c9605 --- /dev/null +++ b/app/assets/images/emoji/flag_kn.png diff --git a/app/assets/images/emoji/flag_kp.png b/app/assets/images/emoji/flag_kp.png Binary files differnew file mode 100644 index 00000000000..6b3fd89eaaa --- /dev/null +++ b/app/assets/images/emoji/flag_kp.png diff --git a/app/assets/images/emoji/flag_kr.png b/app/assets/images/emoji/flag_kr.png Binary files differnew file mode 100644 index 00000000000..833a88116e1 --- /dev/null +++ b/app/assets/images/emoji/flag_kr.png diff --git a/app/assets/images/emoji/flag_kw.png b/app/assets/images/emoji/flag_kw.png Binary files differnew file mode 100644 index 00000000000..4d19bfa6ca7 --- /dev/null +++ b/app/assets/images/emoji/flag_kw.png diff --git a/app/assets/images/emoji/flag_ky.png b/app/assets/images/emoji/flag_ky.png Binary files differnew file mode 100644 index 00000000000..40daa4da597 --- /dev/null +++ b/app/assets/images/emoji/flag_ky.png diff --git a/app/assets/images/emoji/flag_kz.png b/app/assets/images/emoji/flag_kz.png Binary files differnew file mode 100644 index 00000000000..2f97a8fd3c6 --- /dev/null +++ b/app/assets/images/emoji/flag_kz.png diff --git a/app/assets/images/emoji/flag_la.png b/app/assets/images/emoji/flag_la.png Binary files differnew file mode 100644 index 00000000000..4d4179f34f6 --- /dev/null +++ b/app/assets/images/emoji/flag_la.png diff --git a/app/assets/images/emoji/flag_lb.png b/app/assets/images/emoji/flag_lb.png Binary files differnew file mode 100644 index 00000000000..3d594467011 --- /dev/null +++ b/app/assets/images/emoji/flag_lb.png diff --git a/app/assets/images/emoji/flag_lc.png b/app/assets/images/emoji/flag_lc.png Binary files differnew file mode 100644 index 00000000000..45547b1e439 --- /dev/null +++ b/app/assets/images/emoji/flag_lc.png diff --git a/app/assets/images/emoji/flag_li.png b/app/assets/images/emoji/flag_li.png Binary files differnew file mode 100644 index 00000000000..0eafa6a2215 --- /dev/null +++ b/app/assets/images/emoji/flag_li.png diff --git a/app/assets/images/emoji/flag_lk.png b/app/assets/images/emoji/flag_lk.png Binary files differnew file mode 100644 index 00000000000..ab4fe10c40c --- /dev/null +++ b/app/assets/images/emoji/flag_lk.png diff --git a/app/assets/images/emoji/flag_lr.png b/app/assets/images/emoji/flag_lr.png Binary files differnew file mode 100644 index 00000000000..f66f267fea2 --- /dev/null +++ b/app/assets/images/emoji/flag_lr.png diff --git a/app/assets/images/emoji/flag_ls.png b/app/assets/images/emoji/flag_ls.png Binary files differnew file mode 100644 index 00000000000..24745631e3c --- /dev/null +++ b/app/assets/images/emoji/flag_ls.png diff --git a/app/assets/images/emoji/flag_lt.png b/app/assets/images/emoji/flag_lt.png Binary files differnew file mode 100644 index 00000000000..d644b56d62a --- /dev/null +++ b/app/assets/images/emoji/flag_lt.png diff --git a/app/assets/images/emoji/flag_lu.png b/app/assets/images/emoji/flag_lu.png Binary files differnew file mode 100644 index 00000000000..a2df9c92994 --- /dev/null +++ b/app/assets/images/emoji/flag_lu.png diff --git a/app/assets/images/emoji/flag_lv.png b/app/assets/images/emoji/flag_lv.png Binary files differnew file mode 100644 index 00000000000..ae680d5f0e3 --- /dev/null +++ b/app/assets/images/emoji/flag_lv.png diff --git a/app/assets/images/emoji/flag_ly.png b/app/assets/images/emoji/flag_ly.png Binary files differnew file mode 100644 index 00000000000..f6e77b0f3ba --- /dev/null +++ b/app/assets/images/emoji/flag_ly.png diff --git a/app/assets/images/emoji/flag_ma.png b/app/assets/images/emoji/flag_ma.png Binary files differnew file mode 100644 index 00000000000..c4a056722cd --- /dev/null +++ b/app/assets/images/emoji/flag_ma.png diff --git a/app/assets/images/emoji/flag_mc.png b/app/assets/images/emoji/flag_mc.png Binary files differnew file mode 100644 index 00000000000..d479eab98cb --- /dev/null +++ b/app/assets/images/emoji/flag_mc.png diff --git a/app/assets/images/emoji/flag_md.png b/app/assets/images/emoji/flag_md.png Binary files differnew file mode 100644 index 00000000000..a7a72539872 --- /dev/null +++ b/app/assets/images/emoji/flag_md.png diff --git a/app/assets/images/emoji/flag_me.png b/app/assets/images/emoji/flag_me.png Binary files differnew file mode 100644 index 00000000000..7c771e7e120 --- /dev/null +++ b/app/assets/images/emoji/flag_me.png diff --git a/app/assets/images/emoji/flag_mf.png b/app/assets/images/emoji/flag_mf.png Binary files differnew file mode 100644 index 00000000000..70c761036bd --- /dev/null +++ b/app/assets/images/emoji/flag_mf.png diff --git a/app/assets/images/emoji/flag_mg.png b/app/assets/images/emoji/flag_mg.png Binary files differnew file mode 100644 index 00000000000..2f3ccdda76f --- /dev/null +++ b/app/assets/images/emoji/flag_mg.png diff --git a/app/assets/images/emoji/flag_mh.png b/app/assets/images/emoji/flag_mh.png Binary files differnew file mode 100644 index 00000000000..598016481c1 --- /dev/null +++ b/app/assets/images/emoji/flag_mh.png diff --git a/app/assets/images/emoji/flag_mk.png b/app/assets/images/emoji/flag_mk.png Binary files differnew file mode 100644 index 00000000000..7ba775ee75c --- /dev/null +++ b/app/assets/images/emoji/flag_mk.png diff --git a/app/assets/images/emoji/flag_ml.png b/app/assets/images/emoji/flag_ml.png Binary files differnew file mode 100644 index 00000000000..68343785468 --- /dev/null +++ b/app/assets/images/emoji/flag_ml.png diff --git a/app/assets/images/emoji/flag_mm.png b/app/assets/images/emoji/flag_mm.png Binary files differnew file mode 100644 index 00000000000..37dc7d71591 --- /dev/null +++ b/app/assets/images/emoji/flag_mm.png diff --git a/app/assets/images/emoji/flag_mn.png b/app/assets/images/emoji/flag_mn.png Binary files differnew file mode 100644 index 00000000000..1f146bbcd1a --- /dev/null +++ b/app/assets/images/emoji/flag_mn.png diff --git a/app/assets/images/emoji/flag_mo.png b/app/assets/images/emoji/flag_mo.png Binary files differnew file mode 100644 index 00000000000..7edde31f64b --- /dev/null +++ b/app/assets/images/emoji/flag_mo.png diff --git a/app/assets/images/emoji/flag_mp.png b/app/assets/images/emoji/flag_mp.png Binary files differnew file mode 100644 index 00000000000..17ec1c441ed --- /dev/null +++ b/app/assets/images/emoji/flag_mp.png diff --git a/app/assets/images/emoji/flag_mq.png b/app/assets/images/emoji/flag_mq.png Binary files differnew file mode 100644 index 00000000000..1e672dc9087 --- /dev/null +++ b/app/assets/images/emoji/flag_mq.png diff --git a/app/assets/images/emoji/flag_mr.png b/app/assets/images/emoji/flag_mr.png Binary files differnew file mode 100644 index 00000000000..f87de46effe --- /dev/null +++ b/app/assets/images/emoji/flag_mr.png diff --git a/app/assets/images/emoji/flag_ms.png b/app/assets/images/emoji/flag_ms.png Binary files differnew file mode 100644 index 00000000000..480b0d4ebda --- /dev/null +++ b/app/assets/images/emoji/flag_ms.png diff --git a/app/assets/images/emoji/flag_mt.png b/app/assets/images/emoji/flag_mt.png Binary files differnew file mode 100644 index 00000000000..c9e1dbdce82 --- /dev/null +++ b/app/assets/images/emoji/flag_mt.png diff --git a/app/assets/images/emoji/flag_mu.png b/app/assets/images/emoji/flag_mu.png Binary files differnew file mode 100644 index 00000000000..55b33cb7c33 --- /dev/null +++ b/app/assets/images/emoji/flag_mu.png diff --git a/app/assets/images/emoji/flag_mv.png b/app/assets/images/emoji/flag_mv.png Binary files differnew file mode 100644 index 00000000000..ce5867126ae --- /dev/null +++ b/app/assets/images/emoji/flag_mv.png diff --git a/app/assets/images/emoji/flag_mw.png b/app/assets/images/emoji/flag_mw.png Binary files differnew file mode 100644 index 00000000000..003d8548401 --- /dev/null +++ b/app/assets/images/emoji/flag_mw.png diff --git a/app/assets/images/emoji/flag_mx.png b/app/assets/images/emoji/flag_mx.png Binary files differnew file mode 100644 index 00000000000..42572bcd0ba --- /dev/null +++ b/app/assets/images/emoji/flag_mx.png diff --git a/app/assets/images/emoji/flag_my.png b/app/assets/images/emoji/flag_my.png Binary files differnew file mode 100644 index 00000000000..17526c26742 --- /dev/null +++ b/app/assets/images/emoji/flag_my.png diff --git a/app/assets/images/emoji/flag_mz.png b/app/assets/images/emoji/flag_mz.png Binary files differnew file mode 100644 index 00000000000..2352a78e786 --- /dev/null +++ b/app/assets/images/emoji/flag_mz.png diff --git a/app/assets/images/emoji/flag_na.png b/app/assets/images/emoji/flag_na.png Binary files differnew file mode 100644 index 00000000000..ed31c3df04d --- /dev/null +++ b/app/assets/images/emoji/flag_na.png diff --git a/app/assets/images/emoji/flag_nc.png b/app/assets/images/emoji/flag_nc.png Binary files differnew file mode 100644 index 00000000000..90b3afebfa3 --- /dev/null +++ b/app/assets/images/emoji/flag_nc.png diff --git a/app/assets/images/emoji/flag_ne.png b/app/assets/images/emoji/flag_ne.png Binary files differnew file mode 100644 index 00000000000..f98a1173c2a --- /dev/null +++ b/app/assets/images/emoji/flag_ne.png diff --git a/app/assets/images/emoji/flag_nf.png b/app/assets/images/emoji/flag_nf.png Binary files differnew file mode 100644 index 00000000000..9099e767420 --- /dev/null +++ b/app/assets/images/emoji/flag_nf.png diff --git a/app/assets/images/emoji/flag_ng.png b/app/assets/images/emoji/flag_ng.png Binary files differnew file mode 100644 index 00000000000..ea0abeff1a1 --- /dev/null +++ b/app/assets/images/emoji/flag_ng.png diff --git a/app/assets/images/emoji/flag_ni.png b/app/assets/images/emoji/flag_ni.png Binary files differnew file mode 100644 index 00000000000..772920dfa10 --- /dev/null +++ b/app/assets/images/emoji/flag_ni.png diff --git a/app/assets/images/emoji/flag_nl.png b/app/assets/images/emoji/flag_nl.png Binary files differnew file mode 100644 index 00000000000..83a0e817e41 --- /dev/null +++ b/app/assets/images/emoji/flag_nl.png diff --git a/app/assets/images/emoji/flag_no.png b/app/assets/images/emoji/flag_no.png Binary files differnew file mode 100644 index 00000000000..99d3142eb7b --- /dev/null +++ b/app/assets/images/emoji/flag_no.png diff --git a/app/assets/images/emoji/flag_np.png b/app/assets/images/emoji/flag_np.png Binary files differnew file mode 100644 index 00000000000..87425a8dfef --- /dev/null +++ b/app/assets/images/emoji/flag_np.png diff --git a/app/assets/images/emoji/flag_nr.png b/app/assets/images/emoji/flag_nr.png Binary files differnew file mode 100644 index 00000000000..b3e3a5d5621 --- /dev/null +++ b/app/assets/images/emoji/flag_nr.png diff --git a/app/assets/images/emoji/flag_nu.png b/app/assets/images/emoji/flag_nu.png Binary files differnew file mode 100644 index 00000000000..f03614443ee --- /dev/null +++ b/app/assets/images/emoji/flag_nu.png diff --git a/app/assets/images/emoji/flag_nz.png b/app/assets/images/emoji/flag_nz.png Binary files differnew file mode 100644 index 00000000000..a4eeeab9cd9 --- /dev/null +++ b/app/assets/images/emoji/flag_nz.png diff --git a/app/assets/images/emoji/flag_om.png b/app/assets/images/emoji/flag_om.png Binary files differnew file mode 100644 index 00000000000..ea824ba31e7 --- /dev/null +++ b/app/assets/images/emoji/flag_om.png diff --git a/app/assets/images/emoji/flag_pa.png b/app/assets/images/emoji/flag_pa.png Binary files differnew file mode 100644 index 00000000000..c3091d89889 --- /dev/null +++ b/app/assets/images/emoji/flag_pa.png diff --git a/app/assets/images/emoji/flag_pe.png b/app/assets/images/emoji/flag_pe.png Binary files differnew file mode 100644 index 00000000000..39223aa9dbb --- /dev/null +++ b/app/assets/images/emoji/flag_pe.png diff --git a/app/assets/images/emoji/flag_pf.png b/app/assets/images/emoji/flag_pf.png Binary files differnew file mode 100644 index 00000000000..113445f8f6e --- /dev/null +++ b/app/assets/images/emoji/flag_pf.png diff --git a/app/assets/images/emoji/flag_pg.png b/app/assets/images/emoji/flag_pg.png Binary files differnew file mode 100644 index 00000000000..825e9dcb762 --- /dev/null +++ b/app/assets/images/emoji/flag_pg.png diff --git a/app/assets/images/emoji/flag_ph.png b/app/assets/images/emoji/flag_ph.png Binary files differnew file mode 100644 index 00000000000..8260e15bd2c --- /dev/null +++ b/app/assets/images/emoji/flag_ph.png diff --git a/app/assets/images/emoji/flag_pk.png b/app/assets/images/emoji/flag_pk.png Binary files differnew file mode 100644 index 00000000000..a7b6a1c5074 --- /dev/null +++ b/app/assets/images/emoji/flag_pk.png diff --git a/app/assets/images/emoji/flag_pl.png b/app/assets/images/emoji/flag_pl.png Binary files differnew file mode 100644 index 00000000000..19de2edec11 --- /dev/null +++ b/app/assets/images/emoji/flag_pl.png diff --git a/app/assets/images/emoji/flag_pm.png b/app/assets/images/emoji/flag_pm.png Binary files differnew file mode 100644 index 00000000000..2ca60554193 --- /dev/null +++ b/app/assets/images/emoji/flag_pm.png diff --git a/app/assets/images/emoji/flag_pn.png b/app/assets/images/emoji/flag_pn.png Binary files differnew file mode 100644 index 00000000000..f2263b154bc --- /dev/null +++ b/app/assets/images/emoji/flag_pn.png diff --git a/app/assets/images/emoji/flag_pr.png b/app/assets/images/emoji/flag_pr.png Binary files differnew file mode 100644 index 00000000000..d0209cddb79 --- /dev/null +++ b/app/assets/images/emoji/flag_pr.png diff --git a/app/assets/images/emoji/flag_ps.png b/app/assets/images/emoji/flag_ps.png Binary files differnew file mode 100644 index 00000000000..7ccab09778b --- /dev/null +++ b/app/assets/images/emoji/flag_ps.png diff --git a/app/assets/images/emoji/flag_pt.png b/app/assets/images/emoji/flag_pt.png Binary files differnew file mode 100644 index 00000000000..cc93f27c64b --- /dev/null +++ b/app/assets/images/emoji/flag_pt.png diff --git a/app/assets/images/emoji/flag_pw.png b/app/assets/images/emoji/flag_pw.png Binary files differnew file mode 100644 index 00000000000..154b2f12d3c --- /dev/null +++ b/app/assets/images/emoji/flag_pw.png diff --git a/app/assets/images/emoji/flag_py.png b/app/assets/images/emoji/flag_py.png Binary files differnew file mode 100644 index 00000000000..662ad2f6ff1 --- /dev/null +++ b/app/assets/images/emoji/flag_py.png diff --git a/app/assets/images/emoji/flag_qa.png b/app/assets/images/emoji/flag_qa.png Binary files differnew file mode 100644 index 00000000000..a01d8b05cc7 --- /dev/null +++ b/app/assets/images/emoji/flag_qa.png diff --git a/app/assets/images/emoji/flag_re.png b/app/assets/images/emoji/flag_re.png Binary files differnew file mode 100644 index 00000000000..57f2bbe9df8 --- /dev/null +++ b/app/assets/images/emoji/flag_re.png diff --git a/app/assets/images/emoji/flag_ro.png b/app/assets/images/emoji/flag_ro.png Binary files differnew file mode 100644 index 00000000000..3e48c447706 --- /dev/null +++ b/app/assets/images/emoji/flag_ro.png diff --git a/app/assets/images/emoji/flag_rs.png b/app/assets/images/emoji/flag_rs.png Binary files differnew file mode 100644 index 00000000000..9df6c9a5235 --- /dev/null +++ b/app/assets/images/emoji/flag_rs.png diff --git a/app/assets/images/emoji/flag_ru.png b/app/assets/images/emoji/flag_ru.png Binary files differnew file mode 100644 index 00000000000..e50c9db90e7 --- /dev/null +++ b/app/assets/images/emoji/flag_ru.png diff --git a/app/assets/images/emoji/flag_rw.png b/app/assets/images/emoji/flag_rw.png Binary files differnew file mode 100644 index 00000000000..c238c874e1d --- /dev/null +++ b/app/assets/images/emoji/flag_rw.png diff --git a/app/assets/images/emoji/flag_sa.png b/app/assets/images/emoji/flag_sa.png Binary files differnew file mode 100644 index 00000000000..4941be7d198 --- /dev/null +++ b/app/assets/images/emoji/flag_sa.png diff --git a/app/assets/images/emoji/flag_sb.png b/app/assets/images/emoji/flag_sb.png Binary files differnew file mode 100644 index 00000000000..7d8f1ac6130 --- /dev/null +++ b/app/assets/images/emoji/flag_sb.png diff --git a/app/assets/images/emoji/flag_sc.png b/app/assets/images/emoji/flag_sc.png Binary files differnew file mode 100644 index 00000000000..6ae4d90765e --- /dev/null +++ b/app/assets/images/emoji/flag_sc.png diff --git a/app/assets/images/emoji/flag_sd.png b/app/assets/images/emoji/flag_sd.png Binary files differnew file mode 100644 index 00000000000..963be1b36fb --- /dev/null +++ b/app/assets/images/emoji/flag_sd.png diff --git a/app/assets/images/emoji/flag_se.png b/app/assets/images/emoji/flag_se.png Binary files differnew file mode 100644 index 00000000000..fc0d0e0ce89 --- /dev/null +++ b/app/assets/images/emoji/flag_se.png diff --git a/app/assets/images/emoji/flag_sg.png b/app/assets/images/emoji/flag_sg.png Binary files differnew file mode 100644 index 00000000000..de3c7737c42 --- /dev/null +++ b/app/assets/images/emoji/flag_sg.png diff --git a/app/assets/images/emoji/flag_sh.png b/app/assets/images/emoji/flag_sh.png Binary files differnew file mode 100644 index 00000000000..40cd9e44e96 --- /dev/null +++ b/app/assets/images/emoji/flag_sh.png diff --git a/app/assets/images/emoji/flag_si.png b/app/assets/images/emoji/flag_si.png Binary files differnew file mode 100644 index 00000000000..e308999dba2 --- /dev/null +++ b/app/assets/images/emoji/flag_si.png diff --git a/app/assets/images/emoji/flag_sj.png b/app/assets/images/emoji/flag_sj.png Binary files differnew file mode 100644 index 00000000000..5884e648228 --- /dev/null +++ b/app/assets/images/emoji/flag_sj.png diff --git a/app/assets/images/emoji/flag_sk.png b/app/assets/images/emoji/flag_sk.png Binary files differnew file mode 100644 index 00000000000..4259d0e1418 --- /dev/null +++ b/app/assets/images/emoji/flag_sk.png diff --git a/app/assets/images/emoji/flag_sl.png b/app/assets/images/emoji/flag_sl.png Binary files differnew file mode 100644 index 00000000000..d2cc68830ab --- /dev/null +++ b/app/assets/images/emoji/flag_sl.png diff --git a/app/assets/images/emoji/flag_sm.png b/app/assets/images/emoji/flag_sm.png Binary files differnew file mode 100644 index 00000000000..03b8708754e --- /dev/null +++ b/app/assets/images/emoji/flag_sm.png diff --git a/app/assets/images/emoji/flag_sn.png b/app/assets/images/emoji/flag_sn.png Binary files differnew file mode 100644 index 00000000000..5368bbe93df --- /dev/null +++ b/app/assets/images/emoji/flag_sn.png diff --git a/app/assets/images/emoji/flag_so.png b/app/assets/images/emoji/flag_so.png Binary files differnew file mode 100644 index 00000000000..68a0597365a --- /dev/null +++ b/app/assets/images/emoji/flag_so.png diff --git a/app/assets/images/emoji/flag_sr.png b/app/assets/images/emoji/flag_sr.png Binary files differnew file mode 100644 index 00000000000..d3251327035 --- /dev/null +++ b/app/assets/images/emoji/flag_sr.png diff --git a/app/assets/images/emoji/flag_ss.png b/app/assets/images/emoji/flag_ss.png Binary files differnew file mode 100644 index 00000000000..122977e798f --- /dev/null +++ b/app/assets/images/emoji/flag_ss.png diff --git a/app/assets/images/emoji/flag_st.png b/app/assets/images/emoji/flag_st.png Binary files differnew file mode 100644 index 00000000000..f83a863d612 --- /dev/null +++ b/app/assets/images/emoji/flag_st.png diff --git a/app/assets/images/emoji/flag_sv.png b/app/assets/images/emoji/flag_sv.png Binary files differnew file mode 100644 index 00000000000..efb83e2f253 --- /dev/null +++ b/app/assets/images/emoji/flag_sv.png diff --git a/app/assets/images/emoji/flag_sx.png b/app/assets/images/emoji/flag_sx.png Binary files differnew file mode 100644 index 00000000000..94b760fbedf --- /dev/null +++ b/app/assets/images/emoji/flag_sx.png diff --git a/app/assets/images/emoji/flag_sy.png b/app/assets/images/emoji/flag_sy.png Binary files differnew file mode 100644 index 00000000000..09a8ee8f78c --- /dev/null +++ b/app/assets/images/emoji/flag_sy.png diff --git a/app/assets/images/emoji/flag_sz.png b/app/assets/images/emoji/flag_sz.png Binary files differnew file mode 100644 index 00000000000..f74e82ea1fd --- /dev/null +++ b/app/assets/images/emoji/flag_sz.png diff --git a/app/assets/images/emoji/flag_ta.png b/app/assets/images/emoji/flag_ta.png Binary files differnew file mode 100644 index 00000000000..b44283e90e2 --- /dev/null +++ b/app/assets/images/emoji/flag_ta.png diff --git a/app/assets/images/emoji/flag_tc.png b/app/assets/images/emoji/flag_tc.png Binary files differnew file mode 100644 index 00000000000..156b33d1ba6 --- /dev/null +++ b/app/assets/images/emoji/flag_tc.png diff --git a/app/assets/images/emoji/flag_td.png b/app/assets/images/emoji/flag_td.png Binary files differnew file mode 100644 index 00000000000..ebe7f592828 --- /dev/null +++ b/app/assets/images/emoji/flag_td.png diff --git a/app/assets/images/emoji/flag_tf.png b/app/assets/images/emoji/flag_tf.png Binary files differnew file mode 100644 index 00000000000..a1a3ad68ee2 --- /dev/null +++ b/app/assets/images/emoji/flag_tf.png diff --git a/app/assets/images/emoji/flag_tg.png b/app/assets/images/emoji/flag_tg.png Binary files differnew file mode 100644 index 00000000000..826b73c9ac5 --- /dev/null +++ b/app/assets/images/emoji/flag_tg.png diff --git a/app/assets/images/emoji/flag_th.png b/app/assets/images/emoji/flag_th.png Binary files differnew file mode 100644 index 00000000000..93ff542c5a6 --- /dev/null +++ b/app/assets/images/emoji/flag_th.png diff --git a/app/assets/images/emoji/flag_tj.png b/app/assets/images/emoji/flag_tj.png Binary files differnew file mode 100644 index 00000000000..7a8a0b6190a --- /dev/null +++ b/app/assets/images/emoji/flag_tj.png diff --git a/app/assets/images/emoji/flag_tk.png b/app/assets/images/emoji/flag_tk.png Binary files differnew file mode 100644 index 00000000000..2fa5a21b1bb --- /dev/null +++ b/app/assets/images/emoji/flag_tk.png diff --git a/app/assets/images/emoji/flag_tl.png b/app/assets/images/emoji/flag_tl.png Binary files differnew file mode 100644 index 00000000000..5b120eccc6f --- /dev/null +++ b/app/assets/images/emoji/flag_tl.png diff --git a/app/assets/images/emoji/flag_tm.png b/app/assets/images/emoji/flag_tm.png Binary files differnew file mode 100644 index 00000000000..c3c4f532302 --- /dev/null +++ b/app/assets/images/emoji/flag_tm.png diff --git a/app/assets/images/emoji/flag_tn.png b/app/assets/images/emoji/flag_tn.png Binary files differnew file mode 100644 index 00000000000..58ef161229f --- /dev/null +++ b/app/assets/images/emoji/flag_tn.png diff --git a/app/assets/images/emoji/flag_to.png b/app/assets/images/emoji/flag_to.png Binary files differnew file mode 100644 index 00000000000..1ffa7bb9d19 --- /dev/null +++ b/app/assets/images/emoji/flag_to.png diff --git a/app/assets/images/emoji/flag_tr.png b/app/assets/images/emoji/flag_tr.png Binary files differnew file mode 100644 index 00000000000..325251fae88 --- /dev/null +++ b/app/assets/images/emoji/flag_tr.png diff --git a/app/assets/images/emoji/flag_tt.png b/app/assets/images/emoji/flag_tt.png Binary files differnew file mode 100644 index 00000000000..ed3bb39a300 --- /dev/null +++ b/app/assets/images/emoji/flag_tt.png diff --git a/app/assets/images/emoji/flag_tv.png b/app/assets/images/emoji/flag_tv.png Binary files differnew file mode 100644 index 00000000000..e82c65c7bb9 --- /dev/null +++ b/app/assets/images/emoji/flag_tv.png diff --git a/app/assets/images/emoji/flag_tw.png b/app/assets/images/emoji/flag_tw.png Binary files differnew file mode 100644 index 00000000000..3a8f00b5928 --- /dev/null +++ b/app/assets/images/emoji/flag_tw.png diff --git a/app/assets/images/emoji/flag_tz.png b/app/assets/images/emoji/flag_tz.png Binary files differnew file mode 100644 index 00000000000..2a020853d4e --- /dev/null +++ b/app/assets/images/emoji/flag_tz.png diff --git a/app/assets/images/emoji/flag_ua.png b/app/assets/images/emoji/flag_ua.png Binary files differnew file mode 100644 index 00000000000..cd84d1bbd36 --- /dev/null +++ b/app/assets/images/emoji/flag_ua.png diff --git a/app/assets/images/emoji/flag_ug.png b/app/assets/images/emoji/flag_ug.png Binary files differnew file mode 100644 index 00000000000..dc97690eb55 --- /dev/null +++ b/app/assets/images/emoji/flag_ug.png diff --git a/app/assets/images/emoji/flag_um.png b/app/assets/images/emoji/flag_um.png Binary files differnew file mode 100644 index 00000000000..4a7ee3cdf13 --- /dev/null +++ b/app/assets/images/emoji/flag_um.png diff --git a/app/assets/images/emoji/flag_us.png b/app/assets/images/emoji/flag_us.png Binary files differnew file mode 100644 index 00000000000..9f730305860 --- /dev/null +++ b/app/assets/images/emoji/flag_us.png diff --git a/app/assets/images/emoji/flag_uy.png b/app/assets/images/emoji/flag_uy.png Binary files differnew file mode 100644 index 00000000000..b8002a697a6 --- /dev/null +++ b/app/assets/images/emoji/flag_uy.png diff --git a/app/assets/images/emoji/flag_uz.png b/app/assets/images/emoji/flag_uz.png Binary files differnew file mode 100644 index 00000000000..d56ca9bc424 --- /dev/null +++ b/app/assets/images/emoji/flag_uz.png diff --git a/app/assets/images/emoji/flag_va.png b/app/assets/images/emoji/flag_va.png Binary files differnew file mode 100644 index 00000000000..ddaf5e3141b --- /dev/null +++ b/app/assets/images/emoji/flag_va.png diff --git a/app/assets/images/emoji/flag_vc.png b/app/assets/images/emoji/flag_vc.png Binary files differnew file mode 100644 index 00000000000..43703c62a71 --- /dev/null +++ b/app/assets/images/emoji/flag_vc.png diff --git a/app/assets/images/emoji/flag_ve.png b/app/assets/images/emoji/flag_ve.png Binary files differnew file mode 100644 index 00000000000..1b62796824e --- /dev/null +++ b/app/assets/images/emoji/flag_ve.png diff --git a/app/assets/images/emoji/flag_vg.png b/app/assets/images/emoji/flag_vg.png Binary files differnew file mode 100644 index 00000000000..536f780f1c0 --- /dev/null +++ b/app/assets/images/emoji/flag_vg.png diff --git a/app/assets/images/emoji/flag_vi.png b/app/assets/images/emoji/flag_vi.png Binary files differnew file mode 100644 index 00000000000..64102012cfe --- /dev/null +++ b/app/assets/images/emoji/flag_vi.png diff --git a/app/assets/images/emoji/flag_vn.png b/app/assets/images/emoji/flag_vn.png Binary files differnew file mode 100644 index 00000000000..427036046b6 --- /dev/null +++ b/app/assets/images/emoji/flag_vn.png diff --git a/app/assets/images/emoji/flag_vu.png b/app/assets/images/emoji/flag_vu.png Binary files differnew file mode 100644 index 00000000000..706eba44070 --- /dev/null +++ b/app/assets/images/emoji/flag_vu.png diff --git a/app/assets/images/emoji/flag_wf.png b/app/assets/images/emoji/flag_wf.png Binary files differnew file mode 100644 index 00000000000..70c761036bd --- /dev/null +++ b/app/assets/images/emoji/flag_wf.png diff --git a/app/assets/images/emoji/flag_white.png b/app/assets/images/emoji/flag_white.png Binary files differnew file mode 100644 index 00000000000..86d6e96d5e9 --- /dev/null +++ b/app/assets/images/emoji/flag_white.png diff --git a/app/assets/images/emoji/flag_ws.png b/app/assets/images/emoji/flag_ws.png Binary files differnew file mode 100644 index 00000000000..a1ea0703141 --- /dev/null +++ b/app/assets/images/emoji/flag_ws.png diff --git a/app/assets/images/emoji/flag_xk.png b/app/assets/images/emoji/flag_xk.png Binary files differnew file mode 100644 index 00000000000..e587a446632 --- /dev/null +++ b/app/assets/images/emoji/flag_xk.png diff --git a/app/assets/images/emoji/flag_ye.png b/app/assets/images/emoji/flag_ye.png Binary files differnew file mode 100644 index 00000000000..eadfebd5f67 --- /dev/null +++ b/app/assets/images/emoji/flag_ye.png diff --git a/app/assets/images/emoji/flag_yt.png b/app/assets/images/emoji/flag_yt.png Binary files differnew file mode 100644 index 00000000000..c81fa6d886e --- /dev/null +++ b/app/assets/images/emoji/flag_yt.png diff --git a/app/assets/images/emoji/flag_za.png b/app/assets/images/emoji/flag_za.png Binary files differnew file mode 100644 index 00000000000..f397ef5072f --- /dev/null +++ b/app/assets/images/emoji/flag_za.png diff --git a/app/assets/images/emoji/flag_zm.png b/app/assets/images/emoji/flag_zm.png Binary files differnew file mode 100644 index 00000000000..2494a31f662 --- /dev/null +++ b/app/assets/images/emoji/flag_zm.png diff --git a/app/assets/images/emoji/flag_zw.png b/app/assets/images/emoji/flag_zw.png Binary files differnew file mode 100644 index 00000000000..e09b9652be6 --- /dev/null +++ b/app/assets/images/emoji/flag_zw.png diff --git a/app/assets/images/emoji/flags.png b/app/assets/images/emoji/flags.png Binary files differnew file mode 100644 index 00000000000..3b451035a3a --- /dev/null +++ b/app/assets/images/emoji/flags.png diff --git a/app/assets/images/emoji/flashlight.png b/app/assets/images/emoji/flashlight.png Binary files differnew file mode 100644 index 00000000000..eee36c25067 --- /dev/null +++ b/app/assets/images/emoji/flashlight.png diff --git a/app/assets/images/emoji/fleur-de-lis.png b/app/assets/images/emoji/fleur-de-lis.png Binary files differnew file mode 100644 index 00000000000..c9250d27fa7 --- /dev/null +++ b/app/assets/images/emoji/fleur-de-lis.png diff --git a/app/assets/images/emoji/floppy_disk.png b/app/assets/images/emoji/floppy_disk.png Binary files differnew file mode 100644 index 00000000000..072a76d3c13 --- /dev/null +++ b/app/assets/images/emoji/floppy_disk.png diff --git a/app/assets/images/emoji/flower_playing_cards.png b/app/assets/images/emoji/flower_playing_cards.png Binary files differnew file mode 100644 index 00000000000..6766b044d95 --- /dev/null +++ b/app/assets/images/emoji/flower_playing_cards.png diff --git a/app/assets/images/emoji/flushed.png b/app/assets/images/emoji/flushed.png Binary files differnew file mode 100644 index 00000000000..829220bc470 --- /dev/null +++ b/app/assets/images/emoji/flushed.png diff --git a/app/assets/images/emoji/fog.png b/app/assets/images/emoji/fog.png Binary files differnew file mode 100644 index 00000000000..4e73c2de272 --- /dev/null +++ b/app/assets/images/emoji/fog.png diff --git a/app/assets/images/emoji/foggy.png b/app/assets/images/emoji/foggy.png Binary files differnew file mode 100644 index 00000000000..57702d8d3ac --- /dev/null +++ b/app/assets/images/emoji/foggy.png diff --git a/app/assets/images/emoji/football.png b/app/assets/images/emoji/football.png Binary files differnew file mode 100644 index 00000000000..10366f41fce --- /dev/null +++ b/app/assets/images/emoji/football.png diff --git a/app/assets/images/emoji/footprints.png b/app/assets/images/emoji/footprints.png Binary files differnew file mode 100644 index 00000000000..b2673c5a1a8 --- /dev/null +++ b/app/assets/images/emoji/footprints.png diff --git a/app/assets/images/emoji/fork_and_knife.png b/app/assets/images/emoji/fork_and_knife.png Binary files differnew file mode 100644 index 00000000000..09f1feaea1c --- /dev/null +++ b/app/assets/images/emoji/fork_and_knife.png diff --git a/app/assets/images/emoji/fork_knife_plate.png b/app/assets/images/emoji/fork_knife_plate.png Binary files differnew file mode 100644 index 00000000000..7411755f708 --- /dev/null +++ b/app/assets/images/emoji/fork_knife_plate.png diff --git a/app/assets/images/emoji/fountain.png b/app/assets/images/emoji/fountain.png Binary files differnew file mode 100644 index 00000000000..293f5d91c0f --- /dev/null +++ b/app/assets/images/emoji/fountain.png diff --git a/app/assets/images/emoji/four.png b/app/assets/images/emoji/four.png Binary files differnew file mode 100644 index 00000000000..b0e914aac45 --- /dev/null +++ b/app/assets/images/emoji/four.png diff --git a/app/assets/images/emoji/four_leaf_clover.png b/app/assets/images/emoji/four_leaf_clover.png Binary files differnew file mode 100644 index 00000000000..fdedfcc2b4e --- /dev/null +++ b/app/assets/images/emoji/four_leaf_clover.png diff --git a/app/assets/images/emoji/fox.png b/app/assets/images/emoji/fox.png Binary files differnew file mode 100644 index 00000000000..1ab339bf054 --- /dev/null +++ b/app/assets/images/emoji/fox.png diff --git a/app/assets/images/emoji/frame_photo.png b/app/assets/images/emoji/frame_photo.png Binary files differnew file mode 100644 index 00000000000..9fe84607bfd --- /dev/null +++ b/app/assets/images/emoji/frame_photo.png diff --git a/app/assets/images/emoji/free.png b/app/assets/images/emoji/free.png Binary files differnew file mode 100644 index 00000000000..b71956eb48a --- /dev/null +++ b/app/assets/images/emoji/free.png diff --git a/app/assets/images/emoji/french_bread.png b/app/assets/images/emoji/french_bread.png Binary files differnew file mode 100644 index 00000000000..4c2c5639822 --- /dev/null +++ b/app/assets/images/emoji/french_bread.png diff --git a/app/assets/images/emoji/fried_shrimp.png b/app/assets/images/emoji/fried_shrimp.png Binary files differnew file mode 100644 index 00000000000..752ba7f1398 --- /dev/null +++ b/app/assets/images/emoji/fried_shrimp.png diff --git a/app/assets/images/emoji/fries.png b/app/assets/images/emoji/fries.png Binary files differnew file mode 100644 index 00000000000..4e2a4caacef --- /dev/null +++ b/app/assets/images/emoji/fries.png diff --git a/app/assets/images/emoji/frog.png b/app/assets/images/emoji/frog.png Binary files differnew file mode 100644 index 00000000000..8825d1ad577 --- /dev/null +++ b/app/assets/images/emoji/frog.png diff --git a/app/assets/images/emoji/frowning.png b/app/assets/images/emoji/frowning.png Binary files differnew file mode 100644 index 00000000000..43ab6b0a1c1 --- /dev/null +++ b/app/assets/images/emoji/frowning.png diff --git a/app/assets/images/emoji/frowning2.png b/app/assets/images/emoji/frowning2.png Binary files differnew file mode 100644 index 00000000000..6ae71f233b9 --- /dev/null +++ b/app/assets/images/emoji/frowning2.png diff --git a/app/assets/images/emoji/fuelpump.png b/app/assets/images/emoji/fuelpump.png Binary files differnew file mode 100644 index 00000000000..05b18794474 --- /dev/null +++ b/app/assets/images/emoji/fuelpump.png diff --git a/app/assets/images/emoji/full_moon.png b/app/assets/images/emoji/full_moon.png Binary files differnew file mode 100644 index 00000000000..c9a2d6aa7c9 --- /dev/null +++ b/app/assets/images/emoji/full_moon.png diff --git a/app/assets/images/emoji/full_moon_with_face.png b/app/assets/images/emoji/full_moon_with_face.png Binary files differnew file mode 100644 index 00000000000..a5c25bbaf64 --- /dev/null +++ b/app/assets/images/emoji/full_moon_with_face.png diff --git a/app/assets/images/emoji/game_die.png b/app/assets/images/emoji/game_die.png Binary files differnew file mode 100644 index 00000000000..ad3626fe5e5 --- /dev/null +++ b/app/assets/images/emoji/game_die.png diff --git a/app/assets/images/emoji/gear.png b/app/assets/images/emoji/gear.png Binary files differnew file mode 100644 index 00000000000..2a1cc2c0ff4 --- /dev/null +++ b/app/assets/images/emoji/gear.png diff --git a/app/assets/images/emoji/gem.png b/app/assets/images/emoji/gem.png Binary files differnew file mode 100644 index 00000000000..db122d26a19 --- /dev/null +++ b/app/assets/images/emoji/gem.png diff --git a/app/assets/images/emoji/gemini.png b/app/assets/images/emoji/gemini.png Binary files differnew file mode 100644 index 00000000000..1a09698cf00 --- /dev/null +++ b/app/assets/images/emoji/gemini.png diff --git a/app/assets/images/emoji/ghost.png b/app/assets/images/emoji/ghost.png Binary files differnew file mode 100644 index 00000000000..5650bc0ed18 --- /dev/null +++ b/app/assets/images/emoji/ghost.png diff --git a/app/assets/images/emoji/gift.png b/app/assets/images/emoji/gift.png Binary files differnew file mode 100644 index 00000000000..844e2164560 --- /dev/null +++ b/app/assets/images/emoji/gift.png diff --git a/app/assets/images/emoji/gift_heart.png b/app/assets/images/emoji/gift_heart.png Binary files differnew file mode 100644 index 00000000000..902ceafe4d1 --- /dev/null +++ b/app/assets/images/emoji/gift_heart.png diff --git a/app/assets/images/emoji/girl.png b/app/assets/images/emoji/girl.png Binary files differnew file mode 100644 index 00000000000..dc1d4d08b39 --- /dev/null +++ b/app/assets/images/emoji/girl.png diff --git a/app/assets/images/emoji/girl_tone1.png b/app/assets/images/emoji/girl_tone1.png Binary files differnew file mode 100644 index 00000000000..bb667e88651 --- /dev/null +++ b/app/assets/images/emoji/girl_tone1.png diff --git a/app/assets/images/emoji/girl_tone2.png b/app/assets/images/emoji/girl_tone2.png Binary files differnew file mode 100644 index 00000000000..a59ed4a3f0d --- /dev/null +++ b/app/assets/images/emoji/girl_tone2.png diff --git a/app/assets/images/emoji/girl_tone3.png b/app/assets/images/emoji/girl_tone3.png Binary files differnew file mode 100644 index 00000000000..517e7f2a7b0 --- /dev/null +++ b/app/assets/images/emoji/girl_tone3.png diff --git a/app/assets/images/emoji/girl_tone4.png b/app/assets/images/emoji/girl_tone4.png Binary files differnew file mode 100644 index 00000000000..542d96c8487 --- /dev/null +++ b/app/assets/images/emoji/girl_tone4.png diff --git a/app/assets/images/emoji/girl_tone5.png b/app/assets/images/emoji/girl_tone5.png Binary files differnew file mode 100644 index 00000000000..66b7c28c2df --- /dev/null +++ b/app/assets/images/emoji/girl_tone5.png diff --git a/app/assets/images/emoji/globe_with_meridians.png b/app/assets/images/emoji/globe_with_meridians.png Binary files differnew file mode 100644 index 00000000000..82450c1a4ba --- /dev/null +++ b/app/assets/images/emoji/globe_with_meridians.png diff --git a/app/assets/images/emoji/goal.png b/app/assets/images/emoji/goal.png Binary files differnew file mode 100644 index 00000000000..df3a53da0fb --- /dev/null +++ b/app/assets/images/emoji/goal.png diff --git a/app/assets/images/emoji/goat.png b/app/assets/images/emoji/goat.png Binary files differnew file mode 100644 index 00000000000..f9d9e38a128 --- /dev/null +++ b/app/assets/images/emoji/goat.png diff --git a/app/assets/images/emoji/golf.png b/app/assets/images/emoji/golf.png Binary files differnew file mode 100644 index 00000000000..f65a21d8a46 --- /dev/null +++ b/app/assets/images/emoji/golf.png diff --git a/app/assets/images/emoji/golfer.png b/app/assets/images/emoji/golfer.png Binary files differnew file mode 100644 index 00000000000..39c552de86d --- /dev/null +++ b/app/assets/images/emoji/golfer.png diff --git a/app/assets/images/emoji/gorilla.png b/app/assets/images/emoji/gorilla.png Binary files differnew file mode 100644 index 00000000000..acc51e13622 --- /dev/null +++ b/app/assets/images/emoji/gorilla.png diff --git a/app/assets/images/emoji/grapes.png b/app/assets/images/emoji/grapes.png Binary files differnew file mode 100644 index 00000000000..30d22218896 --- /dev/null +++ b/app/assets/images/emoji/grapes.png diff --git a/app/assets/images/emoji/green_apple.png b/app/assets/images/emoji/green_apple.png Binary files differnew file mode 100644 index 00000000000..5fd51bd3915 --- /dev/null +++ b/app/assets/images/emoji/green_apple.png diff --git a/app/assets/images/emoji/green_book.png b/app/assets/images/emoji/green_book.png Binary files differnew file mode 100644 index 00000000000..e5e411cf3b5 --- /dev/null +++ b/app/assets/images/emoji/green_book.png diff --git a/app/assets/images/emoji/green_heart.png b/app/assets/images/emoji/green_heart.png Binary files differnew file mode 100644 index 00000000000..c52d60a58be --- /dev/null +++ b/app/assets/images/emoji/green_heart.png diff --git a/app/assets/images/emoji/grey_exclamation.png b/app/assets/images/emoji/grey_exclamation.png Binary files differnew file mode 100644 index 00000000000..9b64da8bf7f --- /dev/null +++ b/app/assets/images/emoji/grey_exclamation.png diff --git a/app/assets/images/emoji/grey_question.png b/app/assets/images/emoji/grey_question.png Binary files differnew file mode 100644 index 00000000000..6e7824c75f6 --- /dev/null +++ b/app/assets/images/emoji/grey_question.png diff --git a/app/assets/images/emoji/grimacing.png b/app/assets/images/emoji/grimacing.png Binary files differnew file mode 100644 index 00000000000..871b2f071c9 --- /dev/null +++ b/app/assets/images/emoji/grimacing.png diff --git a/app/assets/images/emoji/grin.png b/app/assets/images/emoji/grin.png Binary files differnew file mode 100644 index 00000000000..418d94c811b --- /dev/null +++ b/app/assets/images/emoji/grin.png diff --git a/app/assets/images/emoji/grinning.png b/app/assets/images/emoji/grinning.png Binary files differnew file mode 100644 index 00000000000..3e8e0dab78c --- /dev/null +++ b/app/assets/images/emoji/grinning.png diff --git a/app/assets/images/emoji/guardsman.png b/app/assets/images/emoji/guardsman.png Binary files differnew file mode 100644 index 00000000000..8d7ab3c473c --- /dev/null +++ b/app/assets/images/emoji/guardsman.png diff --git a/app/assets/images/emoji/guardsman_tone1.png b/app/assets/images/emoji/guardsman_tone1.png Binary files differnew file mode 100644 index 00000000000..cea9ba27468 --- /dev/null +++ b/app/assets/images/emoji/guardsman_tone1.png diff --git a/app/assets/images/emoji/guardsman_tone2.png b/app/assets/images/emoji/guardsman_tone2.png Binary files differnew file mode 100644 index 00000000000..037464e4028 --- /dev/null +++ b/app/assets/images/emoji/guardsman_tone2.png diff --git a/app/assets/images/emoji/guardsman_tone3.png b/app/assets/images/emoji/guardsman_tone3.png Binary files differnew file mode 100644 index 00000000000..0f6726fbe87 --- /dev/null +++ b/app/assets/images/emoji/guardsman_tone3.png diff --git a/app/assets/images/emoji/guardsman_tone4.png b/app/assets/images/emoji/guardsman_tone4.png Binary files differnew file mode 100644 index 00000000000..85fcf9a3b97 --- /dev/null +++ b/app/assets/images/emoji/guardsman_tone4.png diff --git a/app/assets/images/emoji/guardsman_tone5.png b/app/assets/images/emoji/guardsman_tone5.png Binary files differnew file mode 100644 index 00000000000..e5f9ca7d5a2 --- /dev/null +++ b/app/assets/images/emoji/guardsman_tone5.png diff --git a/app/assets/images/emoji/guitar.png b/app/assets/images/emoji/guitar.png Binary files differnew file mode 100644 index 00000000000..43d752f1e3d --- /dev/null +++ b/app/assets/images/emoji/guitar.png diff --git a/app/assets/images/emoji/gun.png b/app/assets/images/emoji/gun.png Binary files differnew file mode 100644 index 00000000000..89c5c244c7b --- /dev/null +++ b/app/assets/images/emoji/gun.png diff --git a/app/assets/images/emoji/haircut.png b/app/assets/images/emoji/haircut.png Binary files differnew file mode 100644 index 00000000000..91266b12930 --- /dev/null +++ b/app/assets/images/emoji/haircut.png diff --git a/app/assets/images/emoji/haircut_tone1.png b/app/assets/images/emoji/haircut_tone1.png Binary files differnew file mode 100644 index 00000000000..c743b74abeb --- /dev/null +++ b/app/assets/images/emoji/haircut_tone1.png diff --git a/app/assets/images/emoji/haircut_tone2.png b/app/assets/images/emoji/haircut_tone2.png Binary files differnew file mode 100644 index 00000000000..f144f8e55ce --- /dev/null +++ b/app/assets/images/emoji/haircut_tone2.png diff --git a/app/assets/images/emoji/haircut_tone3.png b/app/assets/images/emoji/haircut_tone3.png Binary files differnew file mode 100644 index 00000000000..d5ad19563ac --- /dev/null +++ b/app/assets/images/emoji/haircut_tone3.png diff --git a/app/assets/images/emoji/haircut_tone4.png b/app/assets/images/emoji/haircut_tone4.png Binary files differnew file mode 100644 index 00000000000..244fd3af008 --- /dev/null +++ b/app/assets/images/emoji/haircut_tone4.png diff --git a/app/assets/images/emoji/haircut_tone5.png b/app/assets/images/emoji/haircut_tone5.png Binary files differnew file mode 100644 index 00000000000..20a94a88623 --- /dev/null +++ b/app/assets/images/emoji/haircut_tone5.png diff --git a/app/assets/images/emoji/hamburger.png b/app/assets/images/emoji/hamburger.png Binary files differnew file mode 100644 index 00000000000..3573b28a1fd --- /dev/null +++ b/app/assets/images/emoji/hamburger.png diff --git a/app/assets/images/emoji/hammer.png b/app/assets/images/emoji/hammer.png Binary files differnew file mode 100644 index 00000000000..00736cce47d --- /dev/null +++ b/app/assets/images/emoji/hammer.png diff --git a/app/assets/images/emoji/hammer_pick.png b/app/assets/images/emoji/hammer_pick.png Binary files differnew file mode 100644 index 00000000000..3bee30ec588 --- /dev/null +++ b/app/assets/images/emoji/hammer_pick.png diff --git a/app/assets/images/emoji/hamster.png b/app/assets/images/emoji/hamster.png Binary files differnew file mode 100644 index 00000000000..9a04388e4e7 --- /dev/null +++ b/app/assets/images/emoji/hamster.png diff --git a/app/assets/images/emoji/hand_splayed.png b/app/assets/images/emoji/hand_splayed.png Binary files differnew file mode 100644 index 00000000000..fb5ae8ebb5a --- /dev/null +++ b/app/assets/images/emoji/hand_splayed.png diff --git a/app/assets/images/emoji/hand_splayed_tone1.png b/app/assets/images/emoji/hand_splayed_tone1.png Binary files differnew file mode 100644 index 00000000000..a7888e6bd23 --- /dev/null +++ b/app/assets/images/emoji/hand_splayed_tone1.png diff --git a/app/assets/images/emoji/hand_splayed_tone2.png b/app/assets/images/emoji/hand_splayed_tone2.png Binary files differnew file mode 100644 index 00000000000..cc10fbc272d --- /dev/null +++ b/app/assets/images/emoji/hand_splayed_tone2.png diff --git a/app/assets/images/emoji/hand_splayed_tone3.png b/app/assets/images/emoji/hand_splayed_tone3.png Binary files differnew file mode 100644 index 00000000000..707236ae8a4 --- /dev/null +++ b/app/assets/images/emoji/hand_splayed_tone3.png diff --git a/app/assets/images/emoji/hand_splayed_tone4.png b/app/assets/images/emoji/hand_splayed_tone4.png Binary files differnew file mode 100644 index 00000000000..1430df9c61f --- /dev/null +++ b/app/assets/images/emoji/hand_splayed_tone4.png diff --git a/app/assets/images/emoji/hand_splayed_tone5.png b/app/assets/images/emoji/hand_splayed_tone5.png Binary files differnew file mode 100644 index 00000000000..80bec971b6b --- /dev/null +++ b/app/assets/images/emoji/hand_splayed_tone5.png diff --git a/app/assets/images/emoji/handbag.png b/app/assets/images/emoji/handbag.png Binary files differnew file mode 100644 index 00000000000..cbf75c5d25e --- /dev/null +++ b/app/assets/images/emoji/handbag.png diff --git a/app/assets/images/emoji/handball.png b/app/assets/images/emoji/handball.png Binary files differnew file mode 100644 index 00000000000..1152f1344c7 --- /dev/null +++ b/app/assets/images/emoji/handball.png diff --git a/app/assets/images/emoji/handball_tone1.png b/app/assets/images/emoji/handball_tone1.png Binary files differnew file mode 100644 index 00000000000..c26cac2df98 --- /dev/null +++ b/app/assets/images/emoji/handball_tone1.png diff --git a/app/assets/images/emoji/handball_tone2.png b/app/assets/images/emoji/handball_tone2.png Binary files differnew file mode 100644 index 00000000000..7baaf95a9a2 --- /dev/null +++ b/app/assets/images/emoji/handball_tone2.png diff --git a/app/assets/images/emoji/handball_tone3.png b/app/assets/images/emoji/handball_tone3.png Binary files differnew file mode 100644 index 00000000000..0e3a37c3d40 --- /dev/null +++ b/app/assets/images/emoji/handball_tone3.png diff --git a/app/assets/images/emoji/handball_tone4.png b/app/assets/images/emoji/handball_tone4.png Binary files differnew file mode 100644 index 00000000000..e1233f38266 --- /dev/null +++ b/app/assets/images/emoji/handball_tone4.png diff --git a/app/assets/images/emoji/handball_tone5.png b/app/assets/images/emoji/handball_tone5.png Binary files differnew file mode 100644 index 00000000000..6b1eb9b64b0 --- /dev/null +++ b/app/assets/images/emoji/handball_tone5.png diff --git a/app/assets/images/emoji/handshake.png b/app/assets/images/emoji/handshake.png Binary files differnew file mode 100644 index 00000000000..c5d35fd8138 --- /dev/null +++ b/app/assets/images/emoji/handshake.png diff --git a/app/assets/images/emoji/handshake_tone1.png b/app/assets/images/emoji/handshake_tone1.png Binary files differnew file mode 100644 index 00000000000..8f8fbb9bdca --- /dev/null +++ b/app/assets/images/emoji/handshake_tone1.png diff --git a/app/assets/images/emoji/handshake_tone2.png b/app/assets/images/emoji/handshake_tone2.png Binary files differnew file mode 100644 index 00000000000..336a77a6d78 --- /dev/null +++ b/app/assets/images/emoji/handshake_tone2.png diff --git a/app/assets/images/emoji/handshake_tone3.png b/app/assets/images/emoji/handshake_tone3.png Binary files differnew file mode 100644 index 00000000000..95f62d4fecd --- /dev/null +++ b/app/assets/images/emoji/handshake_tone3.png diff --git a/app/assets/images/emoji/handshake_tone4.png b/app/assets/images/emoji/handshake_tone4.png Binary files differnew file mode 100644 index 00000000000..2b0a6433886 --- /dev/null +++ b/app/assets/images/emoji/handshake_tone4.png diff --git a/app/assets/images/emoji/handshake_tone5.png b/app/assets/images/emoji/handshake_tone5.png Binary files differnew file mode 100644 index 00000000000..40189ee68e4 --- /dev/null +++ b/app/assets/images/emoji/handshake_tone5.png diff --git a/app/assets/images/emoji/hash.png b/app/assets/images/emoji/hash.png Binary files differnew file mode 100644 index 00000000000..6e26f0070b0 --- /dev/null +++ b/app/assets/images/emoji/hash.png diff --git a/app/assets/images/emoji/hatched_chick.png b/app/assets/images/emoji/hatched_chick.png Binary files differnew file mode 100644 index 00000000000..31dfb511e0e --- /dev/null +++ b/app/assets/images/emoji/hatched_chick.png diff --git a/app/assets/images/emoji/hatching_chick.png b/app/assets/images/emoji/hatching_chick.png Binary files differnew file mode 100644 index 00000000000..c5b0e8f3bcc --- /dev/null +++ b/app/assets/images/emoji/hatching_chick.png diff --git a/app/assets/images/emoji/head_bandage.png b/app/assets/images/emoji/head_bandage.png Binary files differnew file mode 100644 index 00000000000..0be723085e0 --- /dev/null +++ b/app/assets/images/emoji/head_bandage.png diff --git a/app/assets/images/emoji/headphones.png b/app/assets/images/emoji/headphones.png Binary files differnew file mode 100644 index 00000000000..e9fd34041d8 --- /dev/null +++ b/app/assets/images/emoji/headphones.png diff --git a/app/assets/images/emoji/hear_no_evil.png b/app/assets/images/emoji/hear_no_evil.png Binary files differnew file mode 100644 index 00000000000..74b6be0c6c5 --- /dev/null +++ b/app/assets/images/emoji/hear_no_evil.png diff --git a/app/assets/images/emoji/heart.png b/app/assets/images/emoji/heart.png Binary files differnew file mode 100644 index 00000000000..638cb72dc4e --- /dev/null +++ b/app/assets/images/emoji/heart.png diff --git a/app/assets/images/emoji/heart_decoration.png b/app/assets/images/emoji/heart_decoration.png Binary files differnew file mode 100644 index 00000000000..5443f60bc63 --- /dev/null +++ b/app/assets/images/emoji/heart_decoration.png diff --git a/app/assets/images/emoji/heart_exclamation.png b/app/assets/images/emoji/heart_exclamation.png Binary files differnew file mode 100644 index 00000000000..91b520be40b --- /dev/null +++ b/app/assets/images/emoji/heart_exclamation.png diff --git a/app/assets/images/emoji/heart_eyes.png b/app/assets/images/emoji/heart_eyes.png Binary files differnew file mode 100644 index 00000000000..73fbee29d4e --- /dev/null +++ b/app/assets/images/emoji/heart_eyes.png diff --git a/app/assets/images/emoji/heart_eyes_cat.png b/app/assets/images/emoji/heart_eyes_cat.png Binary files differnew file mode 100644 index 00000000000..bc5a833f9a1 --- /dev/null +++ b/app/assets/images/emoji/heart_eyes_cat.png diff --git a/app/assets/images/emoji/heartbeat.png b/app/assets/images/emoji/heartbeat.png Binary files differnew file mode 100644 index 00000000000..0bcf2d1d567 --- /dev/null +++ b/app/assets/images/emoji/heartbeat.png diff --git a/app/assets/images/emoji/heartpulse.png b/app/assets/images/emoji/heartpulse.png Binary files differnew file mode 100644 index 00000000000..d6e694e972f --- /dev/null +++ b/app/assets/images/emoji/heartpulse.png diff --git a/app/assets/images/emoji/hearts.png b/app/assets/images/emoji/hearts.png Binary files differnew file mode 100644 index 00000000000..393c3ed5267 --- /dev/null +++ b/app/assets/images/emoji/hearts.png diff --git a/app/assets/images/emoji/heavy_check_mark.png b/app/assets/images/emoji/heavy_check_mark.png Binary files differnew file mode 100644 index 00000000000..03bd695377e --- /dev/null +++ b/app/assets/images/emoji/heavy_check_mark.png diff --git a/app/assets/images/emoji/heavy_division_sign.png b/app/assets/images/emoji/heavy_division_sign.png Binary files differnew file mode 100644 index 00000000000..df32ab21bea --- /dev/null +++ b/app/assets/images/emoji/heavy_division_sign.png diff --git a/app/assets/images/emoji/heavy_dollar_sign.png b/app/assets/images/emoji/heavy_dollar_sign.png Binary files differnew file mode 100644 index 00000000000..ef2c2e20590 --- /dev/null +++ b/app/assets/images/emoji/heavy_dollar_sign.png diff --git a/app/assets/images/emoji/heavy_minus_sign.png b/app/assets/images/emoji/heavy_minus_sign.png Binary files differnew file mode 100644 index 00000000000..054211caf12 --- /dev/null +++ b/app/assets/images/emoji/heavy_minus_sign.png diff --git a/app/assets/images/emoji/heavy_multiplication_x.png b/app/assets/images/emoji/heavy_multiplication_x.png Binary files differnew file mode 100644 index 00000000000..e47cc1b685d --- /dev/null +++ b/app/assets/images/emoji/heavy_multiplication_x.png diff --git a/app/assets/images/emoji/heavy_plus_sign.png b/app/assets/images/emoji/heavy_plus_sign.png Binary files differnew file mode 100644 index 00000000000..40799798aaf --- /dev/null +++ b/app/assets/images/emoji/heavy_plus_sign.png diff --git a/app/assets/images/emoji/helicopter.png b/app/assets/images/emoji/helicopter.png Binary files differnew file mode 100644 index 00000000000..7ec5f39a51a --- /dev/null +++ b/app/assets/images/emoji/helicopter.png diff --git a/app/assets/images/emoji/helmet_with_cross.png b/app/assets/images/emoji/helmet_with_cross.png Binary files differnew file mode 100644 index 00000000000..7140a676038 --- /dev/null +++ b/app/assets/images/emoji/helmet_with_cross.png diff --git a/app/assets/images/emoji/herb.png b/app/assets/images/emoji/herb.png Binary files differnew file mode 100644 index 00000000000..d984d1562bb --- /dev/null +++ b/app/assets/images/emoji/herb.png diff --git a/app/assets/images/emoji/hibiscus.png b/app/assets/images/emoji/hibiscus.png Binary files differnew file mode 100644 index 00000000000..39dd3524233 --- /dev/null +++ b/app/assets/images/emoji/hibiscus.png diff --git a/app/assets/images/emoji/high_brightness.png b/app/assets/images/emoji/high_brightness.png Binary files differnew file mode 100644 index 00000000000..c41f2d5fd50 --- /dev/null +++ b/app/assets/images/emoji/high_brightness.png diff --git a/app/assets/images/emoji/high_heel.png b/app/assets/images/emoji/high_heel.png Binary files differnew file mode 100644 index 00000000000..b331cbccc9d --- /dev/null +++ b/app/assets/images/emoji/high_heel.png diff --git a/app/assets/images/emoji/hockey.png b/app/assets/images/emoji/hockey.png Binary files differnew file mode 100644 index 00000000000..be94e9cbf73 --- /dev/null +++ b/app/assets/images/emoji/hockey.png diff --git a/app/assets/images/emoji/hole.png b/app/assets/images/emoji/hole.png Binary files differnew file mode 100644 index 00000000000..517d2ae0deb --- /dev/null +++ b/app/assets/images/emoji/hole.png diff --git a/app/assets/images/emoji/homes.png b/app/assets/images/emoji/homes.png Binary files differnew file mode 100644 index 00000000000..6ab4a2a2651 --- /dev/null +++ b/app/assets/images/emoji/homes.png diff --git a/app/assets/images/emoji/honey_pot.png b/app/assets/images/emoji/honey_pot.png Binary files differnew file mode 100644 index 00000000000..9d8f592955e --- /dev/null +++ b/app/assets/images/emoji/honey_pot.png diff --git a/app/assets/images/emoji/horse.png b/app/assets/images/emoji/horse.png Binary files differnew file mode 100644 index 00000000000..7cb1172f4e4 --- /dev/null +++ b/app/assets/images/emoji/horse.png diff --git a/app/assets/images/emoji/horse_racing.png b/app/assets/images/emoji/horse_racing.png Binary files differnew file mode 100644 index 00000000000..addf9edac56 --- /dev/null +++ b/app/assets/images/emoji/horse_racing.png diff --git a/app/assets/images/emoji/horse_racing_tone1.png b/app/assets/images/emoji/horse_racing_tone1.png Binary files differnew file mode 100644 index 00000000000..e9bf4092e98 --- /dev/null +++ b/app/assets/images/emoji/horse_racing_tone1.png diff --git a/app/assets/images/emoji/horse_racing_tone2.png b/app/assets/images/emoji/horse_racing_tone2.png Binary files differnew file mode 100644 index 00000000000..031bbc3d867 --- /dev/null +++ b/app/assets/images/emoji/horse_racing_tone2.png diff --git a/app/assets/images/emoji/horse_racing_tone3.png b/app/assets/images/emoji/horse_racing_tone3.png Binary files differnew file mode 100644 index 00000000000..b40ef891f9b --- /dev/null +++ b/app/assets/images/emoji/horse_racing_tone3.png diff --git a/app/assets/images/emoji/horse_racing_tone4.png b/app/assets/images/emoji/horse_racing_tone4.png Binary files differnew file mode 100644 index 00000000000..e286cb85065 --- /dev/null +++ b/app/assets/images/emoji/horse_racing_tone4.png diff --git a/app/assets/images/emoji/horse_racing_tone5.png b/app/assets/images/emoji/horse_racing_tone5.png Binary files differnew file mode 100644 index 00000000000..453c51c6007 --- /dev/null +++ b/app/assets/images/emoji/horse_racing_tone5.png diff --git a/app/assets/images/emoji/hospital.png b/app/assets/images/emoji/hospital.png Binary files differnew file mode 100644 index 00000000000..1cbce4ae767 --- /dev/null +++ b/app/assets/images/emoji/hospital.png diff --git a/app/assets/images/emoji/hot_pepper.png b/app/assets/images/emoji/hot_pepper.png Binary files differnew file mode 100644 index 00000000000..266675bd577 --- /dev/null +++ b/app/assets/images/emoji/hot_pepper.png diff --git a/app/assets/images/emoji/hotdog.png b/app/assets/images/emoji/hotdog.png Binary files differnew file mode 100644 index 00000000000..3c3354d94cb --- /dev/null +++ b/app/assets/images/emoji/hotdog.png diff --git a/app/assets/images/emoji/hotel.png b/app/assets/images/emoji/hotel.png Binary files differnew file mode 100644 index 00000000000..ea8f4c4979a --- /dev/null +++ b/app/assets/images/emoji/hotel.png diff --git a/app/assets/images/emoji/hotsprings.png b/app/assets/images/emoji/hotsprings.png Binary files differnew file mode 100644 index 00000000000..3d9df2d9475 --- /dev/null +++ b/app/assets/images/emoji/hotsprings.png diff --git a/app/assets/images/emoji/hourglass.png b/app/assets/images/emoji/hourglass.png Binary files differnew file mode 100644 index 00000000000..a5db2d1d3f4 --- /dev/null +++ b/app/assets/images/emoji/hourglass.png diff --git a/app/assets/images/emoji/hourglass_flowing_sand.png b/app/assets/images/emoji/hourglass_flowing_sand.png Binary files differnew file mode 100644 index 00000000000..b93b15ed6d8 --- /dev/null +++ b/app/assets/images/emoji/hourglass_flowing_sand.png diff --git a/app/assets/images/emoji/house.png b/app/assets/images/emoji/house.png Binary files differnew file mode 100644 index 00000000000..01c98a0ba92 --- /dev/null +++ b/app/assets/images/emoji/house.png diff --git a/app/assets/images/emoji/house_abandoned.png b/app/assets/images/emoji/house_abandoned.png Binary files differnew file mode 100644 index 00000000000..c55e81de990 --- /dev/null +++ b/app/assets/images/emoji/house_abandoned.png diff --git a/app/assets/images/emoji/house_with_garden.png b/app/assets/images/emoji/house_with_garden.png Binary files differnew file mode 100644 index 00000000000..0aae41598ef --- /dev/null +++ b/app/assets/images/emoji/house_with_garden.png diff --git a/app/assets/images/emoji/hugging.png b/app/assets/images/emoji/hugging.png Binary files differnew file mode 100644 index 00000000000..5bba6dc6d51 --- /dev/null +++ b/app/assets/images/emoji/hugging.png diff --git a/app/assets/images/emoji/hushed.png b/app/assets/images/emoji/hushed.png Binary files differnew file mode 100644 index 00000000000..cad0e23132e --- /dev/null +++ b/app/assets/images/emoji/hushed.png diff --git a/app/assets/images/emoji/ice_cream.png b/app/assets/images/emoji/ice_cream.png Binary files differnew file mode 100644 index 00000000000..94267b9c434 --- /dev/null +++ b/app/assets/images/emoji/ice_cream.png diff --git a/app/assets/images/emoji/ice_skate.png b/app/assets/images/emoji/ice_skate.png Binary files differnew file mode 100644 index 00000000000..8c449b0c039 --- /dev/null +++ b/app/assets/images/emoji/ice_skate.png diff --git a/app/assets/images/emoji/icecream.png b/app/assets/images/emoji/icecream.png Binary files differnew file mode 100644 index 00000000000..8f6546e31a5 --- /dev/null +++ b/app/assets/images/emoji/icecream.png diff --git a/app/assets/images/emoji/id.png b/app/assets/images/emoji/id.png Binary files differnew file mode 100644 index 00000000000..5bf69bf7ba8 --- /dev/null +++ b/app/assets/images/emoji/id.png diff --git a/app/assets/images/emoji/ideograph_advantage.png b/app/assets/images/emoji/ideograph_advantage.png Binary files differnew file mode 100644 index 00000000000..0c0d589caf0 --- /dev/null +++ b/app/assets/images/emoji/ideograph_advantage.png diff --git a/app/assets/images/emoji/imp.png b/app/assets/images/emoji/imp.png Binary files differnew file mode 100644 index 00000000000..9f9a9605539 --- /dev/null +++ b/app/assets/images/emoji/imp.png diff --git a/app/assets/images/emoji/inbox_tray.png b/app/assets/images/emoji/inbox_tray.png Binary files differnew file mode 100644 index 00000000000..41a6be2b0ee --- /dev/null +++ b/app/assets/images/emoji/inbox_tray.png diff --git a/app/assets/images/emoji/incoming_envelope.png b/app/assets/images/emoji/incoming_envelope.png Binary files differnew file mode 100644 index 00000000000..fd22e88182e --- /dev/null +++ b/app/assets/images/emoji/incoming_envelope.png diff --git a/app/assets/images/emoji/information_desk_person.png b/app/assets/images/emoji/information_desk_person.png Binary files differnew file mode 100644 index 00000000000..55fc6294d25 --- /dev/null +++ b/app/assets/images/emoji/information_desk_person.png diff --git a/app/assets/images/emoji/information_desk_person_tone1.png b/app/assets/images/emoji/information_desk_person_tone1.png Binary files differnew file mode 100644 index 00000000000..3d9e2247940 --- /dev/null +++ b/app/assets/images/emoji/information_desk_person_tone1.png diff --git a/app/assets/images/emoji/information_desk_person_tone2.png b/app/assets/images/emoji/information_desk_person_tone2.png Binary files differnew file mode 100644 index 00000000000..879e8b7966d --- /dev/null +++ b/app/assets/images/emoji/information_desk_person_tone2.png diff --git a/app/assets/images/emoji/information_desk_person_tone3.png b/app/assets/images/emoji/information_desk_person_tone3.png Binary files differnew file mode 100644 index 00000000000..307514eab67 --- /dev/null +++ b/app/assets/images/emoji/information_desk_person_tone3.png diff --git a/app/assets/images/emoji/information_desk_person_tone4.png b/app/assets/images/emoji/information_desk_person_tone4.png Binary files differnew file mode 100644 index 00000000000..297395dcb3f --- /dev/null +++ b/app/assets/images/emoji/information_desk_person_tone4.png diff --git a/app/assets/images/emoji/information_desk_person_tone5.png b/app/assets/images/emoji/information_desk_person_tone5.png Binary files differnew file mode 100644 index 00000000000..26f8f22b28b --- /dev/null +++ b/app/assets/images/emoji/information_desk_person_tone5.png diff --git a/app/assets/images/emoji/information_source.png b/app/assets/images/emoji/information_source.png Binary files differnew file mode 100644 index 00000000000..871f2db9314 --- /dev/null +++ b/app/assets/images/emoji/information_source.png diff --git a/app/assets/images/emoji/innocent.png b/app/assets/images/emoji/innocent.png Binary files differnew file mode 100644 index 00000000000..57f5151124f --- /dev/null +++ b/app/assets/images/emoji/innocent.png diff --git a/app/assets/images/emoji/interrobang.png b/app/assets/images/emoji/interrobang.png Binary files differnew file mode 100644 index 00000000000..509813e9bb2 --- /dev/null +++ b/app/assets/images/emoji/interrobang.png diff --git a/app/assets/images/emoji/iphone.png b/app/assets/images/emoji/iphone.png Binary files differnew file mode 100644 index 00000000000..fd377acf872 --- /dev/null +++ b/app/assets/images/emoji/iphone.png diff --git a/app/assets/images/emoji/island.png b/app/assets/images/emoji/island.png Binary files differnew file mode 100644 index 00000000000..7fd834389b7 --- /dev/null +++ b/app/assets/images/emoji/island.png diff --git a/app/assets/images/emoji/izakaya_lantern.png b/app/assets/images/emoji/izakaya_lantern.png Binary files differnew file mode 100644 index 00000000000..dfd933f6f36 --- /dev/null +++ b/app/assets/images/emoji/izakaya_lantern.png diff --git a/app/assets/images/emoji/jack_o_lantern.png b/app/assets/images/emoji/jack_o_lantern.png Binary files differnew file mode 100644 index 00000000000..44c3fc0aec9 --- /dev/null +++ b/app/assets/images/emoji/jack_o_lantern.png diff --git a/app/assets/images/emoji/japan.png b/app/assets/images/emoji/japan.png Binary files differnew file mode 100644 index 00000000000..d86d0a59e12 --- /dev/null +++ b/app/assets/images/emoji/japan.png diff --git a/app/assets/images/emoji/japanese_castle.png b/app/assets/images/emoji/japanese_castle.png Binary files differnew file mode 100644 index 00000000000..64b4e33a1ae --- /dev/null +++ b/app/assets/images/emoji/japanese_castle.png diff --git a/app/assets/images/emoji/japanese_goblin.png b/app/assets/images/emoji/japanese_goblin.png Binary files differnew file mode 100644 index 00000000000..515c6a2250e --- /dev/null +++ b/app/assets/images/emoji/japanese_goblin.png diff --git a/app/assets/images/emoji/japanese_ogre.png b/app/assets/images/emoji/japanese_ogre.png Binary files differnew file mode 100644 index 00000000000..fe8670fdaf1 --- /dev/null +++ b/app/assets/images/emoji/japanese_ogre.png diff --git a/app/assets/images/emoji/jeans.png b/app/assets/images/emoji/jeans.png Binary files differnew file mode 100644 index 00000000000..2a6869d674c --- /dev/null +++ b/app/assets/images/emoji/jeans.png diff --git a/app/assets/images/emoji/joy.png b/app/assets/images/emoji/joy.png Binary files differnew file mode 100644 index 00000000000..0ba3b1859d8 --- /dev/null +++ b/app/assets/images/emoji/joy.png diff --git a/app/assets/images/emoji/joy_cat.png b/app/assets/images/emoji/joy_cat.png Binary files differnew file mode 100644 index 00000000000..aac353179aa --- /dev/null +++ b/app/assets/images/emoji/joy_cat.png diff --git a/app/assets/images/emoji/joystick.png b/app/assets/images/emoji/joystick.png Binary files differnew file mode 100644 index 00000000000..1ee1905434e --- /dev/null +++ b/app/assets/images/emoji/joystick.png diff --git a/app/assets/images/emoji/juggling.png b/app/assets/images/emoji/juggling.png Binary files differnew file mode 100644 index 00000000000..a37f6224a42 --- /dev/null +++ b/app/assets/images/emoji/juggling.png diff --git a/app/assets/images/emoji/juggling_tone1.png b/app/assets/images/emoji/juggling_tone1.png Binary files differnew file mode 100644 index 00000000000..c18eda40031 --- /dev/null +++ b/app/assets/images/emoji/juggling_tone1.png diff --git a/app/assets/images/emoji/juggling_tone2.png b/app/assets/images/emoji/juggling_tone2.png Binary files differnew file mode 100644 index 00000000000..de3b7a555b6 --- /dev/null +++ b/app/assets/images/emoji/juggling_tone2.png diff --git a/app/assets/images/emoji/juggling_tone3.png b/app/assets/images/emoji/juggling_tone3.png Binary files differnew file mode 100644 index 00000000000..74ab6d85458 --- /dev/null +++ b/app/assets/images/emoji/juggling_tone3.png diff --git a/app/assets/images/emoji/juggling_tone4.png b/app/assets/images/emoji/juggling_tone4.png Binary files differnew file mode 100644 index 00000000000..1c57823203f --- /dev/null +++ b/app/assets/images/emoji/juggling_tone4.png diff --git a/app/assets/images/emoji/juggling_tone5.png b/app/assets/images/emoji/juggling_tone5.png Binary files differnew file mode 100644 index 00000000000..c343d6ee98a --- /dev/null +++ b/app/assets/images/emoji/juggling_tone5.png diff --git a/app/assets/images/emoji/kaaba.png b/app/assets/images/emoji/kaaba.png Binary files differnew file mode 100644 index 00000000000..1778c1138e4 --- /dev/null +++ b/app/assets/images/emoji/kaaba.png diff --git a/app/assets/images/emoji/key.png b/app/assets/images/emoji/key.png Binary files differnew file mode 100644 index 00000000000..319cd1b884c --- /dev/null +++ b/app/assets/images/emoji/key.png diff --git a/app/assets/images/emoji/key2.png b/app/assets/images/emoji/key2.png Binary files differnew file mode 100644 index 00000000000..e11d706c6c8 --- /dev/null +++ b/app/assets/images/emoji/key2.png diff --git a/app/assets/images/emoji/keyboard.png b/app/assets/images/emoji/keyboard.png Binary files differnew file mode 100644 index 00000000000..75027cb9af7 --- /dev/null +++ b/app/assets/images/emoji/keyboard.png diff --git a/app/assets/images/emoji/kimono.png b/app/assets/images/emoji/kimono.png Binary files differnew file mode 100644 index 00000000000..abe851115d1 --- /dev/null +++ b/app/assets/images/emoji/kimono.png diff --git a/app/assets/images/emoji/kiss.png b/app/assets/images/emoji/kiss.png Binary files differnew file mode 100644 index 00000000000..85e6dcfc4e8 --- /dev/null +++ b/app/assets/images/emoji/kiss.png diff --git a/app/assets/images/emoji/kiss_mm.png b/app/assets/images/emoji/kiss_mm.png Binary files differnew file mode 100644 index 00000000000..a9a0edae17c --- /dev/null +++ b/app/assets/images/emoji/kiss_mm.png diff --git a/app/assets/images/emoji/kiss_ww.png b/app/assets/images/emoji/kiss_ww.png Binary files differnew file mode 100644 index 00000000000..fdac73cbb1d --- /dev/null +++ b/app/assets/images/emoji/kiss_ww.png diff --git a/app/assets/images/emoji/kissing.png b/app/assets/images/emoji/kissing.png Binary files differnew file mode 100644 index 00000000000..39d325fd8e3 --- /dev/null +++ b/app/assets/images/emoji/kissing.png diff --git a/app/assets/images/emoji/kissing_cat.png b/app/assets/images/emoji/kissing_cat.png Binary files differnew file mode 100644 index 00000000000..6e0bcc77540 --- /dev/null +++ b/app/assets/images/emoji/kissing_cat.png diff --git a/app/assets/images/emoji/kissing_closed_eyes.png b/app/assets/images/emoji/kissing_closed_eyes.png Binary files differnew file mode 100644 index 00000000000..b684d7d4d6c --- /dev/null +++ b/app/assets/images/emoji/kissing_closed_eyes.png diff --git a/app/assets/images/emoji/kissing_heart.png b/app/assets/images/emoji/kissing_heart.png Binary files differnew file mode 100644 index 00000000000..0ff808fd614 --- /dev/null +++ b/app/assets/images/emoji/kissing_heart.png diff --git a/app/assets/images/emoji/kissing_smiling_eyes.png b/app/assets/images/emoji/kissing_smiling_eyes.png Binary files differnew file mode 100644 index 00000000000..e181f17099d --- /dev/null +++ b/app/assets/images/emoji/kissing_smiling_eyes.png diff --git a/app/assets/images/emoji/kiwi.png b/app/assets/images/emoji/kiwi.png Binary files differnew file mode 100644 index 00000000000..dfbd8258074 --- /dev/null +++ b/app/assets/images/emoji/kiwi.png diff --git a/app/assets/images/emoji/knife.png b/app/assets/images/emoji/knife.png Binary files differnew file mode 100644 index 00000000000..1acb9f3077b --- /dev/null +++ b/app/assets/images/emoji/knife.png diff --git a/app/assets/images/emoji/koala.png b/app/assets/images/emoji/koala.png Binary files differnew file mode 100644 index 00000000000..a0aa437a98c --- /dev/null +++ b/app/assets/images/emoji/koala.png diff --git a/app/assets/images/emoji/koko.png b/app/assets/images/emoji/koko.png Binary files differnew file mode 100644 index 00000000000..6450eb44d90 --- /dev/null +++ b/app/assets/images/emoji/koko.png diff --git a/app/assets/images/emoji/label.png b/app/assets/images/emoji/label.png Binary files differnew file mode 100644 index 00000000000..d41c9b4f1e1 --- /dev/null +++ b/app/assets/images/emoji/label.png diff --git a/app/assets/images/emoji/large_blue_circle.png b/app/assets/images/emoji/large_blue_circle.png Binary files differnew file mode 100644 index 00000000000..84078ef3127 --- /dev/null +++ b/app/assets/images/emoji/large_blue_circle.png diff --git a/app/assets/images/emoji/large_blue_diamond.png b/app/assets/images/emoji/large_blue_diamond.png Binary files differnew file mode 100644 index 00000000000..416a58bd5a8 --- /dev/null +++ b/app/assets/images/emoji/large_blue_diamond.png diff --git a/app/assets/images/emoji/large_orange_diamond.png b/app/assets/images/emoji/large_orange_diamond.png Binary files differnew file mode 100644 index 00000000000..73ff0ac36c8 --- /dev/null +++ b/app/assets/images/emoji/large_orange_diamond.png diff --git a/app/assets/images/emoji/last_quarter_moon.png b/app/assets/images/emoji/last_quarter_moon.png Binary files differnew file mode 100644 index 00000000000..0842a0dd408 --- /dev/null +++ b/app/assets/images/emoji/last_quarter_moon.png diff --git a/app/assets/images/emoji/last_quarter_moon_with_face.png b/app/assets/images/emoji/last_quarter_moon_with_face.png Binary files differnew file mode 100644 index 00000000000..94099343c5d --- /dev/null +++ b/app/assets/images/emoji/last_quarter_moon_with_face.png diff --git a/app/assets/images/emoji/laughing.png b/app/assets/images/emoji/laughing.png Binary files differnew file mode 100644 index 00000000000..d94e9505ba1 --- /dev/null +++ b/app/assets/images/emoji/laughing.png diff --git a/app/assets/images/emoji/leaves.png b/app/assets/images/emoji/leaves.png Binary files differnew file mode 100644 index 00000000000..1e43e1af820 --- /dev/null +++ b/app/assets/images/emoji/leaves.png diff --git a/app/assets/images/emoji/ledger.png b/app/assets/images/emoji/ledger.png Binary files differnew file mode 100644 index 00000000000..13e7561a4bd --- /dev/null +++ b/app/assets/images/emoji/ledger.png diff --git a/app/assets/images/emoji/left_facing_fist.png b/app/assets/images/emoji/left_facing_fist.png Binary files differnew file mode 100644 index 00000000000..a9d9fd8d59c --- /dev/null +++ b/app/assets/images/emoji/left_facing_fist.png diff --git a/app/assets/images/emoji/left_facing_fist_tone1.png b/app/assets/images/emoji/left_facing_fist_tone1.png Binary files differnew file mode 100644 index 00000000000..1262a6b4b69 --- /dev/null +++ b/app/assets/images/emoji/left_facing_fist_tone1.png diff --git a/app/assets/images/emoji/left_facing_fist_tone2.png b/app/assets/images/emoji/left_facing_fist_tone2.png Binary files differnew file mode 100644 index 00000000000..40bf70b82b2 --- /dev/null +++ b/app/assets/images/emoji/left_facing_fist_tone2.png diff --git a/app/assets/images/emoji/left_facing_fist_tone3.png b/app/assets/images/emoji/left_facing_fist_tone3.png Binary files differnew file mode 100644 index 00000000000..93f58145111 --- /dev/null +++ b/app/assets/images/emoji/left_facing_fist_tone3.png diff --git a/app/assets/images/emoji/left_facing_fist_tone4.png b/app/assets/images/emoji/left_facing_fist_tone4.png Binary files differnew file mode 100644 index 00000000000..d82b5ec91f0 --- /dev/null +++ b/app/assets/images/emoji/left_facing_fist_tone4.png diff --git a/app/assets/images/emoji/left_facing_fist_tone5.png b/app/assets/images/emoji/left_facing_fist_tone5.png Binary files differnew file mode 100644 index 00000000000..09ae4cd492b --- /dev/null +++ b/app/assets/images/emoji/left_facing_fist_tone5.png diff --git a/app/assets/images/emoji/left_luggage.png b/app/assets/images/emoji/left_luggage.png Binary files differnew file mode 100644 index 00000000000..887b23f3f25 --- /dev/null +++ b/app/assets/images/emoji/left_luggage.png diff --git a/app/assets/images/emoji/left_right_arrow.png b/app/assets/images/emoji/left_right_arrow.png Binary files differnew file mode 100644 index 00000000000..7937f24f2ac --- /dev/null +++ b/app/assets/images/emoji/left_right_arrow.png diff --git a/app/assets/images/emoji/leftwards_arrow_with_hook.png b/app/assets/images/emoji/leftwards_arrow_with_hook.png Binary files differnew file mode 100644 index 00000000000..ba45c2ad9e9 --- /dev/null +++ b/app/assets/images/emoji/leftwards_arrow_with_hook.png diff --git a/app/assets/images/emoji/lemon.png b/app/assets/images/emoji/lemon.png Binary files differnew file mode 100644 index 00000000000..9a7d95ca220 --- /dev/null +++ b/app/assets/images/emoji/lemon.png diff --git a/app/assets/images/emoji/leo.png b/app/assets/images/emoji/leo.png Binary files differnew file mode 100644 index 00000000000..30158d34de9 --- /dev/null +++ b/app/assets/images/emoji/leo.png diff --git a/app/assets/images/emoji/leopard.png b/app/assets/images/emoji/leopard.png Binary files differnew file mode 100644 index 00000000000..8aac3d49448 --- /dev/null +++ b/app/assets/images/emoji/leopard.png diff --git a/app/assets/images/emoji/level_slider.png b/app/assets/images/emoji/level_slider.png Binary files differnew file mode 100644 index 00000000000..720a3b34119 --- /dev/null +++ b/app/assets/images/emoji/level_slider.png diff --git a/app/assets/images/emoji/levitate.png b/app/assets/images/emoji/levitate.png Binary files differnew file mode 100644 index 00000000000..3dc315a3d91 --- /dev/null +++ b/app/assets/images/emoji/levitate.png diff --git a/app/assets/images/emoji/libra.png b/app/assets/images/emoji/libra.png Binary files differnew file mode 100644 index 00000000000..8fd133a357c --- /dev/null +++ b/app/assets/images/emoji/libra.png diff --git a/app/assets/images/emoji/lifter.png b/app/assets/images/emoji/lifter.png Binary files differnew file mode 100644 index 00000000000..afdeaa476af --- /dev/null +++ b/app/assets/images/emoji/lifter.png diff --git a/app/assets/images/emoji/lifter_tone1.png b/app/assets/images/emoji/lifter_tone1.png Binary files differnew file mode 100644 index 00000000000..febaad123ec --- /dev/null +++ b/app/assets/images/emoji/lifter_tone1.png diff --git a/app/assets/images/emoji/lifter_tone2.png b/app/assets/images/emoji/lifter_tone2.png Binary files differnew file mode 100644 index 00000000000..27ae794a18e --- /dev/null +++ b/app/assets/images/emoji/lifter_tone2.png diff --git a/app/assets/images/emoji/lifter_tone3.png b/app/assets/images/emoji/lifter_tone3.png Binary files differnew file mode 100644 index 00000000000..45c4c22c709 --- /dev/null +++ b/app/assets/images/emoji/lifter_tone3.png diff --git a/app/assets/images/emoji/lifter_tone4.png b/app/assets/images/emoji/lifter_tone4.png Binary files differnew file mode 100644 index 00000000000..67dd21d2464 --- /dev/null +++ b/app/assets/images/emoji/lifter_tone4.png diff --git a/app/assets/images/emoji/lifter_tone5.png b/app/assets/images/emoji/lifter_tone5.png Binary files differnew file mode 100644 index 00000000000..fa0152038b6 --- /dev/null +++ b/app/assets/images/emoji/lifter_tone5.png diff --git a/app/assets/images/emoji/light_rail.png b/app/assets/images/emoji/light_rail.png Binary files differnew file mode 100644 index 00000000000..a64829f5078 --- /dev/null +++ b/app/assets/images/emoji/light_rail.png diff --git a/app/assets/images/emoji/link.png b/app/assets/images/emoji/link.png Binary files differnew file mode 100644 index 00000000000..ae20f0f8eec --- /dev/null +++ b/app/assets/images/emoji/link.png diff --git a/app/assets/images/emoji/lion_face.png b/app/assets/images/emoji/lion_face.png Binary files differnew file mode 100644 index 00000000000..5062ab47ecf --- /dev/null +++ b/app/assets/images/emoji/lion_face.png diff --git a/app/assets/images/emoji/lips.png b/app/assets/images/emoji/lips.png Binary files differnew file mode 100644 index 00000000000..35f3cc2006f --- /dev/null +++ b/app/assets/images/emoji/lips.png diff --git a/app/assets/images/emoji/lipstick.png b/app/assets/images/emoji/lipstick.png Binary files differnew file mode 100644 index 00000000000..61a0c084c99 --- /dev/null +++ b/app/assets/images/emoji/lipstick.png diff --git a/app/assets/images/emoji/lizard.png b/app/assets/images/emoji/lizard.png Binary files differnew file mode 100644 index 00000000000..8363876050e --- /dev/null +++ b/app/assets/images/emoji/lizard.png diff --git a/app/assets/images/emoji/lock.png b/app/assets/images/emoji/lock.png Binary files differnew file mode 100644 index 00000000000..5a739c46644 --- /dev/null +++ b/app/assets/images/emoji/lock.png diff --git a/app/assets/images/emoji/lock_with_ink_pen.png b/app/assets/images/emoji/lock_with_ink_pen.png Binary files differnew file mode 100644 index 00000000000..19a07d162fb --- /dev/null +++ b/app/assets/images/emoji/lock_with_ink_pen.png diff --git a/app/assets/images/emoji/lollipop.png b/app/assets/images/emoji/lollipop.png Binary files differnew file mode 100644 index 00000000000..ad76d7bf916 --- /dev/null +++ b/app/assets/images/emoji/lollipop.png diff --git a/app/assets/images/emoji/loop.png b/app/assets/images/emoji/loop.png Binary files differnew file mode 100644 index 00000000000..0b82c8fe315 --- /dev/null +++ b/app/assets/images/emoji/loop.png diff --git a/app/assets/images/emoji/loud_sound.png b/app/assets/images/emoji/loud_sound.png Binary files differnew file mode 100644 index 00000000000..8370033a539 --- /dev/null +++ b/app/assets/images/emoji/loud_sound.png diff --git a/app/assets/images/emoji/loudspeaker.png b/app/assets/images/emoji/loudspeaker.png Binary files differnew file mode 100644 index 00000000000..5fd76a95b82 --- /dev/null +++ b/app/assets/images/emoji/loudspeaker.png diff --git a/app/assets/images/emoji/love_hotel.png b/app/assets/images/emoji/love_hotel.png Binary files differnew file mode 100644 index 00000000000..5e136be6f8b --- /dev/null +++ b/app/assets/images/emoji/love_hotel.png diff --git a/app/assets/images/emoji/love_letter.png b/app/assets/images/emoji/love_letter.png Binary files differnew file mode 100644 index 00000000000..3c3c767e784 --- /dev/null +++ b/app/assets/images/emoji/love_letter.png diff --git a/app/assets/images/emoji/low_brightness.png b/app/assets/images/emoji/low_brightness.png Binary files differnew file mode 100644 index 00000000000..543011d3961 --- /dev/null +++ b/app/assets/images/emoji/low_brightness.png diff --git a/app/assets/images/emoji/lying_face.png b/app/assets/images/emoji/lying_face.png Binary files differnew file mode 100644 index 00000000000..02827e2628b --- /dev/null +++ b/app/assets/images/emoji/lying_face.png diff --git a/app/assets/images/emoji/m.png b/app/assets/images/emoji/m.png Binary files differnew file mode 100644 index 00000000000..8a3506fc1d7 --- /dev/null +++ b/app/assets/images/emoji/m.png diff --git a/app/assets/images/emoji/mag.png b/app/assets/images/emoji/mag.png Binary files differnew file mode 100644 index 00000000000..55487156ac6 --- /dev/null +++ b/app/assets/images/emoji/mag.png diff --git a/app/assets/images/emoji/mag_right.png b/app/assets/images/emoji/mag_right.png Binary files differnew file mode 100644 index 00000000000..0f4b1bca876 --- /dev/null +++ b/app/assets/images/emoji/mag_right.png diff --git a/app/assets/images/emoji/mahjong.png b/app/assets/images/emoji/mahjong.png Binary files differnew file mode 100644 index 00000000000..66fd32025b2 --- /dev/null +++ b/app/assets/images/emoji/mahjong.png diff --git a/app/assets/images/emoji/mailbox.png b/app/assets/images/emoji/mailbox.png Binary files differnew file mode 100644 index 00000000000..ef5174e40dd --- /dev/null +++ b/app/assets/images/emoji/mailbox.png diff --git a/app/assets/images/emoji/mailbox_closed.png b/app/assets/images/emoji/mailbox_closed.png Binary files differnew file mode 100644 index 00000000000..ddc705db0d8 --- /dev/null +++ b/app/assets/images/emoji/mailbox_closed.png diff --git a/app/assets/images/emoji/mailbox_with_mail.png b/app/assets/images/emoji/mailbox_with_mail.png Binary files differnew file mode 100644 index 00000000000..5460616a5b1 --- /dev/null +++ b/app/assets/images/emoji/mailbox_with_mail.png diff --git a/app/assets/images/emoji/mailbox_with_no_mail.png b/app/assets/images/emoji/mailbox_with_no_mail.png Binary files differnew file mode 100644 index 00000000000..f9aeee6b15a --- /dev/null +++ b/app/assets/images/emoji/mailbox_with_no_mail.png diff --git a/app/assets/images/emoji/man.png b/app/assets/images/emoji/man.png Binary files differnew file mode 100644 index 00000000000..857a02e5146 --- /dev/null +++ b/app/assets/images/emoji/man.png diff --git a/app/assets/images/emoji/man_dancing.png b/app/assets/images/emoji/man_dancing.png Binary files differnew file mode 100644 index 00000000000..ccff3bede5a --- /dev/null +++ b/app/assets/images/emoji/man_dancing.png diff --git a/app/assets/images/emoji/man_dancing_tone1.png b/app/assets/images/emoji/man_dancing_tone1.png Binary files differnew file mode 100644 index 00000000000..e0b9f82d905 --- /dev/null +++ b/app/assets/images/emoji/man_dancing_tone1.png diff --git a/app/assets/images/emoji/man_dancing_tone2.png b/app/assets/images/emoji/man_dancing_tone2.png Binary files differnew file mode 100644 index 00000000000..a5beed56e2e --- /dev/null +++ b/app/assets/images/emoji/man_dancing_tone2.png diff --git a/app/assets/images/emoji/man_dancing_tone3.png b/app/assets/images/emoji/man_dancing_tone3.png Binary files differnew file mode 100644 index 00000000000..2fa20180a6e --- /dev/null +++ b/app/assets/images/emoji/man_dancing_tone3.png diff --git a/app/assets/images/emoji/man_dancing_tone4.png b/app/assets/images/emoji/man_dancing_tone4.png Binary files differnew file mode 100644 index 00000000000..bd3528c83ba --- /dev/null +++ b/app/assets/images/emoji/man_dancing_tone4.png diff --git a/app/assets/images/emoji/man_dancing_tone5.png b/app/assets/images/emoji/man_dancing_tone5.png Binary files differnew file mode 100644 index 00000000000..41fd4f880c9 --- /dev/null +++ b/app/assets/images/emoji/man_dancing_tone5.png diff --git a/app/assets/images/emoji/man_in_tuxedo.png b/app/assets/images/emoji/man_in_tuxedo.png Binary files differnew file mode 100644 index 00000000000..5f7e9303f89 --- /dev/null +++ b/app/assets/images/emoji/man_in_tuxedo.png diff --git a/app/assets/images/emoji/man_in_tuxedo_tone1.png b/app/assets/images/emoji/man_in_tuxedo_tone1.png Binary files differnew file mode 100644 index 00000000000..7b6b3acd99b --- /dev/null +++ b/app/assets/images/emoji/man_in_tuxedo_tone1.png diff --git a/app/assets/images/emoji/man_in_tuxedo_tone2.png b/app/assets/images/emoji/man_in_tuxedo_tone2.png Binary files differnew file mode 100644 index 00000000000..7975191b360 --- /dev/null +++ b/app/assets/images/emoji/man_in_tuxedo_tone2.png diff --git a/app/assets/images/emoji/man_in_tuxedo_tone3.png b/app/assets/images/emoji/man_in_tuxedo_tone3.png Binary files differnew file mode 100644 index 00000000000..a2816f600ae --- /dev/null +++ b/app/assets/images/emoji/man_in_tuxedo_tone3.png diff --git a/app/assets/images/emoji/man_in_tuxedo_tone4.png b/app/assets/images/emoji/man_in_tuxedo_tone4.png Binary files differnew file mode 100644 index 00000000000..ea8291760f9 --- /dev/null +++ b/app/assets/images/emoji/man_in_tuxedo_tone4.png diff --git a/app/assets/images/emoji/man_in_tuxedo_tone5.png b/app/assets/images/emoji/man_in_tuxedo_tone5.png Binary files differnew file mode 100644 index 00000000000..c743e05fc5e --- /dev/null +++ b/app/assets/images/emoji/man_in_tuxedo_tone5.png diff --git a/app/assets/images/emoji/man_tone1.png b/app/assets/images/emoji/man_tone1.png Binary files differnew file mode 100644 index 00000000000..bb86e963a80 --- /dev/null +++ b/app/assets/images/emoji/man_tone1.png diff --git a/app/assets/images/emoji/man_tone2.png b/app/assets/images/emoji/man_tone2.png Binary files differnew file mode 100644 index 00000000000..fdeeaff46f5 --- /dev/null +++ b/app/assets/images/emoji/man_tone2.png diff --git a/app/assets/images/emoji/man_tone3.png b/app/assets/images/emoji/man_tone3.png Binary files differnew file mode 100644 index 00000000000..7ae0b5df9cf --- /dev/null +++ b/app/assets/images/emoji/man_tone3.png diff --git a/app/assets/images/emoji/man_tone4.png b/app/assets/images/emoji/man_tone4.png Binary files differnew file mode 100644 index 00000000000..db14cde99b8 --- /dev/null +++ b/app/assets/images/emoji/man_tone4.png diff --git a/app/assets/images/emoji/man_tone5.png b/app/assets/images/emoji/man_tone5.png Binary files differnew file mode 100644 index 00000000000..7c67a70529c --- /dev/null +++ b/app/assets/images/emoji/man_tone5.png diff --git a/app/assets/images/emoji/man_with_gua_pi_mao.png b/app/assets/images/emoji/man_with_gua_pi_mao.png Binary files differnew file mode 100644 index 00000000000..7841e13608d --- /dev/null +++ b/app/assets/images/emoji/man_with_gua_pi_mao.png diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png Binary files differnew file mode 100644 index 00000000000..5b7b3def19c --- /dev/null +++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png Binary files differnew file mode 100644 index 00000000000..c8b9cf87f4b --- /dev/null +++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png Binary files differnew file mode 100644 index 00000000000..effdd0c4c84 --- /dev/null +++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png Binary files differnew file mode 100644 index 00000000000..f885ff46fa1 --- /dev/null +++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png Binary files differnew file mode 100644 index 00000000000..a6d55ca1380 --- /dev/null +++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png diff --git a/app/assets/images/emoji/man_with_turban.png b/app/assets/images/emoji/man_with_turban.png Binary files differnew file mode 100644 index 00000000000..51cf047f966 --- /dev/null +++ b/app/assets/images/emoji/man_with_turban.png diff --git a/app/assets/images/emoji/man_with_turban_tone1.png b/app/assets/images/emoji/man_with_turban_tone1.png Binary files differnew file mode 100644 index 00000000000..1e12ee4b231 --- /dev/null +++ b/app/assets/images/emoji/man_with_turban_tone1.png diff --git a/app/assets/images/emoji/man_with_turban_tone2.png b/app/assets/images/emoji/man_with_turban_tone2.png Binary files differnew file mode 100644 index 00000000000..37de4cceb23 --- /dev/null +++ b/app/assets/images/emoji/man_with_turban_tone2.png diff --git a/app/assets/images/emoji/man_with_turban_tone3.png b/app/assets/images/emoji/man_with_turban_tone3.png Binary files differnew file mode 100644 index 00000000000..f607afd3450 --- /dev/null +++ b/app/assets/images/emoji/man_with_turban_tone3.png diff --git a/app/assets/images/emoji/man_with_turban_tone4.png b/app/assets/images/emoji/man_with_turban_tone4.png Binary files differnew file mode 100644 index 00000000000..c05695888af --- /dev/null +++ b/app/assets/images/emoji/man_with_turban_tone4.png diff --git a/app/assets/images/emoji/man_with_turban_tone5.png b/app/assets/images/emoji/man_with_turban_tone5.png Binary files differnew file mode 100644 index 00000000000..4b4ff64720b --- /dev/null +++ b/app/assets/images/emoji/man_with_turban_tone5.png diff --git a/app/assets/images/emoji/mans_shoe.png b/app/assets/images/emoji/mans_shoe.png Binary files differnew file mode 100644 index 00000000000..4bf7541032c --- /dev/null +++ b/app/assets/images/emoji/mans_shoe.png diff --git a/app/assets/images/emoji/map.png b/app/assets/images/emoji/map.png Binary files differnew file mode 100644 index 00000000000..15efe32c798 --- /dev/null +++ b/app/assets/images/emoji/map.png diff --git a/app/assets/images/emoji/maple_leaf.png b/app/assets/images/emoji/maple_leaf.png Binary files differnew file mode 100644 index 00000000000..c49acea67f7 --- /dev/null +++ b/app/assets/images/emoji/maple_leaf.png diff --git a/app/assets/images/emoji/martial_arts_uniform.png b/app/assets/images/emoji/martial_arts_uniform.png Binary files differnew file mode 100644 index 00000000000..8d6114761f6 --- /dev/null +++ b/app/assets/images/emoji/martial_arts_uniform.png diff --git a/app/assets/images/emoji/mask.png b/app/assets/images/emoji/mask.png Binary files differnew file mode 100644 index 00000000000..1e800acd1c0 --- /dev/null +++ b/app/assets/images/emoji/mask.png diff --git a/app/assets/images/emoji/massage.png b/app/assets/images/emoji/massage.png Binary files differnew file mode 100644 index 00000000000..b91d845e374 --- /dev/null +++ b/app/assets/images/emoji/massage.png diff --git a/app/assets/images/emoji/massage_tone1.png b/app/assets/images/emoji/massage_tone1.png Binary files differnew file mode 100644 index 00000000000..e0f415d3186 --- /dev/null +++ b/app/assets/images/emoji/massage_tone1.png diff --git a/app/assets/images/emoji/massage_tone2.png b/app/assets/images/emoji/massage_tone2.png Binary files differnew file mode 100644 index 00000000000..0bb244a270b --- /dev/null +++ b/app/assets/images/emoji/massage_tone2.png diff --git a/app/assets/images/emoji/massage_tone3.png b/app/assets/images/emoji/massage_tone3.png Binary files differnew file mode 100644 index 00000000000..a117ee81a22 --- /dev/null +++ b/app/assets/images/emoji/massage_tone3.png diff --git a/app/assets/images/emoji/massage_tone4.png b/app/assets/images/emoji/massage_tone4.png Binary files differnew file mode 100644 index 00000000000..6f42ab017f4 --- /dev/null +++ b/app/assets/images/emoji/massage_tone4.png diff --git a/app/assets/images/emoji/massage_tone5.png b/app/assets/images/emoji/massage_tone5.png Binary files differnew file mode 100644 index 00000000000..6a388c0d0b5 --- /dev/null +++ b/app/assets/images/emoji/massage_tone5.png diff --git a/app/assets/images/emoji/meat_on_bone.png b/app/assets/images/emoji/meat_on_bone.png Binary files differnew file mode 100644 index 00000000000..b20a59d1690 --- /dev/null +++ b/app/assets/images/emoji/meat_on_bone.png diff --git a/app/assets/images/emoji/medal.png b/app/assets/images/emoji/medal.png Binary files differnew file mode 100644 index 00000000000..b85896b14da --- /dev/null +++ b/app/assets/images/emoji/medal.png diff --git a/app/assets/images/emoji/mega.png b/app/assets/images/emoji/mega.png Binary files differnew file mode 100644 index 00000000000..4e6735188e3 --- /dev/null +++ b/app/assets/images/emoji/mega.png diff --git a/app/assets/images/emoji/melon.png b/app/assets/images/emoji/melon.png Binary files differnew file mode 100644 index 00000000000..c01232d419d --- /dev/null +++ b/app/assets/images/emoji/melon.png diff --git a/app/assets/images/emoji/menorah.png b/app/assets/images/emoji/menorah.png Binary files differnew file mode 100644 index 00000000000..b4297362869 --- /dev/null +++ b/app/assets/images/emoji/menorah.png diff --git a/app/assets/images/emoji/mens.png b/app/assets/images/emoji/mens.png Binary files differnew file mode 100644 index 00000000000..f5a1e1ba0cd --- /dev/null +++ b/app/assets/images/emoji/mens.png diff --git a/app/assets/images/emoji/metal.png b/app/assets/images/emoji/metal.png Binary files differnew file mode 100644 index 00000000000..4aa6e7e0a44 --- /dev/null +++ b/app/assets/images/emoji/metal.png diff --git a/app/assets/images/emoji/metal_tone1.png b/app/assets/images/emoji/metal_tone1.png Binary files differnew file mode 100644 index 00000000000..c080d2addbd --- /dev/null +++ b/app/assets/images/emoji/metal_tone1.png diff --git a/app/assets/images/emoji/metal_tone2.png b/app/assets/images/emoji/metal_tone2.png Binary files differnew file mode 100644 index 00000000000..12313529bcf --- /dev/null +++ b/app/assets/images/emoji/metal_tone2.png diff --git a/app/assets/images/emoji/metal_tone3.png b/app/assets/images/emoji/metal_tone3.png Binary files differnew file mode 100644 index 00000000000..ca9be6ae67b --- /dev/null +++ b/app/assets/images/emoji/metal_tone3.png diff --git a/app/assets/images/emoji/metal_tone4.png b/app/assets/images/emoji/metal_tone4.png Binary files differnew file mode 100644 index 00000000000..abe28cbf890 --- /dev/null +++ b/app/assets/images/emoji/metal_tone4.png diff --git a/app/assets/images/emoji/metal_tone5.png b/app/assets/images/emoji/metal_tone5.png Binary files differnew file mode 100644 index 00000000000..0c6b5dd34ed --- /dev/null +++ b/app/assets/images/emoji/metal_tone5.png diff --git a/app/assets/images/emoji/metro.png b/app/assets/images/emoji/metro.png Binary files differnew file mode 100644 index 00000000000..1de8f0551f3 --- /dev/null +++ b/app/assets/images/emoji/metro.png diff --git a/app/assets/images/emoji/microphone.png b/app/assets/images/emoji/microphone.png Binary files differnew file mode 100644 index 00000000000..d4e6b0def25 --- /dev/null +++ b/app/assets/images/emoji/microphone.png diff --git a/app/assets/images/emoji/microphone2.png b/app/assets/images/emoji/microphone2.png Binary files differnew file mode 100644 index 00000000000..cd9167654ff --- /dev/null +++ b/app/assets/images/emoji/microphone2.png diff --git a/app/assets/images/emoji/microscope.png b/app/assets/images/emoji/microscope.png Binary files differnew file mode 100644 index 00000000000..90f5acf6a78 --- /dev/null +++ b/app/assets/images/emoji/microscope.png diff --git a/app/assets/images/emoji/middle_finger.png b/app/assets/images/emoji/middle_finger.png Binary files differnew file mode 100644 index 00000000000..697f7a25eb2 --- /dev/null +++ b/app/assets/images/emoji/middle_finger.png diff --git a/app/assets/images/emoji/middle_finger_tone1.png b/app/assets/images/emoji/middle_finger_tone1.png Binary files differnew file mode 100644 index 00000000000..61ef12a1548 --- /dev/null +++ b/app/assets/images/emoji/middle_finger_tone1.png diff --git a/app/assets/images/emoji/middle_finger_tone2.png b/app/assets/images/emoji/middle_finger_tone2.png Binary files differnew file mode 100644 index 00000000000..c31a69be9af --- /dev/null +++ b/app/assets/images/emoji/middle_finger_tone2.png diff --git a/app/assets/images/emoji/middle_finger_tone3.png b/app/assets/images/emoji/middle_finger_tone3.png Binary files differnew file mode 100644 index 00000000000..73ac216ce63 --- /dev/null +++ b/app/assets/images/emoji/middle_finger_tone3.png diff --git a/app/assets/images/emoji/middle_finger_tone4.png b/app/assets/images/emoji/middle_finger_tone4.png Binary files differnew file mode 100644 index 00000000000..80b8ab7706d --- /dev/null +++ b/app/assets/images/emoji/middle_finger_tone4.png diff --git a/app/assets/images/emoji/middle_finger_tone5.png b/app/assets/images/emoji/middle_finger_tone5.png Binary files differnew file mode 100644 index 00000000000..a8826b196e8 --- /dev/null +++ b/app/assets/images/emoji/middle_finger_tone5.png diff --git a/app/assets/images/emoji/military_medal.png b/app/assets/images/emoji/military_medal.png Binary files differnew file mode 100644 index 00000000000..ecd3fb03584 --- /dev/null +++ b/app/assets/images/emoji/military_medal.png diff --git a/app/assets/images/emoji/milk.png b/app/assets/images/emoji/milk.png Binary files differnew file mode 100644 index 00000000000..e4fcf2e64f3 --- /dev/null +++ b/app/assets/images/emoji/milk.png diff --git a/app/assets/images/emoji/milky_way.png b/app/assets/images/emoji/milky_way.png Binary files differnew file mode 100644 index 00000000000..b2b8ac59c5e --- /dev/null +++ b/app/assets/images/emoji/milky_way.png diff --git a/app/assets/images/emoji/minibus.png b/app/assets/images/emoji/minibus.png Binary files differnew file mode 100644 index 00000000000..c60dd8f47ab --- /dev/null +++ b/app/assets/images/emoji/minibus.png diff --git a/app/assets/images/emoji/minidisc.png b/app/assets/images/emoji/minidisc.png Binary files differnew file mode 100644 index 00000000000..9fa94cfbe74 --- /dev/null +++ b/app/assets/images/emoji/minidisc.png diff --git a/app/assets/images/emoji/mobile_phone_off.png b/app/assets/images/emoji/mobile_phone_off.png Binary files differnew file mode 100644 index 00000000000..8b661ec1c94 --- /dev/null +++ b/app/assets/images/emoji/mobile_phone_off.png diff --git a/app/assets/images/emoji/money_mouth.png b/app/assets/images/emoji/money_mouth.png Binary files differnew file mode 100644 index 00000000000..75fd1e90cb0 --- /dev/null +++ b/app/assets/images/emoji/money_mouth.png diff --git a/app/assets/images/emoji/money_with_wings.png b/app/assets/images/emoji/money_with_wings.png Binary files differnew file mode 100644 index 00000000000..f022b04b3c2 --- /dev/null +++ b/app/assets/images/emoji/money_with_wings.png diff --git a/app/assets/images/emoji/moneybag.png b/app/assets/images/emoji/moneybag.png Binary files differnew file mode 100644 index 00000000000..b9296be0902 --- /dev/null +++ b/app/assets/images/emoji/moneybag.png diff --git a/app/assets/images/emoji/monkey.png b/app/assets/images/emoji/monkey.png Binary files differnew file mode 100644 index 00000000000..9fae29448e3 --- /dev/null +++ b/app/assets/images/emoji/monkey.png diff --git a/app/assets/images/emoji/monkey_face.png b/app/assets/images/emoji/monkey_face.png Binary files differnew file mode 100644 index 00000000000..7cab9b91a82 --- /dev/null +++ b/app/assets/images/emoji/monkey_face.png diff --git a/app/assets/images/emoji/monorail.png b/app/assets/images/emoji/monorail.png Binary files differnew file mode 100644 index 00000000000..11eb1f574bf --- /dev/null +++ b/app/assets/images/emoji/monorail.png diff --git a/app/assets/images/emoji/mortar_board.png b/app/assets/images/emoji/mortar_board.png Binary files differnew file mode 100644 index 00000000000..8b17ddd9d00 --- /dev/null +++ b/app/assets/images/emoji/mortar_board.png diff --git a/app/assets/images/emoji/mosque.png b/app/assets/images/emoji/mosque.png Binary files differnew file mode 100644 index 00000000000..ef770b26d96 --- /dev/null +++ b/app/assets/images/emoji/mosque.png diff --git a/app/assets/images/emoji/motor_scooter.png b/app/assets/images/emoji/motor_scooter.png Binary files differnew file mode 100644 index 00000000000..c5afa72d807 --- /dev/null +++ b/app/assets/images/emoji/motor_scooter.png diff --git a/app/assets/images/emoji/motorboat.png b/app/assets/images/emoji/motorboat.png Binary files differnew file mode 100644 index 00000000000..0506db1a40f --- /dev/null +++ b/app/assets/images/emoji/motorboat.png diff --git a/app/assets/images/emoji/motorcycle.png b/app/assets/images/emoji/motorcycle.png Binary files differnew file mode 100644 index 00000000000..3d1d567e8ec --- /dev/null +++ b/app/assets/images/emoji/motorcycle.png diff --git a/app/assets/images/emoji/motorway.png b/app/assets/images/emoji/motorway.png Binary files differnew file mode 100644 index 00000000000..8c3d3d03e3f --- /dev/null +++ b/app/assets/images/emoji/motorway.png diff --git a/app/assets/images/emoji/mount_fuji.png b/app/assets/images/emoji/mount_fuji.png Binary files differnew file mode 100644 index 00000000000..88a54752458 --- /dev/null +++ b/app/assets/images/emoji/mount_fuji.png diff --git a/app/assets/images/emoji/mountain.png b/app/assets/images/emoji/mountain.png Binary files differnew file mode 100644 index 00000000000..6722ebdd294 --- /dev/null +++ b/app/assets/images/emoji/mountain.png diff --git a/app/assets/images/emoji/mountain_bicyclist.png b/app/assets/images/emoji/mountain_bicyclist.png Binary files differnew file mode 100644 index 00000000000..41d3dc3ac6f --- /dev/null +++ b/app/assets/images/emoji/mountain_bicyclist.png diff --git a/app/assets/images/emoji/mountain_bicyclist_tone1.png b/app/assets/images/emoji/mountain_bicyclist_tone1.png Binary files differnew file mode 100644 index 00000000000..e9f1daf5e40 --- /dev/null +++ b/app/assets/images/emoji/mountain_bicyclist_tone1.png diff --git a/app/assets/images/emoji/mountain_bicyclist_tone2.png b/app/assets/images/emoji/mountain_bicyclist_tone2.png Binary files differnew file mode 100644 index 00000000000..555b9e29d4d --- /dev/null +++ b/app/assets/images/emoji/mountain_bicyclist_tone2.png diff --git a/app/assets/images/emoji/mountain_bicyclist_tone3.png b/app/assets/images/emoji/mountain_bicyclist_tone3.png Binary files differnew file mode 100644 index 00000000000..7df5508ec8c --- /dev/null +++ b/app/assets/images/emoji/mountain_bicyclist_tone3.png diff --git a/app/assets/images/emoji/mountain_bicyclist_tone4.png b/app/assets/images/emoji/mountain_bicyclist_tone4.png Binary files differnew file mode 100644 index 00000000000..f94b3450697 --- /dev/null +++ b/app/assets/images/emoji/mountain_bicyclist_tone4.png diff --git a/app/assets/images/emoji/mountain_bicyclist_tone5.png b/app/assets/images/emoji/mountain_bicyclist_tone5.png Binary files differnew file mode 100644 index 00000000000..16a45861e1f --- /dev/null +++ b/app/assets/images/emoji/mountain_bicyclist_tone5.png diff --git a/app/assets/images/emoji/mountain_cableway.png b/app/assets/images/emoji/mountain_cableway.png Binary files differnew file mode 100644 index 00000000000..1dea73ca53b --- /dev/null +++ b/app/assets/images/emoji/mountain_cableway.png diff --git a/app/assets/images/emoji/mountain_railway.png b/app/assets/images/emoji/mountain_railway.png Binary files differnew file mode 100644 index 00000000000..ade2218e469 --- /dev/null +++ b/app/assets/images/emoji/mountain_railway.png diff --git a/app/assets/images/emoji/mountain_snow.png b/app/assets/images/emoji/mountain_snow.png Binary files differnew file mode 100644 index 00000000000..76e1cfd8313 --- /dev/null +++ b/app/assets/images/emoji/mountain_snow.png diff --git a/app/assets/images/emoji/mouse.png b/app/assets/images/emoji/mouse.png Binary files differnew file mode 100644 index 00000000000..50afcd3262e --- /dev/null +++ b/app/assets/images/emoji/mouse.png diff --git a/app/assets/images/emoji/mouse2.png b/app/assets/images/emoji/mouse2.png Binary files differnew file mode 100644 index 00000000000..20fb041f09f --- /dev/null +++ b/app/assets/images/emoji/mouse2.png diff --git a/app/assets/images/emoji/mouse_three_button.png b/app/assets/images/emoji/mouse_three_button.png Binary files differnew file mode 100644 index 00000000000..e84e96ff6e8 --- /dev/null +++ b/app/assets/images/emoji/mouse_three_button.png diff --git a/app/assets/images/emoji/movie_camera.png b/app/assets/images/emoji/movie_camera.png Binary files differnew file mode 100644 index 00000000000..4e73b130155 --- /dev/null +++ b/app/assets/images/emoji/movie_camera.png diff --git a/app/assets/images/emoji/moyai.png b/app/assets/images/emoji/moyai.png Binary files differnew file mode 100644 index 00000000000..e6a7779c45b --- /dev/null +++ b/app/assets/images/emoji/moyai.png diff --git a/app/assets/images/emoji/mrs_claus.png b/app/assets/images/emoji/mrs_claus.png Binary files differnew file mode 100644 index 00000000000..078f0657f95 --- /dev/null +++ b/app/assets/images/emoji/mrs_claus.png diff --git a/app/assets/images/emoji/mrs_claus_tone1.png b/app/assets/images/emoji/mrs_claus_tone1.png Binary files differnew file mode 100644 index 00000000000..d8a695d7035 --- /dev/null +++ b/app/assets/images/emoji/mrs_claus_tone1.png diff --git a/app/assets/images/emoji/mrs_claus_tone2.png b/app/assets/images/emoji/mrs_claus_tone2.png Binary files differnew file mode 100644 index 00000000000..0e17e8c51f3 --- /dev/null +++ b/app/assets/images/emoji/mrs_claus_tone2.png diff --git a/app/assets/images/emoji/mrs_claus_tone3.png b/app/assets/images/emoji/mrs_claus_tone3.png Binary files differnew file mode 100644 index 00000000000..c3ee4d1dfae --- /dev/null +++ b/app/assets/images/emoji/mrs_claus_tone3.png diff --git a/app/assets/images/emoji/mrs_claus_tone4.png b/app/assets/images/emoji/mrs_claus_tone4.png Binary files differnew file mode 100644 index 00000000000..68a556da2fe --- /dev/null +++ b/app/assets/images/emoji/mrs_claus_tone4.png diff --git a/app/assets/images/emoji/mrs_claus_tone5.png b/app/assets/images/emoji/mrs_claus_tone5.png Binary files differnew file mode 100644 index 00000000000..ccab3c40ff2 --- /dev/null +++ b/app/assets/images/emoji/mrs_claus_tone5.png diff --git a/app/assets/images/emoji/muscle.png b/app/assets/images/emoji/muscle.png Binary files differnew file mode 100644 index 00000000000..7e67c1880f7 --- /dev/null +++ b/app/assets/images/emoji/muscle.png diff --git a/app/assets/images/emoji/muscle_tone1.png b/app/assets/images/emoji/muscle_tone1.png Binary files differnew file mode 100644 index 00000000000..1522942ce51 --- /dev/null +++ b/app/assets/images/emoji/muscle_tone1.png diff --git a/app/assets/images/emoji/muscle_tone2.png b/app/assets/images/emoji/muscle_tone2.png Binary files differnew file mode 100644 index 00000000000..569c6e832ca --- /dev/null +++ b/app/assets/images/emoji/muscle_tone2.png diff --git a/app/assets/images/emoji/muscle_tone3.png b/app/assets/images/emoji/muscle_tone3.png Binary files differnew file mode 100644 index 00000000000..0a76b00fa89 --- /dev/null +++ b/app/assets/images/emoji/muscle_tone3.png diff --git a/app/assets/images/emoji/muscle_tone4.png b/app/assets/images/emoji/muscle_tone4.png Binary files differnew file mode 100644 index 00000000000..f0cf31328e0 --- /dev/null +++ b/app/assets/images/emoji/muscle_tone4.png diff --git a/app/assets/images/emoji/muscle_tone5.png b/app/assets/images/emoji/muscle_tone5.png Binary files differnew file mode 100644 index 00000000000..4fda92460e8 --- /dev/null +++ b/app/assets/images/emoji/muscle_tone5.png diff --git a/app/assets/images/emoji/mushroom.png b/app/assets/images/emoji/mushroom.png Binary files differnew file mode 100644 index 00000000000..dd85742ba2c --- /dev/null +++ b/app/assets/images/emoji/mushroom.png diff --git a/app/assets/images/emoji/musical_keyboard.png b/app/assets/images/emoji/musical_keyboard.png Binary files differnew file mode 100644 index 00000000000..442b7456842 --- /dev/null +++ b/app/assets/images/emoji/musical_keyboard.png diff --git a/app/assets/images/emoji/musical_note.png b/app/assets/images/emoji/musical_note.png Binary files differnew file mode 100644 index 00000000000..06691ef61bb --- /dev/null +++ b/app/assets/images/emoji/musical_note.png diff --git a/app/assets/images/emoji/musical_score.png b/app/assets/images/emoji/musical_score.png Binary files differnew file mode 100644 index 00000000000..47dc05a8ef5 --- /dev/null +++ b/app/assets/images/emoji/musical_score.png diff --git a/app/assets/images/emoji/mute.png b/app/assets/images/emoji/mute.png Binary files differnew file mode 100644 index 00000000000..7c1788e5075 --- /dev/null +++ b/app/assets/images/emoji/mute.png diff --git a/app/assets/images/emoji/nail_care.png b/app/assets/images/emoji/nail_care.png Binary files differnew file mode 100644 index 00000000000..aa52af7050d --- /dev/null +++ b/app/assets/images/emoji/nail_care.png diff --git a/app/assets/images/emoji/nail_care_tone1.png b/app/assets/images/emoji/nail_care_tone1.png Binary files differnew file mode 100644 index 00000000000..26e883dd244 --- /dev/null +++ b/app/assets/images/emoji/nail_care_tone1.png diff --git a/app/assets/images/emoji/nail_care_tone2.png b/app/assets/images/emoji/nail_care_tone2.png Binary files differnew file mode 100644 index 00000000000..61257b47ea3 --- /dev/null +++ b/app/assets/images/emoji/nail_care_tone2.png diff --git a/app/assets/images/emoji/nail_care_tone3.png b/app/assets/images/emoji/nail_care_tone3.png Binary files differnew file mode 100644 index 00000000000..29871b05f62 --- /dev/null +++ b/app/assets/images/emoji/nail_care_tone3.png diff --git a/app/assets/images/emoji/nail_care_tone4.png b/app/assets/images/emoji/nail_care_tone4.png Binary files differnew file mode 100644 index 00000000000..2881de0b17d --- /dev/null +++ b/app/assets/images/emoji/nail_care_tone4.png diff --git a/app/assets/images/emoji/nail_care_tone5.png b/app/assets/images/emoji/nail_care_tone5.png Binary files differnew file mode 100644 index 00000000000..a0b7c0a45a6 --- /dev/null +++ b/app/assets/images/emoji/nail_care_tone5.png diff --git a/app/assets/images/emoji/name_badge.png b/app/assets/images/emoji/name_badge.png Binary files differnew file mode 100644 index 00000000000..ec5ee213e20 --- /dev/null +++ b/app/assets/images/emoji/name_badge.png diff --git a/app/assets/images/emoji/nauseated_face.png b/app/assets/images/emoji/nauseated_face.png Binary files differnew file mode 100644 index 00000000000..a566c109c28 --- /dev/null +++ b/app/assets/images/emoji/nauseated_face.png diff --git a/app/assets/images/emoji/necktie.png b/app/assets/images/emoji/necktie.png Binary files differnew file mode 100644 index 00000000000..1804e7f3ff3 --- /dev/null +++ b/app/assets/images/emoji/necktie.png diff --git a/app/assets/images/emoji/negative_squared_cross_mark.png b/app/assets/images/emoji/negative_squared_cross_mark.png Binary files differnew file mode 100644 index 00000000000..dae487f1f98 --- /dev/null +++ b/app/assets/images/emoji/negative_squared_cross_mark.png diff --git a/app/assets/images/emoji/nerd.png b/app/assets/images/emoji/nerd.png Binary files differnew file mode 100644 index 00000000000..7820bd581dc --- /dev/null +++ b/app/assets/images/emoji/nerd.png diff --git a/app/assets/images/emoji/neutral_face.png b/app/assets/images/emoji/neutral_face.png Binary files differnew file mode 100644 index 00000000000..065d193afe4 --- /dev/null +++ b/app/assets/images/emoji/neutral_face.png diff --git a/app/assets/images/emoji/new.png b/app/assets/images/emoji/new.png Binary files differnew file mode 100644 index 00000000000..b4f85488d1a --- /dev/null +++ b/app/assets/images/emoji/new.png diff --git a/app/assets/images/emoji/new_moon.png b/app/assets/images/emoji/new_moon.png Binary files differnew file mode 100644 index 00000000000..ecff72caa42 --- /dev/null +++ b/app/assets/images/emoji/new_moon.png diff --git a/app/assets/images/emoji/new_moon_with_face.png b/app/assets/images/emoji/new_moon_with_face.png Binary files differnew file mode 100644 index 00000000000..150dd12400c --- /dev/null +++ b/app/assets/images/emoji/new_moon_with_face.png diff --git a/app/assets/images/emoji/newspaper.png b/app/assets/images/emoji/newspaper.png Binary files differnew file mode 100644 index 00000000000..2aa8f060bde --- /dev/null +++ b/app/assets/images/emoji/newspaper.png diff --git a/app/assets/images/emoji/newspaper2.png b/app/assets/images/emoji/newspaper2.png Binary files differnew file mode 100644 index 00000000000..f64748df2b2 --- /dev/null +++ b/app/assets/images/emoji/newspaper2.png diff --git a/app/assets/images/emoji/ng.png b/app/assets/images/emoji/ng.png Binary files differnew file mode 100644 index 00000000000..ee8d20f5ebc --- /dev/null +++ b/app/assets/images/emoji/ng.png diff --git a/app/assets/images/emoji/night_with_stars.png b/app/assets/images/emoji/night_with_stars.png Binary files differnew file mode 100644 index 00000000000..ca2018f456d --- /dev/null +++ b/app/assets/images/emoji/night_with_stars.png diff --git a/app/assets/images/emoji/nine.png b/app/assets/images/emoji/nine.png Binary files differnew file mode 100644 index 00000000000..9fce3d1eca9 --- /dev/null +++ b/app/assets/images/emoji/nine.png diff --git a/app/assets/images/emoji/no_bell.png b/app/assets/images/emoji/no_bell.png Binary files differnew file mode 100644 index 00000000000..15cb38dd1e7 --- /dev/null +++ b/app/assets/images/emoji/no_bell.png diff --git a/app/assets/images/emoji/no_bicycles.png b/app/assets/images/emoji/no_bicycles.png Binary files differnew file mode 100644 index 00000000000..19c85421ce9 --- /dev/null +++ b/app/assets/images/emoji/no_bicycles.png diff --git a/app/assets/images/emoji/no_entry.png b/app/assets/images/emoji/no_entry.png Binary files differnew file mode 100644 index 00000000000..476800fc5c6 --- /dev/null +++ b/app/assets/images/emoji/no_entry.png diff --git a/app/assets/images/emoji/no_entry_sign.png b/app/assets/images/emoji/no_entry_sign.png Binary files differnew file mode 100644 index 00000000000..d2efd65e74b --- /dev/null +++ b/app/assets/images/emoji/no_entry_sign.png diff --git a/app/assets/images/emoji/no_good.png b/app/assets/images/emoji/no_good.png Binary files differnew file mode 100644 index 00000000000..ed577100322 --- /dev/null +++ b/app/assets/images/emoji/no_good.png diff --git a/app/assets/images/emoji/no_good_tone1.png b/app/assets/images/emoji/no_good_tone1.png Binary files differnew file mode 100644 index 00000000000..5c1a3cbb884 --- /dev/null +++ b/app/assets/images/emoji/no_good_tone1.png diff --git a/app/assets/images/emoji/no_good_tone2.png b/app/assets/images/emoji/no_good_tone2.png Binary files differnew file mode 100644 index 00000000000..80d8021f8fe --- /dev/null +++ b/app/assets/images/emoji/no_good_tone2.png diff --git a/app/assets/images/emoji/no_good_tone3.png b/app/assets/images/emoji/no_good_tone3.png Binary files differnew file mode 100644 index 00000000000..635e6a00815 --- /dev/null +++ b/app/assets/images/emoji/no_good_tone3.png diff --git a/app/assets/images/emoji/no_good_tone4.png b/app/assets/images/emoji/no_good_tone4.png Binary files differnew file mode 100644 index 00000000000..b96e412a374 --- /dev/null +++ b/app/assets/images/emoji/no_good_tone4.png diff --git a/app/assets/images/emoji/no_good_tone5.png b/app/assets/images/emoji/no_good_tone5.png Binary files differnew file mode 100644 index 00000000000..9a7084afa0a --- /dev/null +++ b/app/assets/images/emoji/no_good_tone5.png diff --git a/app/assets/images/emoji/no_mobile_phones.png b/app/assets/images/emoji/no_mobile_phones.png Binary files differnew file mode 100644 index 00000000000..7b1ae6ea579 --- /dev/null +++ b/app/assets/images/emoji/no_mobile_phones.png diff --git a/app/assets/images/emoji/no_mouth.png b/app/assets/images/emoji/no_mouth.png Binary files differnew file mode 100644 index 00000000000..b642f6c1172 --- /dev/null +++ b/app/assets/images/emoji/no_mouth.png diff --git a/app/assets/images/emoji/no_pedestrians.png b/app/assets/images/emoji/no_pedestrians.png Binary files differnew file mode 100644 index 00000000000..286aa577a23 --- /dev/null +++ b/app/assets/images/emoji/no_pedestrians.png diff --git a/app/assets/images/emoji/no_smoking.png b/app/assets/images/emoji/no_smoking.png Binary files differnew file mode 100644 index 00000000000..586b8d29d05 --- /dev/null +++ b/app/assets/images/emoji/no_smoking.png diff --git a/app/assets/images/emoji/non-potable_water.png b/app/assets/images/emoji/non-potable_water.png Binary files differnew file mode 100644 index 00000000000..827d4193f4e --- /dev/null +++ b/app/assets/images/emoji/non-potable_water.png diff --git a/app/assets/images/emoji/nose.png b/app/assets/images/emoji/nose.png Binary files differnew file mode 100644 index 00000000000..2f04ac5f98f --- /dev/null +++ b/app/assets/images/emoji/nose.png diff --git a/app/assets/images/emoji/nose_tone1.png b/app/assets/images/emoji/nose_tone1.png Binary files differnew file mode 100644 index 00000000000..8008d17506e --- /dev/null +++ b/app/assets/images/emoji/nose_tone1.png diff --git a/app/assets/images/emoji/nose_tone2.png b/app/assets/images/emoji/nose_tone2.png Binary files differnew file mode 100644 index 00000000000..ac17f26e827 --- /dev/null +++ b/app/assets/images/emoji/nose_tone2.png diff --git a/app/assets/images/emoji/nose_tone3.png b/app/assets/images/emoji/nose_tone3.png Binary files differnew file mode 100644 index 00000000000..d8b6cbe0f8e --- /dev/null +++ b/app/assets/images/emoji/nose_tone3.png diff --git a/app/assets/images/emoji/nose_tone4.png b/app/assets/images/emoji/nose_tone4.png Binary files differnew file mode 100644 index 00000000000..004b2631e2e --- /dev/null +++ b/app/assets/images/emoji/nose_tone4.png diff --git a/app/assets/images/emoji/nose_tone5.png b/app/assets/images/emoji/nose_tone5.png Binary files differnew file mode 100644 index 00000000000..7b33821f6c9 --- /dev/null +++ b/app/assets/images/emoji/nose_tone5.png diff --git a/app/assets/images/emoji/notebook.png b/app/assets/images/emoji/notebook.png Binary files differnew file mode 100644 index 00000000000..f6c28b4915d --- /dev/null +++ b/app/assets/images/emoji/notebook.png diff --git a/app/assets/images/emoji/notebook_with_decorative_cover.png b/app/assets/images/emoji/notebook_with_decorative_cover.png Binary files differnew file mode 100644 index 00000000000..03f566b6d2c --- /dev/null +++ b/app/assets/images/emoji/notebook_with_decorative_cover.png diff --git a/app/assets/images/emoji/notepad_spiral.png b/app/assets/images/emoji/notepad_spiral.png Binary files differnew file mode 100644 index 00000000000..85faa10d8ea --- /dev/null +++ b/app/assets/images/emoji/notepad_spiral.png diff --git a/app/assets/images/emoji/notes.png b/app/assets/images/emoji/notes.png Binary files differnew file mode 100644 index 00000000000..57d499aa181 --- /dev/null +++ b/app/assets/images/emoji/notes.png diff --git a/app/assets/images/emoji/nut_and_bolt.png b/app/assets/images/emoji/nut_and_bolt.png Binary files differnew file mode 100644 index 00000000000..4b9ae155319 --- /dev/null +++ b/app/assets/images/emoji/nut_and_bolt.png diff --git a/app/assets/images/emoji/o.png b/app/assets/images/emoji/o.png Binary files differnew file mode 100644 index 00000000000..3fe75ce4675 --- /dev/null +++ b/app/assets/images/emoji/o.png diff --git a/app/assets/images/emoji/o2.png b/app/assets/images/emoji/o2.png Binary files differnew file mode 100644 index 00000000000..73278ba194a --- /dev/null +++ b/app/assets/images/emoji/o2.png diff --git a/app/assets/images/emoji/ocean.png b/app/assets/images/emoji/ocean.png Binary files differnew file mode 100644 index 00000000000..45ff1e87703 --- /dev/null +++ b/app/assets/images/emoji/ocean.png diff --git a/app/assets/images/emoji/octagonal_sign.png b/app/assets/images/emoji/octagonal_sign.png Binary files differnew file mode 100644 index 00000000000..5ed61004045 --- /dev/null +++ b/app/assets/images/emoji/octagonal_sign.png diff --git a/app/assets/images/emoji/octopus.png b/app/assets/images/emoji/octopus.png Binary files differnew file mode 100644 index 00000000000..72c84074aac --- /dev/null +++ b/app/assets/images/emoji/octopus.png diff --git a/app/assets/images/emoji/oden.png b/app/assets/images/emoji/oden.png Binary files differnew file mode 100644 index 00000000000..d38a849fece --- /dev/null +++ b/app/assets/images/emoji/oden.png diff --git a/app/assets/images/emoji/office.png b/app/assets/images/emoji/office.png Binary files differnew file mode 100644 index 00000000000..7eee927d1b0 --- /dev/null +++ b/app/assets/images/emoji/office.png diff --git a/app/assets/images/emoji/oil.png b/app/assets/images/emoji/oil.png Binary files differnew file mode 100644 index 00000000000..c4c4d42da8b --- /dev/null +++ b/app/assets/images/emoji/oil.png diff --git a/app/assets/images/emoji/ok.png b/app/assets/images/emoji/ok.png Binary files differnew file mode 100644 index 00000000000..d0d775532ff --- /dev/null +++ b/app/assets/images/emoji/ok.png diff --git a/app/assets/images/emoji/ok_hand.png b/app/assets/images/emoji/ok_hand.png Binary files differnew file mode 100644 index 00000000000..028d69b0de3 --- /dev/null +++ b/app/assets/images/emoji/ok_hand.png diff --git a/app/assets/images/emoji/ok_hand_tone1.png b/app/assets/images/emoji/ok_hand_tone1.png Binary files differnew file mode 100644 index 00000000000..cecf7b2ab5a --- /dev/null +++ b/app/assets/images/emoji/ok_hand_tone1.png diff --git a/app/assets/images/emoji/ok_hand_tone2.png b/app/assets/images/emoji/ok_hand_tone2.png Binary files differnew file mode 100644 index 00000000000..c19239bcd3d --- /dev/null +++ b/app/assets/images/emoji/ok_hand_tone2.png diff --git a/app/assets/images/emoji/ok_hand_tone3.png b/app/assets/images/emoji/ok_hand_tone3.png Binary files differnew file mode 100644 index 00000000000..94b65b03ecd --- /dev/null +++ b/app/assets/images/emoji/ok_hand_tone3.png diff --git a/app/assets/images/emoji/ok_hand_tone4.png b/app/assets/images/emoji/ok_hand_tone4.png Binary files differnew file mode 100644 index 00000000000..03d26f08e6a --- /dev/null +++ b/app/assets/images/emoji/ok_hand_tone4.png diff --git a/app/assets/images/emoji/ok_hand_tone5.png b/app/assets/images/emoji/ok_hand_tone5.png Binary files differnew file mode 100644 index 00000000000..d4b24086364 --- /dev/null +++ b/app/assets/images/emoji/ok_hand_tone5.png diff --git a/app/assets/images/emoji/ok_woman.png b/app/assets/images/emoji/ok_woman.png Binary files differnew file mode 100644 index 00000000000..90a2c7469c4 --- /dev/null +++ b/app/assets/images/emoji/ok_woman.png diff --git a/app/assets/images/emoji/ok_woman_tone1.png b/app/assets/images/emoji/ok_woman_tone1.png Binary files differnew file mode 100644 index 00000000000..c99543e785b --- /dev/null +++ b/app/assets/images/emoji/ok_woman_tone1.png diff --git a/app/assets/images/emoji/ok_woman_tone2.png b/app/assets/images/emoji/ok_woman_tone2.png Binary files differnew file mode 100644 index 00000000000..ad5fae813db --- /dev/null +++ b/app/assets/images/emoji/ok_woman_tone2.png diff --git a/app/assets/images/emoji/ok_woman_tone3.png b/app/assets/images/emoji/ok_woman_tone3.png Binary files differnew file mode 100644 index 00000000000..51bf4fab406 --- /dev/null +++ b/app/assets/images/emoji/ok_woman_tone3.png diff --git a/app/assets/images/emoji/ok_woman_tone4.png b/app/assets/images/emoji/ok_woman_tone4.png Binary files differnew file mode 100644 index 00000000000..ee3f9dc640a --- /dev/null +++ b/app/assets/images/emoji/ok_woman_tone4.png diff --git a/app/assets/images/emoji/ok_woman_tone5.png b/app/assets/images/emoji/ok_woman_tone5.png Binary files differnew file mode 100644 index 00000000000..62a9d9237f7 --- /dev/null +++ b/app/assets/images/emoji/ok_woman_tone5.png diff --git a/app/assets/images/emoji/older_man.png b/app/assets/images/emoji/older_man.png Binary files differnew file mode 100644 index 00000000000..4ace4e6f308 --- /dev/null +++ b/app/assets/images/emoji/older_man.png diff --git a/app/assets/images/emoji/older_man_tone1.png b/app/assets/images/emoji/older_man_tone1.png Binary files differnew file mode 100644 index 00000000000..ab459baace8 --- /dev/null +++ b/app/assets/images/emoji/older_man_tone1.png diff --git a/app/assets/images/emoji/older_man_tone2.png b/app/assets/images/emoji/older_man_tone2.png Binary files differnew file mode 100644 index 00000000000..f4dfc7694ea --- /dev/null +++ b/app/assets/images/emoji/older_man_tone2.png diff --git a/app/assets/images/emoji/older_man_tone3.png b/app/assets/images/emoji/older_man_tone3.png Binary files differnew file mode 100644 index 00000000000..5ffd11792f4 --- /dev/null +++ b/app/assets/images/emoji/older_man_tone3.png diff --git a/app/assets/images/emoji/older_man_tone4.png b/app/assets/images/emoji/older_man_tone4.png Binary files differnew file mode 100644 index 00000000000..b350a764bfd --- /dev/null +++ b/app/assets/images/emoji/older_man_tone4.png diff --git a/app/assets/images/emoji/older_man_tone5.png b/app/assets/images/emoji/older_man_tone5.png Binary files differnew file mode 100644 index 00000000000..05fe24a1708 --- /dev/null +++ b/app/assets/images/emoji/older_man_tone5.png diff --git a/app/assets/images/emoji/older_woman.png b/app/assets/images/emoji/older_woman.png Binary files differnew file mode 100644 index 00000000000..52dc4987143 --- /dev/null +++ b/app/assets/images/emoji/older_woman.png diff --git a/app/assets/images/emoji/older_woman_tone1.png b/app/assets/images/emoji/older_woman_tone1.png Binary files differnew file mode 100644 index 00000000000..b49e821402c --- /dev/null +++ b/app/assets/images/emoji/older_woman_tone1.png diff --git a/app/assets/images/emoji/older_woman_tone2.png b/app/assets/images/emoji/older_woman_tone2.png Binary files differnew file mode 100644 index 00000000000..e86bf5ab3b7 --- /dev/null +++ b/app/assets/images/emoji/older_woman_tone2.png diff --git a/app/assets/images/emoji/older_woman_tone3.png b/app/assets/images/emoji/older_woman_tone3.png Binary files differnew file mode 100644 index 00000000000..83fc14b0874 --- /dev/null +++ b/app/assets/images/emoji/older_woman_tone3.png diff --git a/app/assets/images/emoji/older_woman_tone4.png b/app/assets/images/emoji/older_woman_tone4.png Binary files differnew file mode 100644 index 00000000000..e4aa8a424d4 --- /dev/null +++ b/app/assets/images/emoji/older_woman_tone4.png diff --git a/app/assets/images/emoji/older_woman_tone5.png b/app/assets/images/emoji/older_woman_tone5.png Binary files differnew file mode 100644 index 00000000000..4009012bb0a --- /dev/null +++ b/app/assets/images/emoji/older_woman_tone5.png diff --git a/app/assets/images/emoji/om_symbol.png b/app/assets/images/emoji/om_symbol.png Binary files differnew file mode 100644 index 00000000000..a35c63c459c --- /dev/null +++ b/app/assets/images/emoji/om_symbol.png diff --git a/app/assets/images/emoji/on.png b/app/assets/images/emoji/on.png Binary files differnew file mode 100644 index 00000000000..a0c371ae21e --- /dev/null +++ b/app/assets/images/emoji/on.png diff --git a/app/assets/images/emoji/oncoming_automobile.png b/app/assets/images/emoji/oncoming_automobile.png Binary files differnew file mode 100644 index 00000000000..3c7e1d52e63 --- /dev/null +++ b/app/assets/images/emoji/oncoming_automobile.png diff --git a/app/assets/images/emoji/oncoming_bus.png b/app/assets/images/emoji/oncoming_bus.png Binary files differnew file mode 100644 index 00000000000..ad91e256c7f --- /dev/null +++ b/app/assets/images/emoji/oncoming_bus.png diff --git a/app/assets/images/emoji/oncoming_police_car.png b/app/assets/images/emoji/oncoming_police_car.png Binary files differnew file mode 100644 index 00000000000..c9109c85b5d --- /dev/null +++ b/app/assets/images/emoji/oncoming_police_car.png diff --git a/app/assets/images/emoji/oncoming_taxi.png b/app/assets/images/emoji/oncoming_taxi.png Binary files differnew file mode 100644 index 00000000000..fea14e45846 --- /dev/null +++ b/app/assets/images/emoji/oncoming_taxi.png diff --git a/app/assets/images/emoji/one.png b/app/assets/images/emoji/one.png Binary files differnew file mode 100644 index 00000000000..e6d84b80128 --- /dev/null +++ b/app/assets/images/emoji/one.png diff --git a/app/assets/images/emoji/open_file_folder.png b/app/assets/images/emoji/open_file_folder.png Binary files differnew file mode 100644 index 00000000000..3993b09222f --- /dev/null +++ b/app/assets/images/emoji/open_file_folder.png diff --git a/app/assets/images/emoji/open_hands.png b/app/assets/images/emoji/open_hands.png Binary files differnew file mode 100644 index 00000000000..1cf75c9101e --- /dev/null +++ b/app/assets/images/emoji/open_hands.png diff --git a/app/assets/images/emoji/open_hands_tone1.png b/app/assets/images/emoji/open_hands_tone1.png Binary files differnew file mode 100644 index 00000000000..352d2614f11 --- /dev/null +++ b/app/assets/images/emoji/open_hands_tone1.png diff --git a/app/assets/images/emoji/open_hands_tone2.png b/app/assets/images/emoji/open_hands_tone2.png Binary files differnew file mode 100644 index 00000000000..70824a50c73 --- /dev/null +++ b/app/assets/images/emoji/open_hands_tone2.png diff --git a/app/assets/images/emoji/open_hands_tone3.png b/app/assets/images/emoji/open_hands_tone3.png Binary files differnew file mode 100644 index 00000000000..d7d136bd3db --- /dev/null +++ b/app/assets/images/emoji/open_hands_tone3.png diff --git a/app/assets/images/emoji/open_hands_tone4.png b/app/assets/images/emoji/open_hands_tone4.png Binary files differnew file mode 100644 index 00000000000..df4eaa711e7 --- /dev/null +++ b/app/assets/images/emoji/open_hands_tone4.png diff --git a/app/assets/images/emoji/open_hands_tone5.png b/app/assets/images/emoji/open_hands_tone5.png Binary files differnew file mode 100644 index 00000000000..7dc04eaebd8 --- /dev/null +++ b/app/assets/images/emoji/open_hands_tone5.png diff --git a/app/assets/images/emoji/open_mouth.png b/app/assets/images/emoji/open_mouth.png Binary files differnew file mode 100644 index 00000000000..a62cd27e148 --- /dev/null +++ b/app/assets/images/emoji/open_mouth.png diff --git a/app/assets/images/emoji/ophiuchus.png b/app/assets/images/emoji/ophiuchus.png Binary files differnew file mode 100644 index 00000000000..0a780a700da --- /dev/null +++ b/app/assets/images/emoji/ophiuchus.png diff --git a/app/assets/images/emoji/orange_book.png b/app/assets/images/emoji/orange_book.png Binary files differnew file mode 100644 index 00000000000..ab40e6ae6a2 --- /dev/null +++ b/app/assets/images/emoji/orange_book.png diff --git a/app/assets/images/emoji/orthodox_cross.png b/app/assets/images/emoji/orthodox_cross.png Binary files differnew file mode 100644 index 00000000000..0530e33a4d4 --- /dev/null +++ b/app/assets/images/emoji/orthodox_cross.png diff --git a/app/assets/images/emoji/outbox_tray.png b/app/assets/images/emoji/outbox_tray.png Binary files differnew file mode 100644 index 00000000000..46493ed5b2c --- /dev/null +++ b/app/assets/images/emoji/outbox_tray.png diff --git a/app/assets/images/emoji/owl.png b/app/assets/images/emoji/owl.png Binary files differnew file mode 100644 index 00000000000..fa6815480c3 --- /dev/null +++ b/app/assets/images/emoji/owl.png diff --git a/app/assets/images/emoji/ox.png b/app/assets/images/emoji/ox.png Binary files differnew file mode 100644 index 00000000000..badf5708f2f --- /dev/null +++ b/app/assets/images/emoji/ox.png diff --git a/app/assets/images/emoji/package.png b/app/assets/images/emoji/package.png Binary files differnew file mode 100644 index 00000000000..85431756ad8 --- /dev/null +++ b/app/assets/images/emoji/package.png diff --git a/app/assets/images/emoji/page_facing_up.png b/app/assets/images/emoji/page_facing_up.png Binary files differnew file mode 100644 index 00000000000..ba4ed757e01 --- /dev/null +++ b/app/assets/images/emoji/page_facing_up.png diff --git a/app/assets/images/emoji/page_with_curl.png b/app/assets/images/emoji/page_with_curl.png Binary files differnew file mode 100644 index 00000000000..06355319c74 --- /dev/null +++ b/app/assets/images/emoji/page_with_curl.png diff --git a/app/assets/images/emoji/pager.png b/app/assets/images/emoji/pager.png Binary files differnew file mode 100644 index 00000000000..b24b99306a2 --- /dev/null +++ b/app/assets/images/emoji/pager.png diff --git a/app/assets/images/emoji/paintbrush.png b/app/assets/images/emoji/paintbrush.png Binary files differnew file mode 100644 index 00000000000..28bffbaa3c9 --- /dev/null +++ b/app/assets/images/emoji/paintbrush.png diff --git a/app/assets/images/emoji/palm_tree.png b/app/assets/images/emoji/palm_tree.png Binary files differnew file mode 100644 index 00000000000..4bbb10f4f19 --- /dev/null +++ b/app/assets/images/emoji/palm_tree.png diff --git a/app/assets/images/emoji/pancakes.png b/app/assets/images/emoji/pancakes.png Binary files differnew file mode 100644 index 00000000000..6223d1a28e9 --- /dev/null +++ b/app/assets/images/emoji/pancakes.png diff --git a/app/assets/images/emoji/panda_face.png b/app/assets/images/emoji/panda_face.png Binary files differnew file mode 100644 index 00000000000..978382775ce --- /dev/null +++ b/app/assets/images/emoji/panda_face.png diff --git a/app/assets/images/emoji/paperclip.png b/app/assets/images/emoji/paperclip.png Binary files differnew file mode 100644 index 00000000000..8cd8d4f8750 --- /dev/null +++ b/app/assets/images/emoji/paperclip.png diff --git a/app/assets/images/emoji/paperclips.png b/app/assets/images/emoji/paperclips.png Binary files differnew file mode 100644 index 00000000000..76021e8c705 --- /dev/null +++ b/app/assets/images/emoji/paperclips.png diff --git a/app/assets/images/emoji/park.png b/app/assets/images/emoji/park.png Binary files differnew file mode 100644 index 00000000000..63ec7016301 --- /dev/null +++ b/app/assets/images/emoji/park.png diff --git a/app/assets/images/emoji/parking.png b/app/assets/images/emoji/parking.png Binary files differnew file mode 100644 index 00000000000..7be7dac27e8 --- /dev/null +++ b/app/assets/images/emoji/parking.png diff --git a/app/assets/images/emoji/part_alternation_mark.png b/app/assets/images/emoji/part_alternation_mark.png Binary files differnew file mode 100644 index 00000000000..70453d41528 --- /dev/null +++ b/app/assets/images/emoji/part_alternation_mark.png diff --git a/app/assets/images/emoji/partly_sunny.png b/app/assets/images/emoji/partly_sunny.png Binary files differnew file mode 100644 index 00000000000..a55e59c344c --- /dev/null +++ b/app/assets/images/emoji/partly_sunny.png diff --git a/app/assets/images/emoji/passport_control.png b/app/assets/images/emoji/passport_control.png Binary files differnew file mode 100644 index 00000000000..079e34ee4d4 --- /dev/null +++ b/app/assets/images/emoji/passport_control.png diff --git a/app/assets/images/emoji/pause_button.png b/app/assets/images/emoji/pause_button.png Binary files differnew file mode 100644 index 00000000000..4f07e7ebfd7 --- /dev/null +++ b/app/assets/images/emoji/pause_button.png diff --git a/app/assets/images/emoji/peace.png b/app/assets/images/emoji/peace.png Binary files differnew file mode 100644 index 00000000000..86033faf477 --- /dev/null +++ b/app/assets/images/emoji/peace.png diff --git a/app/assets/images/emoji/peach.png b/app/assets/images/emoji/peach.png Binary files differnew file mode 100644 index 00000000000..9ab57cbb758 --- /dev/null +++ b/app/assets/images/emoji/peach.png diff --git a/app/assets/images/emoji/peanuts.png b/app/assets/images/emoji/peanuts.png Binary files differnew file mode 100644 index 00000000000..b64fadad010 --- /dev/null +++ b/app/assets/images/emoji/peanuts.png diff --git a/app/assets/images/emoji/pear.png b/app/assets/images/emoji/pear.png Binary files differnew file mode 100644 index 00000000000..3869f718bcf --- /dev/null +++ b/app/assets/images/emoji/pear.png diff --git a/app/assets/images/emoji/pen_ballpoint.png b/app/assets/images/emoji/pen_ballpoint.png Binary files differnew file mode 100644 index 00000000000..6ef7a342433 --- /dev/null +++ b/app/assets/images/emoji/pen_ballpoint.png diff --git a/app/assets/images/emoji/pen_fountain.png b/app/assets/images/emoji/pen_fountain.png Binary files differnew file mode 100644 index 00000000000..3ca4bd2c231 --- /dev/null +++ b/app/assets/images/emoji/pen_fountain.png diff --git a/app/assets/images/emoji/pencil.png b/app/assets/images/emoji/pencil.png Binary files differnew file mode 100644 index 00000000000..edc6155e168 --- /dev/null +++ b/app/assets/images/emoji/pencil.png diff --git a/app/assets/images/emoji/pencil2.png b/app/assets/images/emoji/pencil2.png Binary files differnew file mode 100644 index 00000000000..3833d590fa2 --- /dev/null +++ b/app/assets/images/emoji/pencil2.png diff --git a/app/assets/images/emoji/penguin.png b/app/assets/images/emoji/penguin.png Binary files differnew file mode 100644 index 00000000000..c0064fb9734 --- /dev/null +++ b/app/assets/images/emoji/penguin.png diff --git a/app/assets/images/emoji/pensive.png b/app/assets/images/emoji/pensive.png Binary files differnew file mode 100644 index 00000000000..490fb566954 --- /dev/null +++ b/app/assets/images/emoji/pensive.png diff --git a/app/assets/images/emoji/performing_arts.png b/app/assets/images/emoji/performing_arts.png Binary files differnew file mode 100644 index 00000000000..685441fdaa1 --- /dev/null +++ b/app/assets/images/emoji/performing_arts.png diff --git a/app/assets/images/emoji/persevere.png b/app/assets/images/emoji/persevere.png Binary files differnew file mode 100644 index 00000000000..646a05fe908 --- /dev/null +++ b/app/assets/images/emoji/persevere.png diff --git a/app/assets/images/emoji/person_frowning.png b/app/assets/images/emoji/person_frowning.png Binary files differnew file mode 100644 index 00000000000..579324959a1 --- /dev/null +++ b/app/assets/images/emoji/person_frowning.png diff --git a/app/assets/images/emoji/person_frowning_tone1.png b/app/assets/images/emoji/person_frowning_tone1.png Binary files differnew file mode 100644 index 00000000000..21d3bb43923 --- /dev/null +++ b/app/assets/images/emoji/person_frowning_tone1.png diff --git a/app/assets/images/emoji/person_frowning_tone2.png b/app/assets/images/emoji/person_frowning_tone2.png Binary files differnew file mode 100644 index 00000000000..973f5fc8382 --- /dev/null +++ b/app/assets/images/emoji/person_frowning_tone2.png diff --git a/app/assets/images/emoji/person_frowning_tone3.png b/app/assets/images/emoji/person_frowning_tone3.png Binary files differnew file mode 100644 index 00000000000..41fbcc78816 --- /dev/null +++ b/app/assets/images/emoji/person_frowning_tone3.png diff --git a/app/assets/images/emoji/person_frowning_tone4.png b/app/assets/images/emoji/person_frowning_tone4.png Binary files differnew file mode 100644 index 00000000000..5a37c741030 --- /dev/null +++ b/app/assets/images/emoji/person_frowning_tone4.png diff --git a/app/assets/images/emoji/person_frowning_tone5.png b/app/assets/images/emoji/person_frowning_tone5.png Binary files differnew file mode 100644 index 00000000000..e08141f3efe --- /dev/null +++ b/app/assets/images/emoji/person_frowning_tone5.png diff --git a/app/assets/images/emoji/person_with_blond_hair.png b/app/assets/images/emoji/person_with_blond_hair.png Binary files differnew file mode 100644 index 00000000000..ad6f01a7dda --- /dev/null +++ b/app/assets/images/emoji/person_with_blond_hair.png diff --git a/app/assets/images/emoji/person_with_blond_hair_tone1.png b/app/assets/images/emoji/person_with_blond_hair_tone1.png Binary files differnew file mode 100644 index 00000000000..7d18ef24445 --- /dev/null +++ b/app/assets/images/emoji/person_with_blond_hair_tone1.png diff --git a/app/assets/images/emoji/person_with_blond_hair_tone2.png b/app/assets/images/emoji/person_with_blond_hair_tone2.png Binary files differnew file mode 100644 index 00000000000..dae1307315c --- /dev/null +++ b/app/assets/images/emoji/person_with_blond_hair_tone2.png diff --git a/app/assets/images/emoji/person_with_blond_hair_tone3.png b/app/assets/images/emoji/person_with_blond_hair_tone3.png Binary files differnew file mode 100644 index 00000000000..684677e8e5a --- /dev/null +++ b/app/assets/images/emoji/person_with_blond_hair_tone3.png diff --git a/app/assets/images/emoji/person_with_blond_hair_tone4.png b/app/assets/images/emoji/person_with_blond_hair_tone4.png Binary files differnew file mode 100644 index 00000000000..012be0b51f8 --- /dev/null +++ b/app/assets/images/emoji/person_with_blond_hair_tone4.png diff --git a/app/assets/images/emoji/person_with_blond_hair_tone5.png b/app/assets/images/emoji/person_with_blond_hair_tone5.png Binary files differnew file mode 100644 index 00000000000..d4ecc4cf44b --- /dev/null +++ b/app/assets/images/emoji/person_with_blond_hair_tone5.png diff --git a/app/assets/images/emoji/person_with_pouting_face.png b/app/assets/images/emoji/person_with_pouting_face.png Binary files differnew file mode 100644 index 00000000000..10eb0571078 --- /dev/null +++ b/app/assets/images/emoji/person_with_pouting_face.png diff --git a/app/assets/images/emoji/person_with_pouting_face_tone1.png b/app/assets/images/emoji/person_with_pouting_face_tone1.png Binary files differnew file mode 100644 index 00000000000..57e826b75a4 --- /dev/null +++ b/app/assets/images/emoji/person_with_pouting_face_tone1.png diff --git a/app/assets/images/emoji/person_with_pouting_face_tone2.png b/app/assets/images/emoji/person_with_pouting_face_tone2.png Binary files differnew file mode 100644 index 00000000000..3f317c0c25f --- /dev/null +++ b/app/assets/images/emoji/person_with_pouting_face_tone2.png diff --git a/app/assets/images/emoji/person_with_pouting_face_tone3.png b/app/assets/images/emoji/person_with_pouting_face_tone3.png Binary files differnew file mode 100644 index 00000000000..d2fbb6c20bf --- /dev/null +++ b/app/assets/images/emoji/person_with_pouting_face_tone3.png diff --git a/app/assets/images/emoji/person_with_pouting_face_tone4.png b/app/assets/images/emoji/person_with_pouting_face_tone4.png Binary files differnew file mode 100644 index 00000000000..643ceb4a5c5 --- /dev/null +++ b/app/assets/images/emoji/person_with_pouting_face_tone4.png diff --git a/app/assets/images/emoji/person_with_pouting_face_tone5.png b/app/assets/images/emoji/person_with_pouting_face_tone5.png Binary files differnew file mode 100644 index 00000000000..b2eb6859c32 --- /dev/null +++ b/app/assets/images/emoji/person_with_pouting_face_tone5.png diff --git a/app/assets/images/emoji/pick.png b/app/assets/images/emoji/pick.png Binary files differnew file mode 100644 index 00000000000..6370fe6d791 --- /dev/null +++ b/app/assets/images/emoji/pick.png diff --git a/app/assets/images/emoji/pig.png b/app/assets/images/emoji/pig.png Binary files differnew file mode 100644 index 00000000000..afe05ca1676 --- /dev/null +++ b/app/assets/images/emoji/pig.png diff --git a/app/assets/images/emoji/pig2.png b/app/assets/images/emoji/pig2.png Binary files differnew file mode 100644 index 00000000000..5f31c1a2d75 --- /dev/null +++ b/app/assets/images/emoji/pig2.png diff --git a/app/assets/images/emoji/pig_nose.png b/app/assets/images/emoji/pig_nose.png Binary files differnew file mode 100644 index 00000000000..3610ae4a910 --- /dev/null +++ b/app/assets/images/emoji/pig_nose.png diff --git a/app/assets/images/emoji/pill.png b/app/assets/images/emoji/pill.png Binary files differnew file mode 100644 index 00000000000..1d4530e77a3 --- /dev/null +++ b/app/assets/images/emoji/pill.png diff --git a/app/assets/images/emoji/pineapple.png b/app/assets/images/emoji/pineapple.png Binary files differnew file mode 100644 index 00000000000..c89a1606462 --- /dev/null +++ b/app/assets/images/emoji/pineapple.png diff --git a/app/assets/images/emoji/ping_pong.png b/app/assets/images/emoji/ping_pong.png Binary files differnew file mode 100644 index 00000000000..ff3c51727d1 --- /dev/null +++ b/app/assets/images/emoji/ping_pong.png diff --git a/app/assets/images/emoji/pisces.png b/app/assets/images/emoji/pisces.png Binary files differnew file mode 100644 index 00000000000..7f6f646a95c --- /dev/null +++ b/app/assets/images/emoji/pisces.png diff --git a/app/assets/images/emoji/pizza.png b/app/assets/images/emoji/pizza.png Binary files differnew file mode 100644 index 00000000000..e07365cb398 --- /dev/null +++ b/app/assets/images/emoji/pizza.png diff --git a/app/assets/images/emoji/place_of_worship.png b/app/assets/images/emoji/place_of_worship.png Binary files differnew file mode 100644 index 00000000000..207d59cce85 --- /dev/null +++ b/app/assets/images/emoji/place_of_worship.png diff --git a/app/assets/images/emoji/play_pause.png b/app/assets/images/emoji/play_pause.png Binary files differnew file mode 100644 index 00000000000..a9f857139ac --- /dev/null +++ b/app/assets/images/emoji/play_pause.png diff --git a/app/assets/images/emoji/point_down.png b/app/assets/images/emoji/point_down.png Binary files differnew file mode 100644 index 00000000000..00d3d13ab5c --- /dev/null +++ b/app/assets/images/emoji/point_down.png diff --git a/app/assets/images/emoji/point_down_tone1.png b/app/assets/images/emoji/point_down_tone1.png Binary files differnew file mode 100644 index 00000000000..140f157d8c7 --- /dev/null +++ b/app/assets/images/emoji/point_down_tone1.png diff --git a/app/assets/images/emoji/point_down_tone2.png b/app/assets/images/emoji/point_down_tone2.png Binary files differnew file mode 100644 index 00000000000..d518544f7fa --- /dev/null +++ b/app/assets/images/emoji/point_down_tone2.png diff --git a/app/assets/images/emoji/point_down_tone3.png b/app/assets/images/emoji/point_down_tone3.png Binary files differnew file mode 100644 index 00000000000..018b688b8b7 --- /dev/null +++ b/app/assets/images/emoji/point_down_tone3.png diff --git a/app/assets/images/emoji/point_down_tone4.png b/app/assets/images/emoji/point_down_tone4.png Binary files differnew file mode 100644 index 00000000000..98845bf6f72 --- /dev/null +++ b/app/assets/images/emoji/point_down_tone4.png diff --git a/app/assets/images/emoji/point_down_tone5.png b/app/assets/images/emoji/point_down_tone5.png Binary files differnew file mode 100644 index 00000000000..9a9b039a9fc --- /dev/null +++ b/app/assets/images/emoji/point_down_tone5.png diff --git a/app/assets/images/emoji/point_left.png b/app/assets/images/emoji/point_left.png Binary files differnew file mode 100644 index 00000000000..599fa2e3cf1 --- /dev/null +++ b/app/assets/images/emoji/point_left.png diff --git a/app/assets/images/emoji/point_left_tone1.png b/app/assets/images/emoji/point_left_tone1.png Binary files differnew file mode 100644 index 00000000000..88e2c306076 --- /dev/null +++ b/app/assets/images/emoji/point_left_tone1.png diff --git a/app/assets/images/emoji/point_left_tone2.png b/app/assets/images/emoji/point_left_tone2.png Binary files differnew file mode 100644 index 00000000000..d3c89d87c5f --- /dev/null +++ b/app/assets/images/emoji/point_left_tone2.png diff --git a/app/assets/images/emoji/point_left_tone3.png b/app/assets/images/emoji/point_left_tone3.png Binary files differnew file mode 100644 index 00000000000..b23b9167358 --- /dev/null +++ b/app/assets/images/emoji/point_left_tone3.png diff --git a/app/assets/images/emoji/point_left_tone4.png b/app/assets/images/emoji/point_left_tone4.png Binary files differnew file mode 100644 index 00000000000..3093f325c27 --- /dev/null +++ b/app/assets/images/emoji/point_left_tone4.png diff --git a/app/assets/images/emoji/point_left_tone5.png b/app/assets/images/emoji/point_left_tone5.png Binary files differnew file mode 100644 index 00000000000..2b4cbfa120c --- /dev/null +++ b/app/assets/images/emoji/point_left_tone5.png diff --git a/app/assets/images/emoji/point_right.png b/app/assets/images/emoji/point_right.png Binary files differnew file mode 100644 index 00000000000..93a3cd34aa5 --- /dev/null +++ b/app/assets/images/emoji/point_right.png diff --git a/app/assets/images/emoji/point_right_tone1.png b/app/assets/images/emoji/point_right_tone1.png Binary files differnew file mode 100644 index 00000000000..4a28c6bbc89 --- /dev/null +++ b/app/assets/images/emoji/point_right_tone1.png diff --git a/app/assets/images/emoji/point_right_tone2.png b/app/assets/images/emoji/point_right_tone2.png Binary files differnew file mode 100644 index 00000000000..7cb13231733 --- /dev/null +++ b/app/assets/images/emoji/point_right_tone2.png diff --git a/app/assets/images/emoji/point_right_tone3.png b/app/assets/images/emoji/point_right_tone3.png Binary files differnew file mode 100644 index 00000000000..5514807d71a --- /dev/null +++ b/app/assets/images/emoji/point_right_tone3.png diff --git a/app/assets/images/emoji/point_right_tone4.png b/app/assets/images/emoji/point_right_tone4.png Binary files differnew file mode 100644 index 00000000000..b8541d6440d --- /dev/null +++ b/app/assets/images/emoji/point_right_tone4.png diff --git a/app/assets/images/emoji/point_right_tone5.png b/app/assets/images/emoji/point_right_tone5.png Binary files differnew file mode 100644 index 00000000000..1b7aab07bb1 --- /dev/null +++ b/app/assets/images/emoji/point_right_tone5.png diff --git a/app/assets/images/emoji/point_up.png b/app/assets/images/emoji/point_up.png Binary files differnew file mode 100644 index 00000000000..f4978ff0f00 --- /dev/null +++ b/app/assets/images/emoji/point_up.png diff --git a/app/assets/images/emoji/point_up_2.png b/app/assets/images/emoji/point_up_2.png Binary files differnew file mode 100644 index 00000000000..bc496dfeae4 --- /dev/null +++ b/app/assets/images/emoji/point_up_2.png diff --git a/app/assets/images/emoji/point_up_2_tone1.png b/app/assets/images/emoji/point_up_2_tone1.png Binary files differnew file mode 100644 index 00000000000..a12a7e78430 --- /dev/null +++ b/app/assets/images/emoji/point_up_2_tone1.png diff --git a/app/assets/images/emoji/point_up_2_tone2.png b/app/assets/images/emoji/point_up_2_tone2.png Binary files differnew file mode 100644 index 00000000000..cdff40ceab0 --- /dev/null +++ b/app/assets/images/emoji/point_up_2_tone2.png diff --git a/app/assets/images/emoji/point_up_2_tone3.png b/app/assets/images/emoji/point_up_2_tone3.png Binary files differnew file mode 100644 index 00000000000..a07ce9e5ae8 --- /dev/null +++ b/app/assets/images/emoji/point_up_2_tone3.png diff --git a/app/assets/images/emoji/point_up_2_tone4.png b/app/assets/images/emoji/point_up_2_tone4.png Binary files differnew file mode 100644 index 00000000000..4f86c88ba42 --- /dev/null +++ b/app/assets/images/emoji/point_up_2_tone4.png diff --git a/app/assets/images/emoji/point_up_2_tone5.png b/app/assets/images/emoji/point_up_2_tone5.png Binary files differnew file mode 100644 index 00000000000..ed1b26c35d3 --- /dev/null +++ b/app/assets/images/emoji/point_up_2_tone5.png diff --git a/app/assets/images/emoji/point_up_tone1.png b/app/assets/images/emoji/point_up_tone1.png Binary files differnew file mode 100644 index 00000000000..6a9db21d64c --- /dev/null +++ b/app/assets/images/emoji/point_up_tone1.png diff --git a/app/assets/images/emoji/point_up_tone2.png b/app/assets/images/emoji/point_up_tone2.png Binary files differnew file mode 100644 index 00000000000..15aa9ea0e05 --- /dev/null +++ b/app/assets/images/emoji/point_up_tone2.png diff --git a/app/assets/images/emoji/point_up_tone3.png b/app/assets/images/emoji/point_up_tone3.png Binary files differnew file mode 100644 index 00000000000..652b73a9c5d --- /dev/null +++ b/app/assets/images/emoji/point_up_tone3.png diff --git a/app/assets/images/emoji/point_up_tone4.png b/app/assets/images/emoji/point_up_tone4.png Binary files differnew file mode 100644 index 00000000000..692bad926e9 --- /dev/null +++ b/app/assets/images/emoji/point_up_tone4.png diff --git a/app/assets/images/emoji/point_up_tone5.png b/app/assets/images/emoji/point_up_tone5.png Binary files differnew file mode 100644 index 00000000000..1e1b10fb71c --- /dev/null +++ b/app/assets/images/emoji/point_up_tone5.png diff --git a/app/assets/images/emoji/police_car.png b/app/assets/images/emoji/police_car.png Binary files differnew file mode 100644 index 00000000000..3da4253de7e --- /dev/null +++ b/app/assets/images/emoji/police_car.png diff --git a/app/assets/images/emoji/poodle.png b/app/assets/images/emoji/poodle.png Binary files differnew file mode 100644 index 00000000000..8ec39e396af --- /dev/null +++ b/app/assets/images/emoji/poodle.png diff --git a/app/assets/images/emoji/poop.png b/app/assets/images/emoji/poop.png Binary files differnew file mode 100644 index 00000000000..10b15e72d56 --- /dev/null +++ b/app/assets/images/emoji/poop.png diff --git a/app/assets/images/emoji/popcorn.png b/app/assets/images/emoji/popcorn.png Binary files differnew file mode 100644 index 00000000000..36853e381d4 --- /dev/null +++ b/app/assets/images/emoji/popcorn.png diff --git a/app/assets/images/emoji/post_office.png b/app/assets/images/emoji/post_office.png Binary files differnew file mode 100644 index 00000000000..a23848f9aa0 --- /dev/null +++ b/app/assets/images/emoji/post_office.png diff --git a/app/assets/images/emoji/postal_horn.png b/app/assets/images/emoji/postal_horn.png Binary files differnew file mode 100644 index 00000000000..c173b8dbd67 --- /dev/null +++ b/app/assets/images/emoji/postal_horn.png diff --git a/app/assets/images/emoji/postbox.png b/app/assets/images/emoji/postbox.png Binary files differnew file mode 100644 index 00000000000..07c9c4ab3d6 --- /dev/null +++ b/app/assets/images/emoji/postbox.png diff --git a/app/assets/images/emoji/potable_water.png b/app/assets/images/emoji/potable_water.png Binary files differnew file mode 100644 index 00000000000..2c610049459 --- /dev/null +++ b/app/assets/images/emoji/potable_water.png diff --git a/app/assets/images/emoji/potato.png b/app/assets/images/emoji/potato.png Binary files differnew file mode 100644 index 00000000000..70350ca2c0a --- /dev/null +++ b/app/assets/images/emoji/potato.png diff --git a/app/assets/images/emoji/pouch.png b/app/assets/images/emoji/pouch.png Binary files differnew file mode 100644 index 00000000000..8795c6c66ff --- /dev/null +++ b/app/assets/images/emoji/pouch.png diff --git a/app/assets/images/emoji/poultry_leg.png b/app/assets/images/emoji/poultry_leg.png Binary files differnew file mode 100644 index 00000000000..eea4a53a2f9 --- /dev/null +++ b/app/assets/images/emoji/poultry_leg.png diff --git a/app/assets/images/emoji/pound.png b/app/assets/images/emoji/pound.png Binary files differnew file mode 100644 index 00000000000..a0d4c4099e9 --- /dev/null +++ b/app/assets/images/emoji/pound.png diff --git a/app/assets/images/emoji/pouting_cat.png b/app/assets/images/emoji/pouting_cat.png Binary files differnew file mode 100644 index 00000000000..41ddfeab42b --- /dev/null +++ b/app/assets/images/emoji/pouting_cat.png diff --git a/app/assets/images/emoji/pray.png b/app/assets/images/emoji/pray.png Binary files differnew file mode 100644 index 00000000000..8347f2435be --- /dev/null +++ b/app/assets/images/emoji/pray.png diff --git a/app/assets/images/emoji/pray_tone1.png b/app/assets/images/emoji/pray_tone1.png Binary files differnew file mode 100644 index 00000000000..060ef257172 --- /dev/null +++ b/app/assets/images/emoji/pray_tone1.png diff --git a/app/assets/images/emoji/pray_tone2.png b/app/assets/images/emoji/pray_tone2.png Binary files differnew file mode 100644 index 00000000000..56dc607c07a --- /dev/null +++ b/app/assets/images/emoji/pray_tone2.png diff --git a/app/assets/images/emoji/pray_tone3.png b/app/assets/images/emoji/pray_tone3.png Binary files differnew file mode 100644 index 00000000000..0f33b862008 --- /dev/null +++ b/app/assets/images/emoji/pray_tone3.png diff --git a/app/assets/images/emoji/pray_tone4.png b/app/assets/images/emoji/pray_tone4.png Binary files differnew file mode 100644 index 00000000000..2ea8dc11657 --- /dev/null +++ b/app/assets/images/emoji/pray_tone4.png diff --git a/app/assets/images/emoji/pray_tone5.png b/app/assets/images/emoji/pray_tone5.png Binary files differnew file mode 100644 index 00000000000..2128a6c4703 --- /dev/null +++ b/app/assets/images/emoji/pray_tone5.png diff --git a/app/assets/images/emoji/prayer_beads.png b/app/assets/images/emoji/prayer_beads.png Binary files differnew file mode 100644 index 00000000000..a4b6dfcc62e --- /dev/null +++ b/app/assets/images/emoji/prayer_beads.png diff --git a/app/assets/images/emoji/pregnant_woman.png b/app/assets/images/emoji/pregnant_woman.png Binary files differnew file mode 100644 index 00000000000..084e83a414a --- /dev/null +++ b/app/assets/images/emoji/pregnant_woman.png diff --git a/app/assets/images/emoji/pregnant_woman_tone1.png b/app/assets/images/emoji/pregnant_woman_tone1.png Binary files differnew file mode 100644 index 00000000000..a78703b33aa --- /dev/null +++ b/app/assets/images/emoji/pregnant_woman_tone1.png diff --git a/app/assets/images/emoji/pregnant_woman_tone2.png b/app/assets/images/emoji/pregnant_woman_tone2.png Binary files differnew file mode 100644 index 00000000000..0068c6c4a77 --- /dev/null +++ b/app/assets/images/emoji/pregnant_woman_tone2.png diff --git a/app/assets/images/emoji/pregnant_woman_tone3.png b/app/assets/images/emoji/pregnant_woman_tone3.png Binary files differnew file mode 100644 index 00000000000..3206296b684 --- /dev/null +++ b/app/assets/images/emoji/pregnant_woman_tone3.png diff --git a/app/assets/images/emoji/pregnant_woman_tone4.png b/app/assets/images/emoji/pregnant_woman_tone4.png Binary files differnew file mode 100644 index 00000000000..120fda5cd8c --- /dev/null +++ b/app/assets/images/emoji/pregnant_woman_tone4.png diff --git a/app/assets/images/emoji/pregnant_woman_tone5.png b/app/assets/images/emoji/pregnant_woman_tone5.png Binary files differnew file mode 100644 index 00000000000..569bfdf05ce --- /dev/null +++ b/app/assets/images/emoji/pregnant_woman_tone5.png diff --git a/app/assets/images/emoji/prince.png b/app/assets/images/emoji/prince.png Binary files differnew file mode 100644 index 00000000000..38d69344c84 --- /dev/null +++ b/app/assets/images/emoji/prince.png diff --git a/app/assets/images/emoji/prince_tone1.png b/app/assets/images/emoji/prince_tone1.png Binary files differnew file mode 100644 index 00000000000..849930c8887 --- /dev/null +++ b/app/assets/images/emoji/prince_tone1.png diff --git a/app/assets/images/emoji/prince_tone2.png b/app/assets/images/emoji/prince_tone2.png Binary files differnew file mode 100644 index 00000000000..23d8b3b1285 --- /dev/null +++ b/app/assets/images/emoji/prince_tone2.png diff --git a/app/assets/images/emoji/prince_tone3.png b/app/assets/images/emoji/prince_tone3.png Binary files differnew file mode 100644 index 00000000000..db6dfff0647 --- /dev/null +++ b/app/assets/images/emoji/prince_tone3.png diff --git a/app/assets/images/emoji/prince_tone4.png b/app/assets/images/emoji/prince_tone4.png Binary files differnew file mode 100644 index 00000000000..8e10f8be6a8 --- /dev/null +++ b/app/assets/images/emoji/prince_tone4.png diff --git a/app/assets/images/emoji/prince_tone5.png b/app/assets/images/emoji/prince_tone5.png Binary files differnew file mode 100644 index 00000000000..138d4ea7048 --- /dev/null +++ b/app/assets/images/emoji/prince_tone5.png diff --git a/app/assets/images/emoji/princess.png b/app/assets/images/emoji/princess.png Binary files differnew file mode 100644 index 00000000000..879e9fa8c5d --- /dev/null +++ b/app/assets/images/emoji/princess.png diff --git a/app/assets/images/emoji/princess_tone1.png b/app/assets/images/emoji/princess_tone1.png Binary files differnew file mode 100644 index 00000000000..c28078cdc36 --- /dev/null +++ b/app/assets/images/emoji/princess_tone1.png diff --git a/app/assets/images/emoji/princess_tone2.png b/app/assets/images/emoji/princess_tone2.png Binary files differnew file mode 100644 index 00000000000..dcd20e6ecd4 --- /dev/null +++ b/app/assets/images/emoji/princess_tone2.png diff --git a/app/assets/images/emoji/princess_tone3.png b/app/assets/images/emoji/princess_tone3.png Binary files differnew file mode 100644 index 00000000000..cde6f315c56 --- /dev/null +++ b/app/assets/images/emoji/princess_tone3.png diff --git a/app/assets/images/emoji/princess_tone4.png b/app/assets/images/emoji/princess_tone4.png Binary files differnew file mode 100644 index 00000000000..c71e69caaef --- /dev/null +++ b/app/assets/images/emoji/princess_tone4.png diff --git a/app/assets/images/emoji/princess_tone5.png b/app/assets/images/emoji/princess_tone5.png Binary files differnew file mode 100644 index 00000000000..063e2645910 --- /dev/null +++ b/app/assets/images/emoji/princess_tone5.png diff --git a/app/assets/images/emoji/printer.png b/app/assets/images/emoji/printer.png Binary files differnew file mode 100644 index 00000000000..027c830f0fe --- /dev/null +++ b/app/assets/images/emoji/printer.png diff --git a/app/assets/images/emoji/projector.png b/app/assets/images/emoji/projector.png Binary files differnew file mode 100644 index 00000000000..ce9ab0daa28 --- /dev/null +++ b/app/assets/images/emoji/projector.png diff --git a/app/assets/images/emoji/punch.png b/app/assets/images/emoji/punch.png Binary files differnew file mode 100644 index 00000000000..b14ca5f5211 --- /dev/null +++ b/app/assets/images/emoji/punch.png diff --git a/app/assets/images/emoji/punch_tone1.png b/app/assets/images/emoji/punch_tone1.png Binary files differnew file mode 100644 index 00000000000..93c7d17fb47 --- /dev/null +++ b/app/assets/images/emoji/punch_tone1.png diff --git a/app/assets/images/emoji/punch_tone2.png b/app/assets/images/emoji/punch_tone2.png Binary files differnew file mode 100644 index 00000000000..c0a1af6e10a --- /dev/null +++ b/app/assets/images/emoji/punch_tone2.png diff --git a/app/assets/images/emoji/punch_tone3.png b/app/assets/images/emoji/punch_tone3.png Binary files differnew file mode 100644 index 00000000000..1458b021201 --- /dev/null +++ b/app/assets/images/emoji/punch_tone3.png diff --git a/app/assets/images/emoji/punch_tone4.png b/app/assets/images/emoji/punch_tone4.png Binary files differnew file mode 100644 index 00000000000..c1466bfcdef --- /dev/null +++ b/app/assets/images/emoji/punch_tone4.png diff --git a/app/assets/images/emoji/punch_tone5.png b/app/assets/images/emoji/punch_tone5.png Binary files differnew file mode 100644 index 00000000000..00b4ddb8953 --- /dev/null +++ b/app/assets/images/emoji/punch_tone5.png diff --git a/app/assets/images/emoji/purple_heart.png b/app/assets/images/emoji/purple_heart.png Binary files differnew file mode 100644 index 00000000000..95c53a9ade6 --- /dev/null +++ b/app/assets/images/emoji/purple_heart.png diff --git a/app/assets/images/emoji/purse.png b/app/assets/images/emoji/purse.png Binary files differnew file mode 100644 index 00000000000..981346193c5 --- /dev/null +++ b/app/assets/images/emoji/purse.png diff --git a/app/assets/images/emoji/pushpin.png b/app/assets/images/emoji/pushpin.png Binary files differnew file mode 100644 index 00000000000..57e07d7f4cc --- /dev/null +++ b/app/assets/images/emoji/pushpin.png diff --git a/app/assets/images/emoji/put_litter_in_its_place.png b/app/assets/images/emoji/put_litter_in_its_place.png Binary files differnew file mode 100644 index 00000000000..82a84f9a375 --- /dev/null +++ b/app/assets/images/emoji/put_litter_in_its_place.png diff --git a/app/assets/images/emoji/question.png b/app/assets/images/emoji/question.png Binary files differnew file mode 100644 index 00000000000..5a58f3458aa --- /dev/null +++ b/app/assets/images/emoji/question.png diff --git a/app/assets/images/emoji/rabbit.png b/app/assets/images/emoji/rabbit.png Binary files differnew file mode 100644 index 00000000000..ea75ab0426e --- /dev/null +++ b/app/assets/images/emoji/rabbit.png diff --git a/app/assets/images/emoji/rabbit2.png b/app/assets/images/emoji/rabbit2.png Binary files differnew file mode 100644 index 00000000000..2c8a29c642f --- /dev/null +++ b/app/assets/images/emoji/rabbit2.png diff --git a/app/assets/images/emoji/race_car.png b/app/assets/images/emoji/race_car.png Binary files differnew file mode 100644 index 00000000000..fe3f045f446 --- /dev/null +++ b/app/assets/images/emoji/race_car.png diff --git a/app/assets/images/emoji/racehorse.png b/app/assets/images/emoji/racehorse.png Binary files differnew file mode 100644 index 00000000000..b3e73cc8903 --- /dev/null +++ b/app/assets/images/emoji/racehorse.png diff --git a/app/assets/images/emoji/radio.png b/app/assets/images/emoji/radio.png Binary files differnew file mode 100644 index 00000000000..dec381fa242 --- /dev/null +++ b/app/assets/images/emoji/radio.png diff --git a/app/assets/images/emoji/radio_button.png b/app/assets/images/emoji/radio_button.png Binary files differnew file mode 100644 index 00000000000..3a23449d917 --- /dev/null +++ b/app/assets/images/emoji/radio_button.png diff --git a/app/assets/images/emoji/radioactive.png b/app/assets/images/emoji/radioactive.png Binary files differnew file mode 100644 index 00000000000..3b46199fe37 --- /dev/null +++ b/app/assets/images/emoji/radioactive.png diff --git a/app/assets/images/emoji/rage.png b/app/assets/images/emoji/rage.png Binary files differnew file mode 100644 index 00000000000..9d739bd40ad --- /dev/null +++ b/app/assets/images/emoji/rage.png diff --git a/app/assets/images/emoji/railway_car.png b/app/assets/images/emoji/railway_car.png Binary files differnew file mode 100644 index 00000000000..a9acbf13008 --- /dev/null +++ b/app/assets/images/emoji/railway_car.png diff --git a/app/assets/images/emoji/railway_track.png b/app/assets/images/emoji/railway_track.png Binary files differnew file mode 100644 index 00000000000..e1a7a0d1430 --- /dev/null +++ b/app/assets/images/emoji/railway_track.png diff --git a/app/assets/images/emoji/rainbow.png b/app/assets/images/emoji/rainbow.png Binary files differnew file mode 100644 index 00000000000..154735d7147 --- /dev/null +++ b/app/assets/images/emoji/rainbow.png diff --git a/app/assets/images/emoji/raised_back_of_hand.png b/app/assets/images/emoji/raised_back_of_hand.png Binary files differnew file mode 100644 index 00000000000..479234294b4 --- /dev/null +++ b/app/assets/images/emoji/raised_back_of_hand.png diff --git a/app/assets/images/emoji/raised_back_of_hand_tone1.png b/app/assets/images/emoji/raised_back_of_hand_tone1.png Binary files differnew file mode 100644 index 00000000000..813d28499b5 --- /dev/null +++ b/app/assets/images/emoji/raised_back_of_hand_tone1.png diff --git a/app/assets/images/emoji/raised_back_of_hand_tone2.png b/app/assets/images/emoji/raised_back_of_hand_tone2.png Binary files differnew file mode 100644 index 00000000000..192ff795e37 --- /dev/null +++ b/app/assets/images/emoji/raised_back_of_hand_tone2.png diff --git a/app/assets/images/emoji/raised_back_of_hand_tone3.png b/app/assets/images/emoji/raised_back_of_hand_tone3.png Binary files differnew file mode 100644 index 00000000000..61a727abe6b --- /dev/null +++ b/app/assets/images/emoji/raised_back_of_hand_tone3.png diff --git a/app/assets/images/emoji/raised_back_of_hand_tone4.png b/app/assets/images/emoji/raised_back_of_hand_tone4.png Binary files differnew file mode 100644 index 00000000000..2e83da511f5 --- /dev/null +++ b/app/assets/images/emoji/raised_back_of_hand_tone4.png diff --git a/app/assets/images/emoji/raised_back_of_hand_tone5.png b/app/assets/images/emoji/raised_back_of_hand_tone5.png Binary files differnew file mode 100644 index 00000000000..d7a5b95a02c --- /dev/null +++ b/app/assets/images/emoji/raised_back_of_hand_tone5.png diff --git a/app/assets/images/emoji/raised_hand.png b/app/assets/images/emoji/raised_hand.png Binary files differnew file mode 100644 index 00000000000..6b2954315d1 --- /dev/null +++ b/app/assets/images/emoji/raised_hand.png diff --git a/app/assets/images/emoji/raised_hand_tone1.png b/app/assets/images/emoji/raised_hand_tone1.png Binary files differnew file mode 100644 index 00000000000..3b752902c07 --- /dev/null +++ b/app/assets/images/emoji/raised_hand_tone1.png diff --git a/app/assets/images/emoji/raised_hand_tone2.png b/app/assets/images/emoji/raised_hand_tone2.png Binary files differnew file mode 100644 index 00000000000..44e2a514c60 --- /dev/null +++ b/app/assets/images/emoji/raised_hand_tone2.png diff --git a/app/assets/images/emoji/raised_hand_tone3.png b/app/assets/images/emoji/raised_hand_tone3.png Binary files differnew file mode 100644 index 00000000000..5bb62a7528a --- /dev/null +++ b/app/assets/images/emoji/raised_hand_tone3.png diff --git a/app/assets/images/emoji/raised_hand_tone4.png b/app/assets/images/emoji/raised_hand_tone4.png Binary files differnew file mode 100644 index 00000000000..c7f8c9ec270 --- /dev/null +++ b/app/assets/images/emoji/raised_hand_tone4.png diff --git a/app/assets/images/emoji/raised_hand_tone5.png b/app/assets/images/emoji/raised_hand_tone5.png Binary files differnew file mode 100644 index 00000000000..c601b58a73e --- /dev/null +++ b/app/assets/images/emoji/raised_hand_tone5.png diff --git a/app/assets/images/emoji/raised_hands.png b/app/assets/images/emoji/raised_hands.png Binary files differnew file mode 100644 index 00000000000..c0155f728e7 --- /dev/null +++ b/app/assets/images/emoji/raised_hands.png diff --git a/app/assets/images/emoji/raised_hands_tone1.png b/app/assets/images/emoji/raised_hands_tone1.png Binary files differnew file mode 100644 index 00000000000..1168b8236b6 --- /dev/null +++ b/app/assets/images/emoji/raised_hands_tone1.png diff --git a/app/assets/images/emoji/raised_hands_tone2.png b/app/assets/images/emoji/raised_hands_tone2.png Binary files differnew file mode 100644 index 00000000000..322de622903 --- /dev/null +++ b/app/assets/images/emoji/raised_hands_tone2.png diff --git a/app/assets/images/emoji/raised_hands_tone3.png b/app/assets/images/emoji/raised_hands_tone3.png Binary files differnew file mode 100644 index 00000000000..2aa24e05ae1 --- /dev/null +++ b/app/assets/images/emoji/raised_hands_tone3.png diff --git a/app/assets/images/emoji/raised_hands_tone4.png b/app/assets/images/emoji/raised_hands_tone4.png Binary files differnew file mode 100644 index 00000000000..f31bf0db992 --- /dev/null +++ b/app/assets/images/emoji/raised_hands_tone4.png diff --git a/app/assets/images/emoji/raised_hands_tone5.png b/app/assets/images/emoji/raised_hands_tone5.png Binary files differnew file mode 100644 index 00000000000..5e95067f98b --- /dev/null +++ b/app/assets/images/emoji/raised_hands_tone5.png diff --git a/app/assets/images/emoji/raising_hand.png b/app/assets/images/emoji/raising_hand.png Binary files differnew file mode 100644 index 00000000000..2880708c0cc --- /dev/null +++ b/app/assets/images/emoji/raising_hand.png diff --git a/app/assets/images/emoji/raising_hand_tone1.png b/app/assets/images/emoji/raising_hand_tone1.png Binary files differnew file mode 100644 index 00000000000..1c90e3e2689 --- /dev/null +++ b/app/assets/images/emoji/raising_hand_tone1.png diff --git a/app/assets/images/emoji/raising_hand_tone2.png b/app/assets/images/emoji/raising_hand_tone2.png Binary files differnew file mode 100644 index 00000000000..82c3ef2bfc5 --- /dev/null +++ b/app/assets/images/emoji/raising_hand_tone2.png diff --git a/app/assets/images/emoji/raising_hand_tone3.png b/app/assets/images/emoji/raising_hand_tone3.png Binary files differnew file mode 100644 index 00000000000..1b1da2aa0ca --- /dev/null +++ b/app/assets/images/emoji/raising_hand_tone3.png diff --git a/app/assets/images/emoji/raising_hand_tone4.png b/app/assets/images/emoji/raising_hand_tone4.png Binary files differnew file mode 100644 index 00000000000..e453855c01f --- /dev/null +++ b/app/assets/images/emoji/raising_hand_tone4.png diff --git a/app/assets/images/emoji/raising_hand_tone5.png b/app/assets/images/emoji/raising_hand_tone5.png Binary files differnew file mode 100644 index 00000000000..b86200fd844 --- /dev/null +++ b/app/assets/images/emoji/raising_hand_tone5.png diff --git a/app/assets/images/emoji/ram.png b/app/assets/images/emoji/ram.png Binary files differnew file mode 100644 index 00000000000..52a44464c9b --- /dev/null +++ b/app/assets/images/emoji/ram.png diff --git a/app/assets/images/emoji/ramen.png b/app/assets/images/emoji/ramen.png Binary files differnew file mode 100644 index 00000000000..c1cb7cd7384 --- /dev/null +++ b/app/assets/images/emoji/ramen.png diff --git a/app/assets/images/emoji/rat.png b/app/assets/images/emoji/rat.png Binary files differnew file mode 100644 index 00000000000..86219144f10 --- /dev/null +++ b/app/assets/images/emoji/rat.png diff --git a/app/assets/images/emoji/record_button.png b/app/assets/images/emoji/record_button.png Binary files differnew file mode 100644 index 00000000000..ada52830fce --- /dev/null +++ b/app/assets/images/emoji/record_button.png diff --git a/app/assets/images/emoji/recycle.png b/app/assets/images/emoji/recycle.png Binary files differnew file mode 100644 index 00000000000..9221f095c37 --- /dev/null +++ b/app/assets/images/emoji/recycle.png diff --git a/app/assets/images/emoji/red_car.png b/app/assets/images/emoji/red_car.png Binary files differnew file mode 100644 index 00000000000..b3e6a774dea --- /dev/null +++ b/app/assets/images/emoji/red_car.png diff --git a/app/assets/images/emoji/red_circle.png b/app/assets/images/emoji/red_circle.png Binary files differnew file mode 100644 index 00000000000..4bef930d92f --- /dev/null +++ b/app/assets/images/emoji/red_circle.png diff --git a/app/assets/images/emoji/registered.png b/app/assets/images/emoji/registered.png Binary files differnew file mode 100644 index 00000000000..53ef9f2d4e6 --- /dev/null +++ b/app/assets/images/emoji/registered.png diff --git a/app/assets/images/emoji/relaxed.png b/app/assets/images/emoji/relaxed.png Binary files differnew file mode 100644 index 00000000000..e9e53c03d45 --- /dev/null +++ b/app/assets/images/emoji/relaxed.png diff --git a/app/assets/images/emoji/relieved.png b/app/assets/images/emoji/relieved.png Binary files differnew file mode 100644 index 00000000000..715ad0bf53f --- /dev/null +++ b/app/assets/images/emoji/relieved.png diff --git a/app/assets/images/emoji/reminder_ribbon.png b/app/assets/images/emoji/reminder_ribbon.png Binary files differnew file mode 100644 index 00000000000..3988bbd094c --- /dev/null +++ b/app/assets/images/emoji/reminder_ribbon.png diff --git a/app/assets/images/emoji/repeat.png b/app/assets/images/emoji/repeat.png Binary files differnew file mode 100644 index 00000000000..540ce4e0fba --- /dev/null +++ b/app/assets/images/emoji/repeat.png diff --git a/app/assets/images/emoji/repeat_one.png b/app/assets/images/emoji/repeat_one.png Binary files differnew file mode 100644 index 00000000000..9567e83337f --- /dev/null +++ b/app/assets/images/emoji/repeat_one.png diff --git a/app/assets/images/emoji/restroom.png b/app/assets/images/emoji/restroom.png Binary files differnew file mode 100644 index 00000000000..9588e0f0ef7 --- /dev/null +++ b/app/assets/images/emoji/restroom.png diff --git a/app/assets/images/emoji/revolving_hearts.png b/app/assets/images/emoji/revolving_hearts.png Binary files differnew file mode 100644 index 00000000000..7b9d1948f73 --- /dev/null +++ b/app/assets/images/emoji/revolving_hearts.png diff --git a/app/assets/images/emoji/rewind.png b/app/assets/images/emoji/rewind.png Binary files differnew file mode 100644 index 00000000000..e22e2bd3da5 --- /dev/null +++ b/app/assets/images/emoji/rewind.png diff --git a/app/assets/images/emoji/rhino.png b/app/assets/images/emoji/rhino.png Binary files differnew file mode 100644 index 00000000000..12f4e0d9d9b --- /dev/null +++ b/app/assets/images/emoji/rhino.png diff --git a/app/assets/images/emoji/ribbon.png b/app/assets/images/emoji/ribbon.png Binary files differnew file mode 100644 index 00000000000..0f253c3d8c8 --- /dev/null +++ b/app/assets/images/emoji/ribbon.png diff --git a/app/assets/images/emoji/rice.png b/app/assets/images/emoji/rice.png Binary files differnew file mode 100644 index 00000000000..6e3ac7956b1 --- /dev/null +++ b/app/assets/images/emoji/rice.png diff --git a/app/assets/images/emoji/rice_ball.png b/app/assets/images/emoji/rice_ball.png Binary files differnew file mode 100644 index 00000000000..d3d8ee25cb8 --- /dev/null +++ b/app/assets/images/emoji/rice_ball.png diff --git a/app/assets/images/emoji/rice_cracker.png b/app/assets/images/emoji/rice_cracker.png Binary files differnew file mode 100644 index 00000000000..7fbd08e4ff9 --- /dev/null +++ b/app/assets/images/emoji/rice_cracker.png diff --git a/app/assets/images/emoji/rice_scene.png b/app/assets/images/emoji/rice_scene.png Binary files differnew file mode 100644 index 00000000000..1a28426592a --- /dev/null +++ b/app/assets/images/emoji/rice_scene.png diff --git a/app/assets/images/emoji/right_facing_fist.png b/app/assets/images/emoji/right_facing_fist.png Binary files differnew file mode 100644 index 00000000000..754ed066d2c --- /dev/null +++ b/app/assets/images/emoji/right_facing_fist.png diff --git a/app/assets/images/emoji/right_facing_fist_tone1.png b/app/assets/images/emoji/right_facing_fist_tone1.png Binary files differnew file mode 100644 index 00000000000..33ded2f61a6 --- /dev/null +++ b/app/assets/images/emoji/right_facing_fist_tone1.png diff --git a/app/assets/images/emoji/right_facing_fist_tone2.png b/app/assets/images/emoji/right_facing_fist_tone2.png Binary files differnew file mode 100644 index 00000000000..88054e335c7 --- /dev/null +++ b/app/assets/images/emoji/right_facing_fist_tone2.png diff --git a/app/assets/images/emoji/right_facing_fist_tone3.png b/app/assets/images/emoji/right_facing_fist_tone3.png Binary files differnew file mode 100644 index 00000000000..84b9f5da7f7 --- /dev/null +++ b/app/assets/images/emoji/right_facing_fist_tone3.png diff --git a/app/assets/images/emoji/right_facing_fist_tone4.png b/app/assets/images/emoji/right_facing_fist_tone4.png Binary files differnew file mode 100644 index 00000000000..e741cfea68b --- /dev/null +++ b/app/assets/images/emoji/right_facing_fist_tone4.png diff --git a/app/assets/images/emoji/right_facing_fist_tone5.png b/app/assets/images/emoji/right_facing_fist_tone5.png Binary files differnew file mode 100644 index 00000000000..cf66d760c1f --- /dev/null +++ b/app/assets/images/emoji/right_facing_fist_tone5.png diff --git a/app/assets/images/emoji/ring.png b/app/assets/images/emoji/ring.png Binary files differnew file mode 100644 index 00000000000..87d227adb74 --- /dev/null +++ b/app/assets/images/emoji/ring.png diff --git a/app/assets/images/emoji/robot.png b/app/assets/images/emoji/robot.png Binary files differnew file mode 100644 index 00000000000..7cc62612c6a --- /dev/null +++ b/app/assets/images/emoji/robot.png diff --git a/app/assets/images/emoji/rocket.png b/app/assets/images/emoji/rocket.png Binary files differnew file mode 100644 index 00000000000..0d8da089a37 --- /dev/null +++ b/app/assets/images/emoji/rocket.png diff --git a/app/assets/images/emoji/rofl.png b/app/assets/images/emoji/rofl.png Binary files differnew file mode 100644 index 00000000000..b1736fedfeb --- /dev/null +++ b/app/assets/images/emoji/rofl.png diff --git a/app/assets/images/emoji/roller_coaster.png b/app/assets/images/emoji/roller_coaster.png Binary files differnew file mode 100644 index 00000000000..5b849e071e8 --- /dev/null +++ b/app/assets/images/emoji/roller_coaster.png diff --git a/app/assets/images/emoji/rolling_eyes.png b/app/assets/images/emoji/rolling_eyes.png Binary files differnew file mode 100644 index 00000000000..2f77b9fc3b9 --- /dev/null +++ b/app/assets/images/emoji/rolling_eyes.png diff --git a/app/assets/images/emoji/rooster.png b/app/assets/images/emoji/rooster.png Binary files differnew file mode 100644 index 00000000000..bbf2bbff97a --- /dev/null +++ b/app/assets/images/emoji/rooster.png diff --git a/app/assets/images/emoji/rose.png b/app/assets/images/emoji/rose.png Binary files differnew file mode 100644 index 00000000000..52c286d31ce --- /dev/null +++ b/app/assets/images/emoji/rose.png diff --git a/app/assets/images/emoji/rosette.png b/app/assets/images/emoji/rosette.png Binary files differnew file mode 100644 index 00000000000..8030e494bcf --- /dev/null +++ b/app/assets/images/emoji/rosette.png diff --git a/app/assets/images/emoji/rotating_light.png b/app/assets/images/emoji/rotating_light.png Binary files differnew file mode 100644 index 00000000000..cad66b0afef --- /dev/null +++ b/app/assets/images/emoji/rotating_light.png diff --git a/app/assets/images/emoji/round_pushpin.png b/app/assets/images/emoji/round_pushpin.png Binary files differnew file mode 100644 index 00000000000..28b9d72866e --- /dev/null +++ b/app/assets/images/emoji/round_pushpin.png diff --git a/app/assets/images/emoji/rowboat.png b/app/assets/images/emoji/rowboat.png Binary files differnew file mode 100644 index 00000000000..dd4dfc095d9 --- /dev/null +++ b/app/assets/images/emoji/rowboat.png diff --git a/app/assets/images/emoji/rowboat_tone1.png b/app/assets/images/emoji/rowboat_tone1.png Binary files differnew file mode 100644 index 00000000000..5e5d18548cb --- /dev/null +++ b/app/assets/images/emoji/rowboat_tone1.png diff --git a/app/assets/images/emoji/rowboat_tone2.png b/app/assets/images/emoji/rowboat_tone2.png Binary files differnew file mode 100644 index 00000000000..9b123ef8871 --- /dev/null +++ b/app/assets/images/emoji/rowboat_tone2.png diff --git a/app/assets/images/emoji/rowboat_tone3.png b/app/assets/images/emoji/rowboat_tone3.png Binary files differnew file mode 100644 index 00000000000..8ebd89a55f5 --- /dev/null +++ b/app/assets/images/emoji/rowboat_tone3.png diff --git a/app/assets/images/emoji/rowboat_tone4.png b/app/assets/images/emoji/rowboat_tone4.png Binary files differnew file mode 100644 index 00000000000..2b0d04f8725 --- /dev/null +++ b/app/assets/images/emoji/rowboat_tone4.png diff --git a/app/assets/images/emoji/rowboat_tone5.png b/app/assets/images/emoji/rowboat_tone5.png Binary files differnew file mode 100644 index 00000000000..b346f2dfc84 --- /dev/null +++ b/app/assets/images/emoji/rowboat_tone5.png diff --git a/app/assets/images/emoji/rugby_football.png b/app/assets/images/emoji/rugby_football.png Binary files differnew file mode 100644 index 00000000000..b1872273436 --- /dev/null +++ b/app/assets/images/emoji/rugby_football.png diff --git a/app/assets/images/emoji/runner.png b/app/assets/images/emoji/runner.png Binary files differnew file mode 100644 index 00000000000..e914915976a --- /dev/null +++ b/app/assets/images/emoji/runner.png diff --git a/app/assets/images/emoji/runner_tone1.png b/app/assets/images/emoji/runner_tone1.png Binary files differnew file mode 100644 index 00000000000..9355239a52d --- /dev/null +++ b/app/assets/images/emoji/runner_tone1.png diff --git a/app/assets/images/emoji/runner_tone2.png b/app/assets/images/emoji/runner_tone2.png Binary files differnew file mode 100644 index 00000000000..6112fd5c376 --- /dev/null +++ b/app/assets/images/emoji/runner_tone2.png diff --git a/app/assets/images/emoji/runner_tone3.png b/app/assets/images/emoji/runner_tone3.png Binary files differnew file mode 100644 index 00000000000..625ec708f48 --- /dev/null +++ b/app/assets/images/emoji/runner_tone3.png diff --git a/app/assets/images/emoji/runner_tone4.png b/app/assets/images/emoji/runner_tone4.png Binary files differnew file mode 100644 index 00000000000..242f1b56337 --- /dev/null +++ b/app/assets/images/emoji/runner_tone4.png diff --git a/app/assets/images/emoji/runner_tone5.png b/app/assets/images/emoji/runner_tone5.png Binary files differnew file mode 100644 index 00000000000..2976c6f019f --- /dev/null +++ b/app/assets/images/emoji/runner_tone5.png diff --git a/app/assets/images/emoji/running_shirt_with_sash.png b/app/assets/images/emoji/running_shirt_with_sash.png Binary files differnew file mode 100644 index 00000000000..6d83c06b803 --- /dev/null +++ b/app/assets/images/emoji/running_shirt_with_sash.png diff --git a/app/assets/images/emoji/sa.png b/app/assets/images/emoji/sa.png Binary files differnew file mode 100644 index 00000000000..900f9633247 --- /dev/null +++ b/app/assets/images/emoji/sa.png diff --git a/app/assets/images/emoji/sagittarius.png b/app/assets/images/emoji/sagittarius.png Binary files differnew file mode 100644 index 00000000000..f8d94ff2923 --- /dev/null +++ b/app/assets/images/emoji/sagittarius.png diff --git a/app/assets/images/emoji/sailboat.png b/app/assets/images/emoji/sailboat.png Binary files differnew file mode 100644 index 00000000000..772ef11da5d --- /dev/null +++ b/app/assets/images/emoji/sailboat.png diff --git a/app/assets/images/emoji/sake.png b/app/assets/images/emoji/sake.png Binary files differnew file mode 100644 index 00000000000..2933f5672c4 --- /dev/null +++ b/app/assets/images/emoji/sake.png diff --git a/app/assets/images/emoji/salad.png b/app/assets/images/emoji/salad.png Binary files differnew file mode 100644 index 00000000000..c89f9341158 --- /dev/null +++ b/app/assets/images/emoji/salad.png diff --git a/app/assets/images/emoji/sandal.png b/app/assets/images/emoji/sandal.png Binary files differnew file mode 100644 index 00000000000..9d9f5122b7a --- /dev/null +++ b/app/assets/images/emoji/sandal.png diff --git a/app/assets/images/emoji/santa.png b/app/assets/images/emoji/santa.png Binary files differnew file mode 100644 index 00000000000..bc83ab80d52 --- /dev/null +++ b/app/assets/images/emoji/santa.png diff --git a/app/assets/images/emoji/santa_tone1.png b/app/assets/images/emoji/santa_tone1.png Binary files differnew file mode 100644 index 00000000000..5233ffb7174 --- /dev/null +++ b/app/assets/images/emoji/santa_tone1.png diff --git a/app/assets/images/emoji/santa_tone2.png b/app/assets/images/emoji/santa_tone2.png Binary files differnew file mode 100644 index 00000000000..4e845438197 --- /dev/null +++ b/app/assets/images/emoji/santa_tone2.png diff --git a/app/assets/images/emoji/santa_tone3.png b/app/assets/images/emoji/santa_tone3.png Binary files differnew file mode 100644 index 00000000000..7fc4f33b60f --- /dev/null +++ b/app/assets/images/emoji/santa_tone3.png diff --git a/app/assets/images/emoji/santa_tone4.png b/app/assets/images/emoji/santa_tone4.png Binary files differnew file mode 100644 index 00000000000..d1d5a15132d --- /dev/null +++ b/app/assets/images/emoji/santa_tone4.png diff --git a/app/assets/images/emoji/santa_tone5.png b/app/assets/images/emoji/santa_tone5.png Binary files differnew file mode 100644 index 00000000000..4d697a01f24 --- /dev/null +++ b/app/assets/images/emoji/santa_tone5.png diff --git a/app/assets/images/emoji/satellite.png b/app/assets/images/emoji/satellite.png Binary files differnew file mode 100644 index 00000000000..db0372795f4 --- /dev/null +++ b/app/assets/images/emoji/satellite.png diff --git a/app/assets/images/emoji/satellite_orbital.png b/app/assets/images/emoji/satellite_orbital.png Binary files differnew file mode 100644 index 00000000000..4ba55d6e297 --- /dev/null +++ b/app/assets/images/emoji/satellite_orbital.png diff --git a/app/assets/images/emoji/saxophone.png b/app/assets/images/emoji/saxophone.png Binary files differnew file mode 100644 index 00000000000..a392faec291 --- /dev/null +++ b/app/assets/images/emoji/saxophone.png diff --git a/app/assets/images/emoji/scales.png b/app/assets/images/emoji/scales.png Binary files differnew file mode 100644 index 00000000000..0757eda1684 --- /dev/null +++ b/app/assets/images/emoji/scales.png diff --git a/app/assets/images/emoji/school.png b/app/assets/images/emoji/school.png Binary files differnew file mode 100644 index 00000000000..269759534f0 --- /dev/null +++ b/app/assets/images/emoji/school.png diff --git a/app/assets/images/emoji/school_satchel.png b/app/assets/images/emoji/school_satchel.png Binary files differnew file mode 100644 index 00000000000..9997c86e7dc --- /dev/null +++ b/app/assets/images/emoji/school_satchel.png diff --git a/app/assets/images/emoji/scissors.png b/app/assets/images/emoji/scissors.png Binary files differnew file mode 100644 index 00000000000..270571c8cdd --- /dev/null +++ b/app/assets/images/emoji/scissors.png diff --git a/app/assets/images/emoji/scooter.png b/app/assets/images/emoji/scooter.png Binary files differnew file mode 100644 index 00000000000..4ab7ef59cd2 --- /dev/null +++ b/app/assets/images/emoji/scooter.png diff --git a/app/assets/images/emoji/scorpion.png b/app/assets/images/emoji/scorpion.png Binary files differnew file mode 100644 index 00000000000..449a6b281c9 --- /dev/null +++ b/app/assets/images/emoji/scorpion.png diff --git a/app/assets/images/emoji/scorpius.png b/app/assets/images/emoji/scorpius.png Binary files differnew file mode 100644 index 00000000000..c31a9920455 --- /dev/null +++ b/app/assets/images/emoji/scorpius.png diff --git a/app/assets/images/emoji/scream.png b/app/assets/images/emoji/scream.png Binary files differnew file mode 100644 index 00000000000..c3bea9f2510 --- /dev/null +++ b/app/assets/images/emoji/scream.png diff --git a/app/assets/images/emoji/scream_cat.png b/app/assets/images/emoji/scream_cat.png Binary files differnew file mode 100644 index 00000000000..15803ad8e6e --- /dev/null +++ b/app/assets/images/emoji/scream_cat.png diff --git a/app/assets/images/emoji/scroll.png b/app/assets/images/emoji/scroll.png Binary files differnew file mode 100644 index 00000000000..50ee5dcd4b9 --- /dev/null +++ b/app/assets/images/emoji/scroll.png diff --git a/app/assets/images/emoji/seat.png b/app/assets/images/emoji/seat.png Binary files differnew file mode 100644 index 00000000000..a6d72d95adb --- /dev/null +++ b/app/assets/images/emoji/seat.png diff --git a/app/assets/images/emoji/second_place.png b/app/assets/images/emoji/second_place.png Binary files differnew file mode 100644 index 00000000000..17b011268b6 --- /dev/null +++ b/app/assets/images/emoji/second_place.png diff --git a/app/assets/images/emoji/secret.png b/app/assets/images/emoji/secret.png Binary files differnew file mode 100644 index 00000000000..5fd72608e60 --- /dev/null +++ b/app/assets/images/emoji/secret.png diff --git a/app/assets/images/emoji/see_no_evil.png b/app/assets/images/emoji/see_no_evil.png Binary files differnew file mode 100644 index 00000000000..5187e474531 --- /dev/null +++ b/app/assets/images/emoji/see_no_evil.png diff --git a/app/assets/images/emoji/seedling.png b/app/assets/images/emoji/seedling.png Binary files differnew file mode 100644 index 00000000000..ae0948bcfd6 --- /dev/null +++ b/app/assets/images/emoji/seedling.png diff --git a/app/assets/images/emoji/selfie.png b/app/assets/images/emoji/selfie.png Binary files differnew file mode 100644 index 00000000000..6a1ba75c7e3 --- /dev/null +++ b/app/assets/images/emoji/selfie.png diff --git a/app/assets/images/emoji/selfie_tone1.png b/app/assets/images/emoji/selfie_tone1.png Binary files differnew file mode 100644 index 00000000000..290e075b56f --- /dev/null +++ b/app/assets/images/emoji/selfie_tone1.png diff --git a/app/assets/images/emoji/selfie_tone2.png b/app/assets/images/emoji/selfie_tone2.png Binary files differnew file mode 100644 index 00000000000..fcd9595b643 --- /dev/null +++ b/app/assets/images/emoji/selfie_tone2.png diff --git a/app/assets/images/emoji/selfie_tone3.png b/app/assets/images/emoji/selfie_tone3.png Binary files differnew file mode 100644 index 00000000000..f3a22fdf435 --- /dev/null +++ b/app/assets/images/emoji/selfie_tone3.png diff --git a/app/assets/images/emoji/selfie_tone4.png b/app/assets/images/emoji/selfie_tone4.png Binary files differnew file mode 100644 index 00000000000..cdecf6d9f4e --- /dev/null +++ b/app/assets/images/emoji/selfie_tone4.png diff --git a/app/assets/images/emoji/selfie_tone5.png b/app/assets/images/emoji/selfie_tone5.png Binary files differnew file mode 100644 index 00000000000..86acbb6c202 --- /dev/null +++ b/app/assets/images/emoji/selfie_tone5.png diff --git a/app/assets/images/emoji/seven.png b/app/assets/images/emoji/seven.png Binary files differnew file mode 100644 index 00000000000..9b3476ae7c7 --- /dev/null +++ b/app/assets/images/emoji/seven.png diff --git a/app/assets/images/emoji/shallow_pan_of_food.png b/app/assets/images/emoji/shallow_pan_of_food.png Binary files differnew file mode 100644 index 00000000000..663a1006acd --- /dev/null +++ b/app/assets/images/emoji/shallow_pan_of_food.png diff --git a/app/assets/images/emoji/shamrock.png b/app/assets/images/emoji/shamrock.png Binary files differnew file mode 100644 index 00000000000..f202aecfe6f --- /dev/null +++ b/app/assets/images/emoji/shamrock.png diff --git a/app/assets/images/emoji/shark.png b/app/assets/images/emoji/shark.png Binary files differnew file mode 100644 index 00000000000..c75076d57d8 --- /dev/null +++ b/app/assets/images/emoji/shark.png diff --git a/app/assets/images/emoji/shaved_ice.png b/app/assets/images/emoji/shaved_ice.png Binary files differnew file mode 100644 index 00000000000..36dfb53ca93 --- /dev/null +++ b/app/assets/images/emoji/shaved_ice.png diff --git a/app/assets/images/emoji/sheep.png b/app/assets/images/emoji/sheep.png Binary files differnew file mode 100644 index 00000000000..102b8a52b28 --- /dev/null +++ b/app/assets/images/emoji/sheep.png diff --git a/app/assets/images/emoji/shell.png b/app/assets/images/emoji/shell.png Binary files differnew file mode 100644 index 00000000000..55721629f62 --- /dev/null +++ b/app/assets/images/emoji/shell.png diff --git a/app/assets/images/emoji/shield.png b/app/assets/images/emoji/shield.png Binary files differnew file mode 100644 index 00000000000..610bf033ce0 --- /dev/null +++ b/app/assets/images/emoji/shield.png diff --git a/app/assets/images/emoji/shinto_shrine.png b/app/assets/images/emoji/shinto_shrine.png Binary files differnew file mode 100644 index 00000000000..5a344975bf3 --- /dev/null +++ b/app/assets/images/emoji/shinto_shrine.png diff --git a/app/assets/images/emoji/ship.png b/app/assets/images/emoji/ship.png Binary files differnew file mode 100644 index 00000000000..62d54f7d6c9 --- /dev/null +++ b/app/assets/images/emoji/ship.png diff --git a/app/assets/images/emoji/shirt.png b/app/assets/images/emoji/shirt.png Binary files differnew file mode 100644 index 00000000000..af08dec8b59 --- /dev/null +++ b/app/assets/images/emoji/shirt.png diff --git a/app/assets/images/emoji/shopping_bags.png b/app/assets/images/emoji/shopping_bags.png Binary files differnew file mode 100644 index 00000000000..99f2a2b13ac --- /dev/null +++ b/app/assets/images/emoji/shopping_bags.png diff --git a/app/assets/images/emoji/shopping_cart.png b/app/assets/images/emoji/shopping_cart.png Binary files differnew file mode 100644 index 00000000000..1086fe6e456 --- /dev/null +++ b/app/assets/images/emoji/shopping_cart.png diff --git a/app/assets/images/emoji/shower.png b/app/assets/images/emoji/shower.png Binary files differnew file mode 100644 index 00000000000..156776a2e52 --- /dev/null +++ b/app/assets/images/emoji/shower.png diff --git a/app/assets/images/emoji/shrimp.png b/app/assets/images/emoji/shrimp.png Binary files differnew file mode 100644 index 00000000000..49eff28a71e --- /dev/null +++ b/app/assets/images/emoji/shrimp.png diff --git a/app/assets/images/emoji/shrug.png b/app/assets/images/emoji/shrug.png Binary files differnew file mode 100644 index 00000000000..76e63bfac77 --- /dev/null +++ b/app/assets/images/emoji/shrug.png diff --git a/app/assets/images/emoji/shrug_tone1.png b/app/assets/images/emoji/shrug_tone1.png Binary files differnew file mode 100644 index 00000000000..1c895e64468 --- /dev/null +++ b/app/assets/images/emoji/shrug_tone1.png diff --git a/app/assets/images/emoji/shrug_tone2.png b/app/assets/images/emoji/shrug_tone2.png Binary files differnew file mode 100644 index 00000000000..4e3ca8f8bac --- /dev/null +++ b/app/assets/images/emoji/shrug_tone2.png diff --git a/app/assets/images/emoji/shrug_tone3.png b/app/assets/images/emoji/shrug_tone3.png Binary files differnew file mode 100644 index 00000000000..d1b16a19bb5 --- /dev/null +++ b/app/assets/images/emoji/shrug_tone3.png diff --git a/app/assets/images/emoji/shrug_tone4.png b/app/assets/images/emoji/shrug_tone4.png Binary files differnew file mode 100644 index 00000000000..5fbef3f2255 --- /dev/null +++ b/app/assets/images/emoji/shrug_tone4.png diff --git a/app/assets/images/emoji/shrug_tone5.png b/app/assets/images/emoji/shrug_tone5.png Binary files differnew file mode 100644 index 00000000000..4af2e28bc5c --- /dev/null +++ b/app/assets/images/emoji/shrug_tone5.png diff --git a/app/assets/images/emoji/signal_strength.png b/app/assets/images/emoji/signal_strength.png Binary files differnew file mode 100644 index 00000000000..ee2b5a4b519 --- /dev/null +++ b/app/assets/images/emoji/signal_strength.png diff --git a/app/assets/images/emoji/six.png b/app/assets/images/emoji/six.png Binary files differnew file mode 100644 index 00000000000..371b3acef2c --- /dev/null +++ b/app/assets/images/emoji/six.png diff --git a/app/assets/images/emoji/six_pointed_star.png b/app/assets/images/emoji/six_pointed_star.png Binary files differnew file mode 100644 index 00000000000..2eb1707458b --- /dev/null +++ b/app/assets/images/emoji/six_pointed_star.png diff --git a/app/assets/images/emoji/ski.png b/app/assets/images/emoji/ski.png Binary files differnew file mode 100644 index 00000000000..4a2d2c12306 --- /dev/null +++ b/app/assets/images/emoji/ski.png diff --git a/app/assets/images/emoji/skier.png b/app/assets/images/emoji/skier.png Binary files differnew file mode 100644 index 00000000000..2eb3bdce2af --- /dev/null +++ b/app/assets/images/emoji/skier.png diff --git a/app/assets/images/emoji/skull.png b/app/assets/images/emoji/skull.png Binary files differnew file mode 100644 index 00000000000..26abb17296a --- /dev/null +++ b/app/assets/images/emoji/skull.png diff --git a/app/assets/images/emoji/skull_crossbones.png b/app/assets/images/emoji/skull_crossbones.png Binary files differnew file mode 100644 index 00000000000..b459df9227a --- /dev/null +++ b/app/assets/images/emoji/skull_crossbones.png diff --git a/app/assets/images/emoji/sleeping.png b/app/assets/images/emoji/sleeping.png Binary files differnew file mode 100644 index 00000000000..9ecf600d6d8 --- /dev/null +++ b/app/assets/images/emoji/sleeping.png diff --git a/app/assets/images/emoji/sleeping_accommodation.png b/app/assets/images/emoji/sleeping_accommodation.png Binary files differnew file mode 100644 index 00000000000..c739e7fb69b --- /dev/null +++ b/app/assets/images/emoji/sleeping_accommodation.png diff --git a/app/assets/images/emoji/sleepy.png b/app/assets/images/emoji/sleepy.png Binary files differnew file mode 100644 index 00000000000..836b4107717 --- /dev/null +++ b/app/assets/images/emoji/sleepy.png diff --git a/app/assets/images/emoji/slight_frown.png b/app/assets/images/emoji/slight_frown.png Binary files differnew file mode 100644 index 00000000000..b2f1d983d36 --- /dev/null +++ b/app/assets/images/emoji/slight_frown.png diff --git a/app/assets/images/emoji/slight_smile.png b/app/assets/images/emoji/slight_smile.png Binary files differnew file mode 100644 index 00000000000..ddd7d65dd3d --- /dev/null +++ b/app/assets/images/emoji/slight_smile.png diff --git a/app/assets/images/emoji/slot_machine.png b/app/assets/images/emoji/slot_machine.png Binary files differnew file mode 100644 index 00000000000..ee71b6c268c --- /dev/null +++ b/app/assets/images/emoji/slot_machine.png diff --git a/app/assets/images/emoji/small_blue_diamond.png b/app/assets/images/emoji/small_blue_diamond.png Binary files differnew file mode 100644 index 00000000000..b86b5bc4db3 --- /dev/null +++ b/app/assets/images/emoji/small_blue_diamond.png diff --git a/app/assets/images/emoji/small_orange_diamond.png b/app/assets/images/emoji/small_orange_diamond.png Binary files differnew file mode 100644 index 00000000000..e1c6ed9b2f8 --- /dev/null +++ b/app/assets/images/emoji/small_orange_diamond.png diff --git a/app/assets/images/emoji/small_red_triangle.png b/app/assets/images/emoji/small_red_triangle.png Binary files differnew file mode 100644 index 00000000000..785887c195a --- /dev/null +++ b/app/assets/images/emoji/small_red_triangle.png diff --git a/app/assets/images/emoji/small_red_triangle_down.png b/app/assets/images/emoji/small_red_triangle_down.png Binary files differnew file mode 100644 index 00000000000..a83beff1914 --- /dev/null +++ b/app/assets/images/emoji/small_red_triangle_down.png diff --git a/app/assets/images/emoji/smile.png b/app/assets/images/emoji/smile.png Binary files differnew file mode 100644 index 00000000000..aa47ffe978c --- /dev/null +++ b/app/assets/images/emoji/smile.png diff --git a/app/assets/images/emoji/smile_cat.png b/app/assets/images/emoji/smile_cat.png Binary files differnew file mode 100644 index 00000000000..6f25f11dd3a --- /dev/null +++ b/app/assets/images/emoji/smile_cat.png diff --git a/app/assets/images/emoji/smiley.png b/app/assets/images/emoji/smiley.png Binary files differnew file mode 100644 index 00000000000..30957a65968 --- /dev/null +++ b/app/assets/images/emoji/smiley.png diff --git a/app/assets/images/emoji/smiley_cat.png b/app/assets/images/emoji/smiley_cat.png Binary files differnew file mode 100644 index 00000000000..163b57a3427 --- /dev/null +++ b/app/assets/images/emoji/smiley_cat.png diff --git a/app/assets/images/emoji/smiling_imp.png b/app/assets/images/emoji/smiling_imp.png Binary files differnew file mode 100644 index 00000000000..cc2c5f1ec72 --- /dev/null +++ b/app/assets/images/emoji/smiling_imp.png diff --git a/app/assets/images/emoji/smirk.png b/app/assets/images/emoji/smirk.png Binary files differnew file mode 100644 index 00000000000..87852109988 --- /dev/null +++ b/app/assets/images/emoji/smirk.png diff --git a/app/assets/images/emoji/smirk_cat.png b/app/assets/images/emoji/smirk_cat.png Binary files differnew file mode 100644 index 00000000000..9ac5954c199 --- /dev/null +++ b/app/assets/images/emoji/smirk_cat.png diff --git a/app/assets/images/emoji/smoking.png b/app/assets/images/emoji/smoking.png Binary files differnew file mode 100644 index 00000000000..910f648c8f9 --- /dev/null +++ b/app/assets/images/emoji/smoking.png diff --git a/app/assets/images/emoji/snail.png b/app/assets/images/emoji/snail.png Binary files differnew file mode 100644 index 00000000000..f4ea071e2d3 --- /dev/null +++ b/app/assets/images/emoji/snail.png diff --git a/app/assets/images/emoji/snake.png b/app/assets/images/emoji/snake.png Binary files differnew file mode 100644 index 00000000000..d0278a28d8c --- /dev/null +++ b/app/assets/images/emoji/snake.png diff --git a/app/assets/images/emoji/sneezing_face.png b/app/assets/images/emoji/sneezing_face.png Binary files differnew file mode 100644 index 00000000000..ccf07d4b64d --- /dev/null +++ b/app/assets/images/emoji/sneezing_face.png diff --git a/app/assets/images/emoji/snowboarder.png b/app/assets/images/emoji/snowboarder.png Binary files differnew file mode 100644 index 00000000000..6361c0f2c9d --- /dev/null +++ b/app/assets/images/emoji/snowboarder.png diff --git a/app/assets/images/emoji/snowflake.png b/app/assets/images/emoji/snowflake.png Binary files differnew file mode 100644 index 00000000000..db319a77ec6 --- /dev/null +++ b/app/assets/images/emoji/snowflake.png diff --git a/app/assets/images/emoji/snowman.png b/app/assets/images/emoji/snowman.png Binary files differnew file mode 100644 index 00000000000..20c177c2aff --- /dev/null +++ b/app/assets/images/emoji/snowman.png diff --git a/app/assets/images/emoji/snowman2.png b/app/assets/images/emoji/snowman2.png Binary files differnew file mode 100644 index 00000000000..896f28502af --- /dev/null +++ b/app/assets/images/emoji/snowman2.png diff --git a/app/assets/images/emoji/sob.png b/app/assets/images/emoji/sob.png Binary files differnew file mode 100644 index 00000000000..52e3517a1ee --- /dev/null +++ b/app/assets/images/emoji/sob.png diff --git a/app/assets/images/emoji/soccer.png b/app/assets/images/emoji/soccer.png Binary files differnew file mode 100644 index 00000000000..28cfa218d6d --- /dev/null +++ b/app/assets/images/emoji/soccer.png diff --git a/app/assets/images/emoji/soon.png b/app/assets/images/emoji/soon.png Binary files differnew file mode 100644 index 00000000000..8cdfd86690d --- /dev/null +++ b/app/assets/images/emoji/soon.png diff --git a/app/assets/images/emoji/sos.png b/app/assets/images/emoji/sos.png Binary files differnew file mode 100644 index 00000000000..d7d8c9953e4 --- /dev/null +++ b/app/assets/images/emoji/sos.png diff --git a/app/assets/images/emoji/sound.png b/app/assets/images/emoji/sound.png Binary files differnew file mode 100644 index 00000000000..e75ddca53ba --- /dev/null +++ b/app/assets/images/emoji/sound.png diff --git a/app/assets/images/emoji/space_invader.png b/app/assets/images/emoji/space_invader.png Binary files differnew file mode 100644 index 00000000000..2e73f5f32e5 --- /dev/null +++ b/app/assets/images/emoji/space_invader.png diff --git a/app/assets/images/emoji/spades.png b/app/assets/images/emoji/spades.png Binary files differnew file mode 100644 index 00000000000..f822f184cb0 --- /dev/null +++ b/app/assets/images/emoji/spades.png diff --git a/app/assets/images/emoji/spaghetti.png b/app/assets/images/emoji/spaghetti.png Binary files differnew file mode 100644 index 00000000000..89c24a321f1 --- /dev/null +++ b/app/assets/images/emoji/spaghetti.png diff --git a/app/assets/images/emoji/sparkle.png b/app/assets/images/emoji/sparkle.png Binary files differnew file mode 100644 index 00000000000..6aa7b6ec9cf --- /dev/null +++ b/app/assets/images/emoji/sparkle.png diff --git a/app/assets/images/emoji/sparkler.png b/app/assets/images/emoji/sparkler.png Binary files differnew file mode 100644 index 00000000000..30339cd6e09 --- /dev/null +++ b/app/assets/images/emoji/sparkler.png diff --git a/app/assets/images/emoji/sparkles.png b/app/assets/images/emoji/sparkles.png Binary files differnew file mode 100644 index 00000000000..169bc10b023 --- /dev/null +++ b/app/assets/images/emoji/sparkles.png diff --git a/app/assets/images/emoji/sparkling_heart.png b/app/assets/images/emoji/sparkling_heart.png Binary files differnew file mode 100644 index 00000000000..6709269454e --- /dev/null +++ b/app/assets/images/emoji/sparkling_heart.png diff --git a/app/assets/images/emoji/speak_no_evil.png b/app/assets/images/emoji/speak_no_evil.png Binary files differnew file mode 100644 index 00000000000..9d9e07c974b --- /dev/null +++ b/app/assets/images/emoji/speak_no_evil.png diff --git a/app/assets/images/emoji/speaker.png b/app/assets/images/emoji/speaker.png Binary files differnew file mode 100644 index 00000000000..7bcffb8fc43 --- /dev/null +++ b/app/assets/images/emoji/speaker.png diff --git a/app/assets/images/emoji/speaking_head.png b/app/assets/images/emoji/speaking_head.png Binary files differnew file mode 100644 index 00000000000..2df93aaae09 --- /dev/null +++ b/app/assets/images/emoji/speaking_head.png diff --git a/app/assets/images/emoji/speech_balloon.png b/app/assets/images/emoji/speech_balloon.png Binary files differnew file mode 100644 index 00000000000..a34ef741733 --- /dev/null +++ b/app/assets/images/emoji/speech_balloon.png diff --git a/app/assets/images/emoji/speedboat.png b/app/assets/images/emoji/speedboat.png Binary files differnew file mode 100644 index 00000000000..74059d12de1 --- /dev/null +++ b/app/assets/images/emoji/speedboat.png diff --git a/app/assets/images/emoji/spider.png b/app/assets/images/emoji/spider.png Binary files differnew file mode 100644 index 00000000000..3849fa90b94 --- /dev/null +++ b/app/assets/images/emoji/spider.png diff --git a/app/assets/images/emoji/spider_web.png b/app/assets/images/emoji/spider_web.png Binary files differnew file mode 100644 index 00000000000..ba448ee7fba --- /dev/null +++ b/app/assets/images/emoji/spider_web.png diff --git a/app/assets/images/emoji/spoon.png b/app/assets/images/emoji/spoon.png Binary files differnew file mode 100644 index 00000000000..3c4da766aee --- /dev/null +++ b/app/assets/images/emoji/spoon.png diff --git a/app/assets/images/emoji/spy.png b/app/assets/images/emoji/spy.png Binary files differnew file mode 100644 index 00000000000..a729e9584d6 --- /dev/null +++ b/app/assets/images/emoji/spy.png diff --git a/app/assets/images/emoji/spy_tone1.png b/app/assets/images/emoji/spy_tone1.png Binary files differnew file mode 100644 index 00000000000..2d1c022caee --- /dev/null +++ b/app/assets/images/emoji/spy_tone1.png diff --git a/app/assets/images/emoji/spy_tone2.png b/app/assets/images/emoji/spy_tone2.png Binary files differnew file mode 100644 index 00000000000..548b9c26f5d --- /dev/null +++ b/app/assets/images/emoji/spy_tone2.png diff --git a/app/assets/images/emoji/spy_tone3.png b/app/assets/images/emoji/spy_tone3.png Binary files differnew file mode 100644 index 00000000000..b023f4b18e1 --- /dev/null +++ b/app/assets/images/emoji/spy_tone3.png diff --git a/app/assets/images/emoji/spy_tone4.png b/app/assets/images/emoji/spy_tone4.png Binary files differnew file mode 100644 index 00000000000..d8300af492d --- /dev/null +++ b/app/assets/images/emoji/spy_tone4.png diff --git a/app/assets/images/emoji/spy_tone5.png b/app/assets/images/emoji/spy_tone5.png Binary files differnew file mode 100644 index 00000000000..ca1462595fa --- /dev/null +++ b/app/assets/images/emoji/spy_tone5.png diff --git a/app/assets/images/emoji/squid.png b/app/assets/images/emoji/squid.png Binary files differnew file mode 100644 index 00000000000..d2af223f0cb --- /dev/null +++ b/app/assets/images/emoji/squid.png diff --git a/app/assets/images/emoji/stadium.png b/app/assets/images/emoji/stadium.png Binary files differnew file mode 100644 index 00000000000..00cd6db5e29 --- /dev/null +++ b/app/assets/images/emoji/stadium.png diff --git a/app/assets/images/emoji/star.png b/app/assets/images/emoji/star.png Binary files differnew file mode 100644 index 00000000000..c930947076e --- /dev/null +++ b/app/assets/images/emoji/star.png diff --git a/app/assets/images/emoji/star2.png b/app/assets/images/emoji/star2.png Binary files differnew file mode 100644 index 00000000000..2f5cba592db --- /dev/null +++ b/app/assets/images/emoji/star2.png diff --git a/app/assets/images/emoji/star_and_crescent.png b/app/assets/images/emoji/star_and_crescent.png Binary files differnew file mode 100644 index 00000000000..e182636457d --- /dev/null +++ b/app/assets/images/emoji/star_and_crescent.png diff --git a/app/assets/images/emoji/star_of_david.png b/app/assets/images/emoji/star_of_david.png Binary files differnew file mode 100644 index 00000000000..fc59d0dde24 --- /dev/null +++ b/app/assets/images/emoji/star_of_david.png diff --git a/app/assets/images/emoji/stars.png b/app/assets/images/emoji/stars.png Binary files differnew file mode 100644 index 00000000000..aa45384d1c6 --- /dev/null +++ b/app/assets/images/emoji/stars.png diff --git a/app/assets/images/emoji/station.png b/app/assets/images/emoji/station.png Binary files differnew file mode 100644 index 00000000000..5c26fee529c --- /dev/null +++ b/app/assets/images/emoji/station.png diff --git a/app/assets/images/emoji/statue_of_liberty.png b/app/assets/images/emoji/statue_of_liberty.png Binary files differnew file mode 100644 index 00000000000..05df8289b59 --- /dev/null +++ b/app/assets/images/emoji/statue_of_liberty.png diff --git a/app/assets/images/emoji/steam_locomotive.png b/app/assets/images/emoji/steam_locomotive.png Binary files differnew file mode 100644 index 00000000000..9ac0d999c4c --- /dev/null +++ b/app/assets/images/emoji/steam_locomotive.png diff --git a/app/assets/images/emoji/stew.png b/app/assets/images/emoji/stew.png Binary files differnew file mode 100644 index 00000000000..6b3f010c17a --- /dev/null +++ b/app/assets/images/emoji/stew.png diff --git a/app/assets/images/emoji/stop_button.png b/app/assets/images/emoji/stop_button.png Binary files differnew file mode 100644 index 00000000000..cfa99988ac2 --- /dev/null +++ b/app/assets/images/emoji/stop_button.png diff --git a/app/assets/images/emoji/stopwatch.png b/app/assets/images/emoji/stopwatch.png Binary files differnew file mode 100644 index 00000000000..8fae1c9a898 --- /dev/null +++ b/app/assets/images/emoji/stopwatch.png diff --git a/app/assets/images/emoji/straight_ruler.png b/app/assets/images/emoji/straight_ruler.png Binary files differnew file mode 100644 index 00000000000..1017b7433a1 --- /dev/null +++ b/app/assets/images/emoji/straight_ruler.png diff --git a/app/assets/images/emoji/strawberry.png b/app/assets/images/emoji/strawberry.png Binary files differnew file mode 100644 index 00000000000..7bb86f0b29c --- /dev/null +++ b/app/assets/images/emoji/strawberry.png diff --git a/app/assets/images/emoji/stuck_out_tongue.png b/app/assets/images/emoji/stuck_out_tongue.png Binary files differnew file mode 100644 index 00000000000..25757341f96 --- /dev/null +++ b/app/assets/images/emoji/stuck_out_tongue.png diff --git a/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png b/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png Binary files differnew file mode 100644 index 00000000000..5c0401e9b1d --- /dev/null +++ b/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png diff --git a/app/assets/images/emoji/stuck_out_tongue_winking_eye.png b/app/assets/images/emoji/stuck_out_tongue_winking_eye.png Binary files differnew file mode 100644 index 00000000000..4817eaa3dc6 --- /dev/null +++ b/app/assets/images/emoji/stuck_out_tongue_winking_eye.png diff --git a/app/assets/images/emoji/stuffed_flatbread.png b/app/assets/images/emoji/stuffed_flatbread.png Binary files differnew file mode 100644 index 00000000000..a2e10df40a5 --- /dev/null +++ b/app/assets/images/emoji/stuffed_flatbread.png diff --git a/app/assets/images/emoji/sun_with_face.png b/app/assets/images/emoji/sun_with_face.png Binary files differnew file mode 100644 index 00000000000..14a4ea971db --- /dev/null +++ b/app/assets/images/emoji/sun_with_face.png diff --git a/app/assets/images/emoji/sunflower.png b/app/assets/images/emoji/sunflower.png Binary files differnew file mode 100644 index 00000000000..08cc07761ea --- /dev/null +++ b/app/assets/images/emoji/sunflower.png diff --git a/app/assets/images/emoji/sunglasses.png b/app/assets/images/emoji/sunglasses.png Binary files differnew file mode 100644 index 00000000000..20011735110 --- /dev/null +++ b/app/assets/images/emoji/sunglasses.png diff --git a/app/assets/images/emoji/sunny.png b/app/assets/images/emoji/sunny.png Binary files differnew file mode 100644 index 00000000000..fd521ae31a7 --- /dev/null +++ b/app/assets/images/emoji/sunny.png diff --git a/app/assets/images/emoji/sunrise.png b/app/assets/images/emoji/sunrise.png Binary files differnew file mode 100644 index 00000000000..4ad36003c20 --- /dev/null +++ b/app/assets/images/emoji/sunrise.png diff --git a/app/assets/images/emoji/sunrise_over_mountains.png b/app/assets/images/emoji/sunrise_over_mountains.png Binary files differnew file mode 100644 index 00000000000..2b99307344d --- /dev/null +++ b/app/assets/images/emoji/sunrise_over_mountains.png diff --git a/app/assets/images/emoji/surfer.png b/app/assets/images/emoji/surfer.png Binary files differnew file mode 100644 index 00000000000..3ab017adf4b --- /dev/null +++ b/app/assets/images/emoji/surfer.png diff --git a/app/assets/images/emoji/surfer_tone1.png b/app/assets/images/emoji/surfer_tone1.png Binary files differnew file mode 100644 index 00000000000..b5faaa524cc --- /dev/null +++ b/app/assets/images/emoji/surfer_tone1.png diff --git a/app/assets/images/emoji/surfer_tone2.png b/app/assets/images/emoji/surfer_tone2.png Binary files differnew file mode 100644 index 00000000000..6d92e412ff1 --- /dev/null +++ b/app/assets/images/emoji/surfer_tone2.png diff --git a/app/assets/images/emoji/surfer_tone3.png b/app/assets/images/emoji/surfer_tone3.png Binary files differnew file mode 100644 index 00000000000..f05ef59496e --- /dev/null +++ b/app/assets/images/emoji/surfer_tone3.png diff --git a/app/assets/images/emoji/surfer_tone4.png b/app/assets/images/emoji/surfer_tone4.png Binary files differnew file mode 100644 index 00000000000..35e143d19dc --- /dev/null +++ b/app/assets/images/emoji/surfer_tone4.png diff --git a/app/assets/images/emoji/surfer_tone5.png b/app/assets/images/emoji/surfer_tone5.png Binary files differnew file mode 100644 index 00000000000..38917658eac --- /dev/null +++ b/app/assets/images/emoji/surfer_tone5.png diff --git a/app/assets/images/emoji/sushi.png b/app/assets/images/emoji/sushi.png Binary files differnew file mode 100644 index 00000000000..f171fd2f7a1 --- /dev/null +++ b/app/assets/images/emoji/sushi.png diff --git a/app/assets/images/emoji/suspension_railway.png b/app/assets/images/emoji/suspension_railway.png Binary files differnew file mode 100644 index 00000000000..a59d5f48c24 --- /dev/null +++ b/app/assets/images/emoji/suspension_railway.png diff --git a/app/assets/images/emoji/sweat.png b/app/assets/images/emoji/sweat.png Binary files differnew file mode 100644 index 00000000000..f0dae7b7893 --- /dev/null +++ b/app/assets/images/emoji/sweat.png diff --git a/app/assets/images/emoji/sweat_drops.png b/app/assets/images/emoji/sweat_drops.png Binary files differnew file mode 100644 index 00000000000..4106117ebc8 --- /dev/null +++ b/app/assets/images/emoji/sweat_drops.png diff --git a/app/assets/images/emoji/sweat_smile.png b/app/assets/images/emoji/sweat_smile.png Binary files differnew file mode 100644 index 00000000000..cb18d9c899b --- /dev/null +++ b/app/assets/images/emoji/sweat_smile.png diff --git a/app/assets/images/emoji/sweet_potato.png b/app/assets/images/emoji/sweet_potato.png Binary files differnew file mode 100644 index 00000000000..92a425f2e20 --- /dev/null +++ b/app/assets/images/emoji/sweet_potato.png diff --git a/app/assets/images/emoji/swimmer.png b/app/assets/images/emoji/swimmer.png Binary files differnew file mode 100644 index 00000000000..55b4d72f9a7 --- /dev/null +++ b/app/assets/images/emoji/swimmer.png diff --git a/app/assets/images/emoji/swimmer_tone1.png b/app/assets/images/emoji/swimmer_tone1.png Binary files differnew file mode 100644 index 00000000000..38441c9ca9a --- /dev/null +++ b/app/assets/images/emoji/swimmer_tone1.png diff --git a/app/assets/images/emoji/swimmer_tone2.png b/app/assets/images/emoji/swimmer_tone2.png Binary files differnew file mode 100644 index 00000000000..b0d43112444 --- /dev/null +++ b/app/assets/images/emoji/swimmer_tone2.png diff --git a/app/assets/images/emoji/swimmer_tone3.png b/app/assets/images/emoji/swimmer_tone3.png Binary files differnew file mode 100644 index 00000000000..211e77e2aa0 --- /dev/null +++ b/app/assets/images/emoji/swimmer_tone3.png diff --git a/app/assets/images/emoji/swimmer_tone4.png b/app/assets/images/emoji/swimmer_tone4.png Binary files differnew file mode 100644 index 00000000000..f34c34db9d2 --- /dev/null +++ b/app/assets/images/emoji/swimmer_tone4.png diff --git a/app/assets/images/emoji/swimmer_tone5.png b/app/assets/images/emoji/swimmer_tone5.png Binary files differnew file mode 100644 index 00000000000..3e9231ff868 --- /dev/null +++ b/app/assets/images/emoji/swimmer_tone5.png diff --git a/app/assets/images/emoji/symbols.png b/app/assets/images/emoji/symbols.png Binary files differnew file mode 100644 index 00000000000..ac2fc1f358f --- /dev/null +++ b/app/assets/images/emoji/symbols.png diff --git a/app/assets/images/emoji/synagogue.png b/app/assets/images/emoji/synagogue.png Binary files differnew file mode 100644 index 00000000000..ee347904c80 --- /dev/null +++ b/app/assets/images/emoji/synagogue.png diff --git a/app/assets/images/emoji/syringe.png b/app/assets/images/emoji/syringe.png Binary files differnew file mode 100644 index 00000000000..71c1a9528d5 --- /dev/null +++ b/app/assets/images/emoji/syringe.png diff --git a/app/assets/images/emoji/taco.png b/app/assets/images/emoji/taco.png Binary files differnew file mode 100644 index 00000000000..10e847a4619 --- /dev/null +++ b/app/assets/images/emoji/taco.png diff --git a/app/assets/images/emoji/tada.png b/app/assets/images/emoji/tada.png Binary files differnew file mode 100644 index 00000000000..0244d60f269 --- /dev/null +++ b/app/assets/images/emoji/tada.png diff --git a/app/assets/images/emoji/tanabata_tree.png b/app/assets/images/emoji/tanabata_tree.png Binary files differnew file mode 100644 index 00000000000..46fcb3a1aac --- /dev/null +++ b/app/assets/images/emoji/tanabata_tree.png diff --git a/app/assets/images/emoji/tangerine.png b/app/assets/images/emoji/tangerine.png Binary files differnew file mode 100644 index 00000000000..ab14e5378db --- /dev/null +++ b/app/assets/images/emoji/tangerine.png diff --git a/app/assets/images/emoji/taurus.png b/app/assets/images/emoji/taurus.png Binary files differnew file mode 100644 index 00000000000..b2a370df42b --- /dev/null +++ b/app/assets/images/emoji/taurus.png diff --git a/app/assets/images/emoji/taxi.png b/app/assets/images/emoji/taxi.png Binary files differnew file mode 100644 index 00000000000..55f4cc84797 --- /dev/null +++ b/app/assets/images/emoji/taxi.png diff --git a/app/assets/images/emoji/tea.png b/app/assets/images/emoji/tea.png Binary files differnew file mode 100644 index 00000000000..b53b98f0c45 --- /dev/null +++ b/app/assets/images/emoji/tea.png diff --git a/app/assets/images/emoji/telephone.png b/app/assets/images/emoji/telephone.png Binary files differnew file mode 100644 index 00000000000..a1e69f566bc --- /dev/null +++ b/app/assets/images/emoji/telephone.png diff --git a/app/assets/images/emoji/telephone_receiver.png b/app/assets/images/emoji/telephone_receiver.png Binary files differnew file mode 100644 index 00000000000..69388316c35 --- /dev/null +++ b/app/assets/images/emoji/telephone_receiver.png diff --git a/app/assets/images/emoji/telescope.png b/app/assets/images/emoji/telescope.png Binary files differnew file mode 100644 index 00000000000..d63154614b5 --- /dev/null +++ b/app/assets/images/emoji/telescope.png diff --git a/app/assets/images/emoji/ten.png b/app/assets/images/emoji/ten.png Binary files differnew file mode 100644 index 00000000000..782d4004962 --- /dev/null +++ b/app/assets/images/emoji/ten.png diff --git a/app/assets/images/emoji/tennis.png b/app/assets/images/emoji/tennis.png Binary files differnew file mode 100644 index 00000000000..7e68ba8f301 --- /dev/null +++ b/app/assets/images/emoji/tennis.png diff --git a/app/assets/images/emoji/tent.png b/app/assets/images/emoji/tent.png Binary files differnew file mode 100644 index 00000000000..3fddcfc56eb --- /dev/null +++ b/app/assets/images/emoji/tent.png diff --git a/app/assets/images/emoji/thermometer.png b/app/assets/images/emoji/thermometer.png Binary files differnew file mode 100644 index 00000000000..b1147392426 --- /dev/null +++ b/app/assets/images/emoji/thermometer.png diff --git a/app/assets/images/emoji/thermometer_face.png b/app/assets/images/emoji/thermometer_face.png Binary files differnew file mode 100644 index 00000000000..8fc57387563 --- /dev/null +++ b/app/assets/images/emoji/thermometer_face.png diff --git a/app/assets/images/emoji/thinking.png b/app/assets/images/emoji/thinking.png Binary files differnew file mode 100644 index 00000000000..c18f6fd14ad --- /dev/null +++ b/app/assets/images/emoji/thinking.png diff --git a/app/assets/images/emoji/third_place.png b/app/assets/images/emoji/third_place.png Binary files differnew file mode 100644 index 00000000000..636e04a5950 --- /dev/null +++ b/app/assets/images/emoji/third_place.png diff --git a/app/assets/images/emoji/thought_balloon.png b/app/assets/images/emoji/thought_balloon.png Binary files differnew file mode 100644 index 00000000000..72fe8fa7022 --- /dev/null +++ b/app/assets/images/emoji/thought_balloon.png diff --git a/app/assets/images/emoji/three.png b/app/assets/images/emoji/three.png Binary files differnew file mode 100644 index 00000000000..dbaa6183e72 --- /dev/null +++ b/app/assets/images/emoji/three.png diff --git a/app/assets/images/emoji/thumbsdown.png b/app/assets/images/emoji/thumbsdown.png Binary files differnew file mode 100644 index 00000000000..b63da2f20a8 --- /dev/null +++ b/app/assets/images/emoji/thumbsdown.png diff --git a/app/assets/images/emoji/thumbsdown_tone1.png b/app/assets/images/emoji/thumbsdown_tone1.png Binary files differnew file mode 100644 index 00000000000..a1631af8e92 --- /dev/null +++ b/app/assets/images/emoji/thumbsdown_tone1.png diff --git a/app/assets/images/emoji/thumbsdown_tone2.png b/app/assets/images/emoji/thumbsdown_tone2.png Binary files differnew file mode 100644 index 00000000000..85fff82d595 --- /dev/null +++ b/app/assets/images/emoji/thumbsdown_tone2.png diff --git a/app/assets/images/emoji/thumbsdown_tone3.png b/app/assets/images/emoji/thumbsdown_tone3.png Binary files differnew file mode 100644 index 00000000000..eeba3be80fd --- /dev/null +++ b/app/assets/images/emoji/thumbsdown_tone3.png diff --git a/app/assets/images/emoji/thumbsdown_tone4.png b/app/assets/images/emoji/thumbsdown_tone4.png Binary files differnew file mode 100644 index 00000000000..1addafdaed0 --- /dev/null +++ b/app/assets/images/emoji/thumbsdown_tone4.png diff --git a/app/assets/images/emoji/thumbsdown_tone5.png b/app/assets/images/emoji/thumbsdown_tone5.png Binary files differnew file mode 100644 index 00000000000..37ec07b5721 --- /dev/null +++ b/app/assets/images/emoji/thumbsdown_tone5.png diff --git a/app/assets/images/emoji/thumbsup.png b/app/assets/images/emoji/thumbsup.png Binary files differnew file mode 100644 index 00000000000..f9e6f13a34f --- /dev/null +++ b/app/assets/images/emoji/thumbsup.png diff --git a/app/assets/images/emoji/thumbsup_tone1.png b/app/assets/images/emoji/thumbsup_tone1.png Binary files differnew file mode 100644 index 00000000000..39684cd5cc7 --- /dev/null +++ b/app/assets/images/emoji/thumbsup_tone1.png diff --git a/app/assets/images/emoji/thumbsup_tone2.png b/app/assets/images/emoji/thumbsup_tone2.png Binary files differnew file mode 100644 index 00000000000..a9b59723573 --- /dev/null +++ b/app/assets/images/emoji/thumbsup_tone2.png diff --git a/app/assets/images/emoji/thumbsup_tone3.png b/app/assets/images/emoji/thumbsup_tone3.png Binary files differnew file mode 100644 index 00000000000..c5e29167015 --- /dev/null +++ b/app/assets/images/emoji/thumbsup_tone3.png diff --git a/app/assets/images/emoji/thumbsup_tone4.png b/app/assets/images/emoji/thumbsup_tone4.png Binary files differnew file mode 100644 index 00000000000..5bf4857a884 --- /dev/null +++ b/app/assets/images/emoji/thumbsup_tone4.png diff --git a/app/assets/images/emoji/thumbsup_tone5.png b/app/assets/images/emoji/thumbsup_tone5.png Binary files differnew file mode 100644 index 00000000000..d829f787c61 --- /dev/null +++ b/app/assets/images/emoji/thumbsup_tone5.png diff --git a/app/assets/images/emoji/thunder_cloud_rain.png b/app/assets/images/emoji/thunder_cloud_rain.png Binary files differnew file mode 100644 index 00000000000..31a26a1b6ee --- /dev/null +++ b/app/assets/images/emoji/thunder_cloud_rain.png diff --git a/app/assets/images/emoji/ticket.png b/app/assets/images/emoji/ticket.png Binary files differnew file mode 100644 index 00000000000..605936bb6b3 --- /dev/null +++ b/app/assets/images/emoji/ticket.png diff --git a/app/assets/images/emoji/tickets.png b/app/assets/images/emoji/tickets.png Binary files differnew file mode 100644 index 00000000000..e510f4a7a50 --- /dev/null +++ b/app/assets/images/emoji/tickets.png diff --git a/app/assets/images/emoji/tiger.png b/app/assets/images/emoji/tiger.png Binary files differnew file mode 100644 index 00000000000..a4d3ef086d4 --- /dev/null +++ b/app/assets/images/emoji/tiger.png diff --git a/app/assets/images/emoji/tiger2.png b/app/assets/images/emoji/tiger2.png Binary files differnew file mode 100644 index 00000000000..871a8b74d56 --- /dev/null +++ b/app/assets/images/emoji/tiger2.png diff --git a/app/assets/images/emoji/timer.png b/app/assets/images/emoji/timer.png Binary files differnew file mode 100644 index 00000000000..8a3be574c24 --- /dev/null +++ b/app/assets/images/emoji/timer.png diff --git a/app/assets/images/emoji/tired_face.png b/app/assets/images/emoji/tired_face.png Binary files differnew file mode 100644 index 00000000000..4e01eff5b23 --- /dev/null +++ b/app/assets/images/emoji/tired_face.png diff --git a/app/assets/images/emoji/tm.png b/app/assets/images/emoji/tm.png Binary files differnew file mode 100644 index 00000000000..7a0c44a2c2b --- /dev/null +++ b/app/assets/images/emoji/tm.png diff --git a/app/assets/images/emoji/toilet.png b/app/assets/images/emoji/toilet.png Binary files differnew file mode 100644 index 00000000000..1392f761835 --- /dev/null +++ b/app/assets/images/emoji/toilet.png diff --git a/app/assets/images/emoji/tokyo_tower.png b/app/assets/images/emoji/tokyo_tower.png Binary files differnew file mode 100644 index 00000000000..37df7fc65b1 --- /dev/null +++ b/app/assets/images/emoji/tokyo_tower.png diff --git a/app/assets/images/emoji/tomato.png b/app/assets/images/emoji/tomato.png Binary files differnew file mode 100644 index 00000000000..497da8f6b22 --- /dev/null +++ b/app/assets/images/emoji/tomato.png diff --git a/app/assets/images/emoji/tone1.png b/app/assets/images/emoji/tone1.png Binary files differnew file mode 100644 index 00000000000..c395f3d0d68 --- /dev/null +++ b/app/assets/images/emoji/tone1.png diff --git a/app/assets/images/emoji/tone2.png b/app/assets/images/emoji/tone2.png Binary files differnew file mode 100644 index 00000000000..080847431c1 --- /dev/null +++ b/app/assets/images/emoji/tone2.png diff --git a/app/assets/images/emoji/tone3.png b/app/assets/images/emoji/tone3.png Binary files differnew file mode 100644 index 00000000000..482dd403475 --- /dev/null +++ b/app/assets/images/emoji/tone3.png diff --git a/app/assets/images/emoji/tone4.png b/app/assets/images/emoji/tone4.png Binary files differnew file mode 100644 index 00000000000..5cae8bb20b0 --- /dev/null +++ b/app/assets/images/emoji/tone4.png diff --git a/app/assets/images/emoji/tone5.png b/app/assets/images/emoji/tone5.png Binary files differnew file mode 100644 index 00000000000..49d1a8c3a64 --- /dev/null +++ b/app/assets/images/emoji/tone5.png diff --git a/app/assets/images/emoji/tongue.png b/app/assets/images/emoji/tongue.png Binary files differnew file mode 100644 index 00000000000..70ce9c1225f --- /dev/null +++ b/app/assets/images/emoji/tongue.png diff --git a/app/assets/images/emoji/tools.png b/app/assets/images/emoji/tools.png Binary files differnew file mode 100644 index 00000000000..3c6049273a9 --- /dev/null +++ b/app/assets/images/emoji/tools.png diff --git a/app/assets/images/emoji/top.png b/app/assets/images/emoji/top.png Binary files differnew file mode 100644 index 00000000000..49dea8c08b5 --- /dev/null +++ b/app/assets/images/emoji/top.png diff --git a/app/assets/images/emoji/tophat.png b/app/assets/images/emoji/tophat.png Binary files differnew file mode 100644 index 00000000000..131b657b109 --- /dev/null +++ b/app/assets/images/emoji/tophat.png diff --git a/app/assets/images/emoji/track_next.png b/app/assets/images/emoji/track_next.png Binary files differnew file mode 100644 index 00000000000..f8880d33bab --- /dev/null +++ b/app/assets/images/emoji/track_next.png diff --git a/app/assets/images/emoji/track_previous.png b/app/assets/images/emoji/track_previous.png Binary files differnew file mode 100644 index 00000000000..1ffd0566cfc --- /dev/null +++ b/app/assets/images/emoji/track_previous.png diff --git a/app/assets/images/emoji/trackball.png b/app/assets/images/emoji/trackball.png Binary files differnew file mode 100644 index 00000000000..3bea84ad7ce --- /dev/null +++ b/app/assets/images/emoji/trackball.png diff --git a/app/assets/images/emoji/tractor.png b/app/assets/images/emoji/tractor.png Binary files differnew file mode 100644 index 00000000000..c1bf8cae44f --- /dev/null +++ b/app/assets/images/emoji/tractor.png diff --git a/app/assets/images/emoji/traffic_light.png b/app/assets/images/emoji/traffic_light.png Binary files differnew file mode 100644 index 00000000000..6b312285b00 --- /dev/null +++ b/app/assets/images/emoji/traffic_light.png diff --git a/app/assets/images/emoji/train.png b/app/assets/images/emoji/train.png Binary files differnew file mode 100644 index 00000000000..3c80321f7e8 --- /dev/null +++ b/app/assets/images/emoji/train.png diff --git a/app/assets/images/emoji/train2.png b/app/assets/images/emoji/train2.png Binary files differnew file mode 100644 index 00000000000..367c7bc5d39 --- /dev/null +++ b/app/assets/images/emoji/train2.png diff --git a/app/assets/images/emoji/tram.png b/app/assets/images/emoji/tram.png Binary files differnew file mode 100644 index 00000000000..b6f0e69038f --- /dev/null +++ b/app/assets/images/emoji/tram.png diff --git a/app/assets/images/emoji/triangular_flag_on_post.png b/app/assets/images/emoji/triangular_flag_on_post.png Binary files differnew file mode 100644 index 00000000000..c12d8b06886 --- /dev/null +++ b/app/assets/images/emoji/triangular_flag_on_post.png diff --git a/app/assets/images/emoji/triangular_ruler.png b/app/assets/images/emoji/triangular_ruler.png Binary files differnew file mode 100644 index 00000000000..77dee9ee843 --- /dev/null +++ b/app/assets/images/emoji/triangular_ruler.png diff --git a/app/assets/images/emoji/trident.png b/app/assets/images/emoji/trident.png Binary files differnew file mode 100644 index 00000000000..777a1dad121 --- /dev/null +++ b/app/assets/images/emoji/trident.png diff --git a/app/assets/images/emoji/triumph.png b/app/assets/images/emoji/triumph.png Binary files differnew file mode 100644 index 00000000000..0be7a501969 --- /dev/null +++ b/app/assets/images/emoji/triumph.png diff --git a/app/assets/images/emoji/trolleybus.png b/app/assets/images/emoji/trolleybus.png Binary files differnew file mode 100644 index 00000000000..139a9931b52 --- /dev/null +++ b/app/assets/images/emoji/trolleybus.png diff --git a/app/assets/images/emoji/trophy.png b/app/assets/images/emoji/trophy.png Binary files differnew file mode 100644 index 00000000000..ac2895c1896 --- /dev/null +++ b/app/assets/images/emoji/trophy.png diff --git a/app/assets/images/emoji/tropical_drink.png b/app/assets/images/emoji/tropical_drink.png Binary files differnew file mode 100644 index 00000000000..cd714f81b36 --- /dev/null +++ b/app/assets/images/emoji/tropical_drink.png diff --git a/app/assets/images/emoji/tropical_fish.png b/app/assets/images/emoji/tropical_fish.png Binary files differnew file mode 100644 index 00000000000..252105235a6 --- /dev/null +++ b/app/assets/images/emoji/tropical_fish.png diff --git a/app/assets/images/emoji/truck.png b/app/assets/images/emoji/truck.png Binary files differnew file mode 100644 index 00000000000..130de047f8b --- /dev/null +++ b/app/assets/images/emoji/truck.png diff --git a/app/assets/images/emoji/trumpet.png b/app/assets/images/emoji/trumpet.png Binary files differnew file mode 100644 index 00000000000..864ccbcd04a --- /dev/null +++ b/app/assets/images/emoji/trumpet.png diff --git a/app/assets/images/emoji/tulip.png b/app/assets/images/emoji/tulip.png Binary files differnew file mode 100644 index 00000000000..f799d75c182 --- /dev/null +++ b/app/assets/images/emoji/tulip.png diff --git a/app/assets/images/emoji/tumbler_glass.png b/app/assets/images/emoji/tumbler_glass.png Binary files differnew file mode 100644 index 00000000000..7bf09229879 --- /dev/null +++ b/app/assets/images/emoji/tumbler_glass.png diff --git a/app/assets/images/emoji/turkey.png b/app/assets/images/emoji/turkey.png Binary files differnew file mode 100644 index 00000000000..344af94c9ec --- /dev/null +++ b/app/assets/images/emoji/turkey.png diff --git a/app/assets/images/emoji/turtle.png b/app/assets/images/emoji/turtle.png Binary files differnew file mode 100644 index 00000000000..c22f7519fe8 --- /dev/null +++ b/app/assets/images/emoji/turtle.png diff --git a/app/assets/images/emoji/tv.png b/app/assets/images/emoji/tv.png Binary files differnew file mode 100644 index 00000000000..999f1fb5c6d --- /dev/null +++ b/app/assets/images/emoji/tv.png diff --git a/app/assets/images/emoji/twisted_rightwards_arrows.png b/app/assets/images/emoji/twisted_rightwards_arrows.png Binary files differnew file mode 100644 index 00000000000..5904badde65 --- /dev/null +++ b/app/assets/images/emoji/twisted_rightwards_arrows.png diff --git a/app/assets/images/emoji/two.png b/app/assets/images/emoji/two.png Binary files differnew file mode 100644 index 00000000000..927339c9bff --- /dev/null +++ b/app/assets/images/emoji/two.png diff --git a/app/assets/images/emoji/two_hearts.png b/app/assets/images/emoji/two_hearts.png Binary files differnew file mode 100644 index 00000000000..4d8c3386042 --- /dev/null +++ b/app/assets/images/emoji/two_hearts.png diff --git a/app/assets/images/emoji/two_men_holding_hands.png b/app/assets/images/emoji/two_men_holding_hands.png Binary files differnew file mode 100644 index 00000000000..a511fda822a --- /dev/null +++ b/app/assets/images/emoji/two_men_holding_hands.png diff --git a/app/assets/images/emoji/two_women_holding_hands.png b/app/assets/images/emoji/two_women_holding_hands.png Binary files differnew file mode 100644 index 00000000000..b077cd3e40f --- /dev/null +++ b/app/assets/images/emoji/two_women_holding_hands.png diff --git a/app/assets/images/emoji/u5272.png b/app/assets/images/emoji/u5272.png Binary files differnew file mode 100644 index 00000000000..c4f837fe684 --- /dev/null +++ b/app/assets/images/emoji/u5272.png diff --git a/app/assets/images/emoji/u5408.png b/app/assets/images/emoji/u5408.png Binary files differnew file mode 100644 index 00000000000..8375ad9d9af --- /dev/null +++ b/app/assets/images/emoji/u5408.png diff --git a/app/assets/images/emoji/u55b6.png b/app/assets/images/emoji/u55b6.png Binary files differnew file mode 100644 index 00000000000..d21cb30eaf3 --- /dev/null +++ b/app/assets/images/emoji/u55b6.png diff --git a/app/assets/images/emoji/u6307.png b/app/assets/images/emoji/u6307.png Binary files differnew file mode 100644 index 00000000000..078e23e4ff3 --- /dev/null +++ b/app/assets/images/emoji/u6307.png diff --git a/app/assets/images/emoji/u6708.png b/app/assets/images/emoji/u6708.png Binary files differnew file mode 100644 index 00000000000..c41bd36a26a --- /dev/null +++ b/app/assets/images/emoji/u6708.png diff --git a/app/assets/images/emoji/u6709.png b/app/assets/images/emoji/u6709.png Binary files differnew file mode 100644 index 00000000000..a4510de41c0 --- /dev/null +++ b/app/assets/images/emoji/u6709.png diff --git a/app/assets/images/emoji/u6e80.png b/app/assets/images/emoji/u6e80.png Binary files differnew file mode 100644 index 00000000000..f9dea8b8833 --- /dev/null +++ b/app/assets/images/emoji/u6e80.png diff --git a/app/assets/images/emoji/u7121.png b/app/assets/images/emoji/u7121.png Binary files differnew file mode 100644 index 00000000000..d3a19b420de --- /dev/null +++ b/app/assets/images/emoji/u7121.png diff --git a/app/assets/images/emoji/u7533.png b/app/assets/images/emoji/u7533.png Binary files differnew file mode 100644 index 00000000000..6b7af0ee222 --- /dev/null +++ b/app/assets/images/emoji/u7533.png diff --git a/app/assets/images/emoji/u7981.png b/app/assets/images/emoji/u7981.png Binary files differnew file mode 100644 index 00000000000..4c704e03433 --- /dev/null +++ b/app/assets/images/emoji/u7981.png diff --git a/app/assets/images/emoji/u7a7a.png b/app/assets/images/emoji/u7a7a.png Binary files differnew file mode 100644 index 00000000000..47966c1ea93 --- /dev/null +++ b/app/assets/images/emoji/u7a7a.png diff --git a/app/assets/images/emoji/umbrella.png b/app/assets/images/emoji/umbrella.png Binary files differnew file mode 100644 index 00000000000..5b35b7ff6a4 --- /dev/null +++ b/app/assets/images/emoji/umbrella.png diff --git a/app/assets/images/emoji/umbrella2.png b/app/assets/images/emoji/umbrella2.png Binary files differnew file mode 100644 index 00000000000..97fe859e74f --- /dev/null +++ b/app/assets/images/emoji/umbrella2.png diff --git a/app/assets/images/emoji/unamused.png b/app/assets/images/emoji/unamused.png Binary files differnew file mode 100644 index 00000000000..25e3677f2eb --- /dev/null +++ b/app/assets/images/emoji/unamused.png diff --git a/app/assets/images/emoji/underage.png b/app/assets/images/emoji/underage.png Binary files differnew file mode 100644 index 00000000000..6dfe6da51e2 --- /dev/null +++ b/app/assets/images/emoji/underage.png diff --git a/app/assets/images/emoji/unicorn.png b/app/assets/images/emoji/unicorn.png Binary files differnew file mode 100644 index 00000000000..05a97969f7e --- /dev/null +++ b/app/assets/images/emoji/unicorn.png diff --git a/app/assets/images/emoji/unlock.png b/app/assets/images/emoji/unlock.png Binary files differnew file mode 100644 index 00000000000..4a74a693911 --- /dev/null +++ b/app/assets/images/emoji/unlock.png diff --git a/app/assets/images/emoji/up.png b/app/assets/images/emoji/up.png Binary files differnew file mode 100644 index 00000000000..0d42142ba04 --- /dev/null +++ b/app/assets/images/emoji/up.png diff --git a/app/assets/images/emoji/upside_down.png b/app/assets/images/emoji/upside_down.png Binary files differnew file mode 100644 index 00000000000..128f31c9828 --- /dev/null +++ b/app/assets/images/emoji/upside_down.png diff --git a/app/assets/images/emoji/urn.png b/app/assets/images/emoji/urn.png Binary files differnew file mode 100644 index 00000000000..6b5b3503438 --- /dev/null +++ b/app/assets/images/emoji/urn.png diff --git a/app/assets/images/emoji/v.png b/app/assets/images/emoji/v.png Binary files differnew file mode 100644 index 00000000000..70c5516ffee --- /dev/null +++ b/app/assets/images/emoji/v.png diff --git a/app/assets/images/emoji/v_tone1.png b/app/assets/images/emoji/v_tone1.png Binary files differnew file mode 100644 index 00000000000..6ac54a745f4 --- /dev/null +++ b/app/assets/images/emoji/v_tone1.png diff --git a/app/assets/images/emoji/v_tone2.png b/app/assets/images/emoji/v_tone2.png Binary files differnew file mode 100644 index 00000000000..6dd9669866d --- /dev/null +++ b/app/assets/images/emoji/v_tone2.png diff --git a/app/assets/images/emoji/v_tone3.png b/app/assets/images/emoji/v_tone3.png Binary files differnew file mode 100644 index 00000000000..a615e53f02f --- /dev/null +++ b/app/assets/images/emoji/v_tone3.png diff --git a/app/assets/images/emoji/v_tone4.png b/app/assets/images/emoji/v_tone4.png Binary files differnew file mode 100644 index 00000000000..33a34bd5a78 --- /dev/null +++ b/app/assets/images/emoji/v_tone4.png diff --git a/app/assets/images/emoji/v_tone5.png b/app/assets/images/emoji/v_tone5.png Binary files differnew file mode 100644 index 00000000000..45ad14b6c9c --- /dev/null +++ b/app/assets/images/emoji/v_tone5.png diff --git a/app/assets/images/emoji/vertical_traffic_light.png b/app/assets/images/emoji/vertical_traffic_light.png Binary files differnew file mode 100644 index 00000000000..8085973eecf --- /dev/null +++ b/app/assets/images/emoji/vertical_traffic_light.png diff --git a/app/assets/images/emoji/vhs.png b/app/assets/images/emoji/vhs.png Binary files differnew file mode 100644 index 00000000000..b9eb78ecd92 --- /dev/null +++ b/app/assets/images/emoji/vhs.png diff --git a/app/assets/images/emoji/vibration_mode.png b/app/assets/images/emoji/vibration_mode.png Binary files differnew file mode 100644 index 00000000000..cc46510e48e --- /dev/null +++ b/app/assets/images/emoji/vibration_mode.png diff --git a/app/assets/images/emoji/video_camera.png b/app/assets/images/emoji/video_camera.png Binary files differnew file mode 100644 index 00000000000..85b300d425c --- /dev/null +++ b/app/assets/images/emoji/video_camera.png diff --git a/app/assets/images/emoji/video_game.png b/app/assets/images/emoji/video_game.png Binary files differnew file mode 100644 index 00000000000..316a9106a55 --- /dev/null +++ b/app/assets/images/emoji/video_game.png diff --git a/app/assets/images/emoji/violin.png b/app/assets/images/emoji/violin.png Binary files differnew file mode 100644 index 00000000000..e1e76cce242 --- /dev/null +++ b/app/assets/images/emoji/violin.png diff --git a/app/assets/images/emoji/virgo.png b/app/assets/images/emoji/virgo.png Binary files differnew file mode 100644 index 00000000000..a6b56c2cb5e --- /dev/null +++ b/app/assets/images/emoji/virgo.png diff --git a/app/assets/images/emoji/volcano.png b/app/assets/images/emoji/volcano.png Binary files differnew file mode 100644 index 00000000000..931d569294c --- /dev/null +++ b/app/assets/images/emoji/volcano.png diff --git a/app/assets/images/emoji/volleyball.png b/app/assets/images/emoji/volleyball.png Binary files differnew file mode 100644 index 00000000000..7a0e49d4b07 --- /dev/null +++ b/app/assets/images/emoji/volleyball.png diff --git a/app/assets/images/emoji/vs.png b/app/assets/images/emoji/vs.png Binary files differnew file mode 100644 index 00000000000..e1180f4a464 --- /dev/null +++ b/app/assets/images/emoji/vs.png diff --git a/app/assets/images/emoji/vulcan.png b/app/assets/images/emoji/vulcan.png Binary files differnew file mode 100644 index 00000000000..54728bcaf5c --- /dev/null +++ b/app/assets/images/emoji/vulcan.png diff --git a/app/assets/images/emoji/vulcan_tone1.png b/app/assets/images/emoji/vulcan_tone1.png Binary files differnew file mode 100644 index 00000000000..8aff5d8fa16 --- /dev/null +++ b/app/assets/images/emoji/vulcan_tone1.png diff --git a/app/assets/images/emoji/vulcan_tone2.png b/app/assets/images/emoji/vulcan_tone2.png Binary files differnew file mode 100644 index 00000000000..82b7ad519b4 --- /dev/null +++ b/app/assets/images/emoji/vulcan_tone2.png diff --git a/app/assets/images/emoji/vulcan_tone3.png b/app/assets/images/emoji/vulcan_tone3.png Binary files differnew file mode 100644 index 00000000000..d1400e1dd28 --- /dev/null +++ b/app/assets/images/emoji/vulcan_tone3.png diff --git a/app/assets/images/emoji/vulcan_tone4.png b/app/assets/images/emoji/vulcan_tone4.png Binary files differnew file mode 100644 index 00000000000..47e2b280148 --- /dev/null +++ b/app/assets/images/emoji/vulcan_tone4.png diff --git a/app/assets/images/emoji/vulcan_tone5.png b/app/assets/images/emoji/vulcan_tone5.png Binary files differnew file mode 100644 index 00000000000..60b5c6077be --- /dev/null +++ b/app/assets/images/emoji/vulcan_tone5.png diff --git a/app/assets/images/emoji/walking.png b/app/assets/images/emoji/walking.png Binary files differnew file mode 100644 index 00000000000..06dc169a3fd --- /dev/null +++ b/app/assets/images/emoji/walking.png diff --git a/app/assets/images/emoji/walking_tone1.png b/app/assets/images/emoji/walking_tone1.png Binary files differnew file mode 100644 index 00000000000..4e391b45a0b --- /dev/null +++ b/app/assets/images/emoji/walking_tone1.png diff --git a/app/assets/images/emoji/walking_tone2.png b/app/assets/images/emoji/walking_tone2.png Binary files differnew file mode 100644 index 00000000000..31f94a1bce1 --- /dev/null +++ b/app/assets/images/emoji/walking_tone2.png diff --git a/app/assets/images/emoji/walking_tone3.png b/app/assets/images/emoji/walking_tone3.png Binary files differnew file mode 100644 index 00000000000..f7ed8e39c2e --- /dev/null +++ b/app/assets/images/emoji/walking_tone3.png diff --git a/app/assets/images/emoji/walking_tone4.png b/app/assets/images/emoji/walking_tone4.png Binary files differnew file mode 100644 index 00000000000..e58dc04c7b2 --- /dev/null +++ b/app/assets/images/emoji/walking_tone4.png diff --git a/app/assets/images/emoji/walking_tone5.png b/app/assets/images/emoji/walking_tone5.png Binary files differnew file mode 100644 index 00000000000..ba4e1b58fcb --- /dev/null +++ b/app/assets/images/emoji/walking_tone5.png diff --git a/app/assets/images/emoji/waning_crescent_moon.png b/app/assets/images/emoji/waning_crescent_moon.png Binary files differnew file mode 100644 index 00000000000..cf68706b871 --- /dev/null +++ b/app/assets/images/emoji/waning_crescent_moon.png diff --git a/app/assets/images/emoji/waning_gibbous_moon.png b/app/assets/images/emoji/waning_gibbous_moon.png Binary files differnew file mode 100644 index 00000000000..24e16266119 --- /dev/null +++ b/app/assets/images/emoji/waning_gibbous_moon.png diff --git a/app/assets/images/emoji/warning.png b/app/assets/images/emoji/warning.png Binary files differnew file mode 100644 index 00000000000..35691c2ed97 --- /dev/null +++ b/app/assets/images/emoji/warning.png diff --git a/app/assets/images/emoji/wastebasket.png b/app/assets/images/emoji/wastebasket.png Binary files differnew file mode 100644 index 00000000000..2b3c484b498 --- /dev/null +++ b/app/assets/images/emoji/wastebasket.png diff --git a/app/assets/images/emoji/watch.png b/app/assets/images/emoji/watch.png Binary files differnew file mode 100644 index 00000000000..64819bc6e21 --- /dev/null +++ b/app/assets/images/emoji/watch.png diff --git a/app/assets/images/emoji/water_buffalo.png b/app/assets/images/emoji/water_buffalo.png Binary files differnew file mode 100644 index 00000000000..80446615caf --- /dev/null +++ b/app/assets/images/emoji/water_buffalo.png diff --git a/app/assets/images/emoji/water_polo.png b/app/assets/images/emoji/water_polo.png Binary files differnew file mode 100644 index 00000000000..cb44576780d --- /dev/null +++ b/app/assets/images/emoji/water_polo.png diff --git a/app/assets/images/emoji/water_polo_tone1.png b/app/assets/images/emoji/water_polo_tone1.png Binary files differnew file mode 100644 index 00000000000..bed1a908d6a --- /dev/null +++ b/app/assets/images/emoji/water_polo_tone1.png diff --git a/app/assets/images/emoji/water_polo_tone2.png b/app/assets/images/emoji/water_polo_tone2.png Binary files differnew file mode 100644 index 00000000000..ec5a43b4d4a --- /dev/null +++ b/app/assets/images/emoji/water_polo_tone2.png diff --git a/app/assets/images/emoji/water_polo_tone3.png b/app/assets/images/emoji/water_polo_tone3.png Binary files differnew file mode 100644 index 00000000000..b081a4a5a96 --- /dev/null +++ b/app/assets/images/emoji/water_polo_tone3.png diff --git a/app/assets/images/emoji/water_polo_tone4.png b/app/assets/images/emoji/water_polo_tone4.png Binary files differnew file mode 100644 index 00000000000..82cfbc3b0c7 --- /dev/null +++ b/app/assets/images/emoji/water_polo_tone4.png diff --git a/app/assets/images/emoji/water_polo_tone5.png b/app/assets/images/emoji/water_polo_tone5.png Binary files differnew file mode 100644 index 00000000000..bd3366eb06c --- /dev/null +++ b/app/assets/images/emoji/water_polo_tone5.png diff --git a/app/assets/images/emoji/watermelon.png b/app/assets/images/emoji/watermelon.png Binary files differnew file mode 100644 index 00000000000..0761488b4c9 --- /dev/null +++ b/app/assets/images/emoji/watermelon.png diff --git a/app/assets/images/emoji/wave.png b/app/assets/images/emoji/wave.png Binary files differnew file mode 100644 index 00000000000..e0cd79b45f5 --- /dev/null +++ b/app/assets/images/emoji/wave.png diff --git a/app/assets/images/emoji/wave_tone1.png b/app/assets/images/emoji/wave_tone1.png Binary files differnew file mode 100644 index 00000000000..6b2b34b106e --- /dev/null +++ b/app/assets/images/emoji/wave_tone1.png diff --git a/app/assets/images/emoji/wave_tone2.png b/app/assets/images/emoji/wave_tone2.png Binary files differnew file mode 100644 index 00000000000..b857119732e --- /dev/null +++ b/app/assets/images/emoji/wave_tone2.png diff --git a/app/assets/images/emoji/wave_tone3.png b/app/assets/images/emoji/wave_tone3.png Binary files differnew file mode 100644 index 00000000000..6283b670f43 --- /dev/null +++ b/app/assets/images/emoji/wave_tone3.png diff --git a/app/assets/images/emoji/wave_tone4.png b/app/assets/images/emoji/wave_tone4.png Binary files differnew file mode 100644 index 00000000000..fe6b2baa747 --- /dev/null +++ b/app/assets/images/emoji/wave_tone4.png diff --git a/app/assets/images/emoji/wave_tone5.png b/app/assets/images/emoji/wave_tone5.png Binary files differnew file mode 100644 index 00000000000..4bd168ebb78 --- /dev/null +++ b/app/assets/images/emoji/wave_tone5.png diff --git a/app/assets/images/emoji/wavy_dash.png b/app/assets/images/emoji/wavy_dash.png Binary files differnew file mode 100644 index 00000000000..001c8d6e47d --- /dev/null +++ b/app/assets/images/emoji/wavy_dash.png diff --git a/app/assets/images/emoji/waxing_crescent_moon.png b/app/assets/images/emoji/waxing_crescent_moon.png Binary files differnew file mode 100644 index 00000000000..687125173d9 --- /dev/null +++ b/app/assets/images/emoji/waxing_crescent_moon.png diff --git a/app/assets/images/emoji/waxing_gibbous_moon.png b/app/assets/images/emoji/waxing_gibbous_moon.png Binary files differnew file mode 100644 index 00000000000..3a808156318 --- /dev/null +++ b/app/assets/images/emoji/waxing_gibbous_moon.png diff --git a/app/assets/images/emoji/wc.png b/app/assets/images/emoji/wc.png Binary files differnew file mode 100644 index 00000000000..aa433e84ba6 --- /dev/null +++ b/app/assets/images/emoji/wc.png diff --git a/app/assets/images/emoji/weary.png b/app/assets/images/emoji/weary.png Binary files differnew file mode 100644 index 00000000000..98bfbd24a16 --- /dev/null +++ b/app/assets/images/emoji/weary.png diff --git a/app/assets/images/emoji/wedding.png b/app/assets/images/emoji/wedding.png Binary files differnew file mode 100644 index 00000000000..d0d8aa0bfae --- /dev/null +++ b/app/assets/images/emoji/wedding.png diff --git a/app/assets/images/emoji/whale.png b/app/assets/images/emoji/whale.png Binary files differnew file mode 100644 index 00000000000..9f19b44257c --- /dev/null +++ b/app/assets/images/emoji/whale.png diff --git a/app/assets/images/emoji/whale2.png b/app/assets/images/emoji/whale2.png Binary files differnew file mode 100644 index 00000000000..0df9d3c73a4 --- /dev/null +++ b/app/assets/images/emoji/whale2.png diff --git a/app/assets/images/emoji/wheel_of_dharma.png b/app/assets/images/emoji/wheel_of_dharma.png Binary files differnew file mode 100644 index 00000000000..3666db0016b --- /dev/null +++ b/app/assets/images/emoji/wheel_of_dharma.png diff --git a/app/assets/images/emoji/wheelchair.png b/app/assets/images/emoji/wheelchair.png Binary files differnew file mode 100644 index 00000000000..4e5b2698eac --- /dev/null +++ b/app/assets/images/emoji/wheelchair.png diff --git a/app/assets/images/emoji/white_check_mark.png b/app/assets/images/emoji/white_check_mark.png Binary files differnew file mode 100644 index 00000000000..e55f087e544 --- /dev/null +++ b/app/assets/images/emoji/white_check_mark.png diff --git a/app/assets/images/emoji/white_circle.png b/app/assets/images/emoji/white_circle.png Binary files differnew file mode 100644 index 00000000000..c19e15684dd --- /dev/null +++ b/app/assets/images/emoji/white_circle.png diff --git a/app/assets/images/emoji/white_flower.png b/app/assets/images/emoji/white_flower.png Binary files differnew file mode 100644 index 00000000000..d6af8b60077 --- /dev/null +++ b/app/assets/images/emoji/white_flower.png diff --git a/app/assets/images/emoji/white_large_square.png b/app/assets/images/emoji/white_large_square.png Binary files differnew file mode 100644 index 00000000000..6f06c1c79de --- /dev/null +++ b/app/assets/images/emoji/white_large_square.png diff --git a/app/assets/images/emoji/white_medium_small_square.png b/app/assets/images/emoji/white_medium_small_square.png Binary files differnew file mode 100644 index 00000000000..ae874126750 --- /dev/null +++ b/app/assets/images/emoji/white_medium_small_square.png diff --git a/app/assets/images/emoji/white_medium_square.png b/app/assets/images/emoji/white_medium_square.png Binary files differnew file mode 100644 index 00000000000..8daacf57059 --- /dev/null +++ b/app/assets/images/emoji/white_medium_square.png diff --git a/app/assets/images/emoji/white_small_square.png b/app/assets/images/emoji/white_small_square.png Binary files differnew file mode 100644 index 00000000000..d7ebdb0c0ed --- /dev/null +++ b/app/assets/images/emoji/white_small_square.png diff --git a/app/assets/images/emoji/white_square_button.png b/app/assets/images/emoji/white_square_button.png Binary files differnew file mode 100644 index 00000000000..934b1cedfd2 --- /dev/null +++ b/app/assets/images/emoji/white_square_button.png diff --git a/app/assets/images/emoji/white_sun_cloud.png b/app/assets/images/emoji/white_sun_cloud.png Binary files differnew file mode 100644 index 00000000000..0a4cc100269 --- /dev/null +++ b/app/assets/images/emoji/white_sun_cloud.png diff --git a/app/assets/images/emoji/white_sun_rain_cloud.png b/app/assets/images/emoji/white_sun_rain_cloud.png Binary files differnew file mode 100644 index 00000000000..491f9ca4839 --- /dev/null +++ b/app/assets/images/emoji/white_sun_rain_cloud.png diff --git a/app/assets/images/emoji/white_sun_small_cloud.png b/app/assets/images/emoji/white_sun_small_cloud.png Binary files differnew file mode 100644 index 00000000000..cead0bfa521 --- /dev/null +++ b/app/assets/images/emoji/white_sun_small_cloud.png diff --git a/app/assets/images/emoji/wilted_rose.png b/app/assets/images/emoji/wilted_rose.png Binary files differnew file mode 100644 index 00000000000..62412b143ae --- /dev/null +++ b/app/assets/images/emoji/wilted_rose.png diff --git a/app/assets/images/emoji/wind_blowing_face.png b/app/assets/images/emoji/wind_blowing_face.png Binary files differnew file mode 100644 index 00000000000..df81b652eb6 --- /dev/null +++ b/app/assets/images/emoji/wind_blowing_face.png diff --git a/app/assets/images/emoji/wind_chime.png b/app/assets/images/emoji/wind_chime.png Binary files differnew file mode 100644 index 00000000000..3c9ef3a95f6 --- /dev/null +++ b/app/assets/images/emoji/wind_chime.png diff --git a/app/assets/images/emoji/wine_glass.png b/app/assets/images/emoji/wine_glass.png Binary files differnew file mode 100644 index 00000000000..3cc98689192 --- /dev/null +++ b/app/assets/images/emoji/wine_glass.png diff --git a/app/assets/images/emoji/wink.png b/app/assets/images/emoji/wink.png Binary files differnew file mode 100644 index 00000000000..7ea7810a37d --- /dev/null +++ b/app/assets/images/emoji/wink.png diff --git a/app/assets/images/emoji/wolf.png b/app/assets/images/emoji/wolf.png Binary files differnew file mode 100644 index 00000000000..ba7220f2de9 --- /dev/null +++ b/app/assets/images/emoji/wolf.png diff --git a/app/assets/images/emoji/woman.png b/app/assets/images/emoji/woman.png Binary files differnew file mode 100644 index 00000000000..ece440e7a61 --- /dev/null +++ b/app/assets/images/emoji/woman.png diff --git a/app/assets/images/emoji/woman_tone1.png b/app/assets/images/emoji/woman_tone1.png Binary files differnew file mode 100644 index 00000000000..ff089b8889b --- /dev/null +++ b/app/assets/images/emoji/woman_tone1.png diff --git a/app/assets/images/emoji/woman_tone2.png b/app/assets/images/emoji/woman_tone2.png Binary files differnew file mode 100644 index 00000000000..0719c378016 --- /dev/null +++ b/app/assets/images/emoji/woman_tone2.png diff --git a/app/assets/images/emoji/woman_tone3.png b/app/assets/images/emoji/woman_tone3.png Binary files differnew file mode 100644 index 00000000000..5672e2fd52d --- /dev/null +++ b/app/assets/images/emoji/woman_tone3.png diff --git a/app/assets/images/emoji/woman_tone4.png b/app/assets/images/emoji/woman_tone4.png Binary files differnew file mode 100644 index 00000000000..5754aab558b --- /dev/null +++ b/app/assets/images/emoji/woman_tone4.png diff --git a/app/assets/images/emoji/woman_tone5.png b/app/assets/images/emoji/woman_tone5.png Binary files differnew file mode 100644 index 00000000000..fc252af3a39 --- /dev/null +++ b/app/assets/images/emoji/woman_tone5.png diff --git a/app/assets/images/emoji/womans_clothes.png b/app/assets/images/emoji/womans_clothes.png Binary files differnew file mode 100644 index 00000000000..01410dc8107 --- /dev/null +++ b/app/assets/images/emoji/womans_clothes.png diff --git a/app/assets/images/emoji/womans_hat.png b/app/assets/images/emoji/womans_hat.png Binary files differnew file mode 100644 index 00000000000..b837b6a2e47 --- /dev/null +++ b/app/assets/images/emoji/womans_hat.png diff --git a/app/assets/images/emoji/womens.png b/app/assets/images/emoji/womens.png Binary files differnew file mode 100644 index 00000000000..d4ecc22e7b3 --- /dev/null +++ b/app/assets/images/emoji/womens.png diff --git a/app/assets/images/emoji/worried.png b/app/assets/images/emoji/worried.png Binary files differnew file mode 100644 index 00000000000..7074afcf5b7 --- /dev/null +++ b/app/assets/images/emoji/worried.png diff --git a/app/assets/images/emoji/wrench.png b/app/assets/images/emoji/wrench.png Binary files differnew file mode 100644 index 00000000000..c16b7439697 --- /dev/null +++ b/app/assets/images/emoji/wrench.png diff --git a/app/assets/images/emoji/wrestlers.png b/app/assets/images/emoji/wrestlers.png Binary files differnew file mode 100644 index 00000000000..71e67cfad85 --- /dev/null +++ b/app/assets/images/emoji/wrestlers.png diff --git a/app/assets/images/emoji/wrestlers_tone1.png b/app/assets/images/emoji/wrestlers_tone1.png Binary files differnew file mode 100644 index 00000000000..379070fd03b --- /dev/null +++ b/app/assets/images/emoji/wrestlers_tone1.png diff --git a/app/assets/images/emoji/wrestlers_tone2.png b/app/assets/images/emoji/wrestlers_tone2.png Binary files differnew file mode 100644 index 00000000000..6863ea9209d --- /dev/null +++ b/app/assets/images/emoji/wrestlers_tone2.png diff --git a/app/assets/images/emoji/wrestlers_tone3.png b/app/assets/images/emoji/wrestlers_tone3.png Binary files differnew file mode 100644 index 00000000000..b7e62910127 --- /dev/null +++ b/app/assets/images/emoji/wrestlers_tone3.png diff --git a/app/assets/images/emoji/wrestlers_tone4.png b/app/assets/images/emoji/wrestlers_tone4.png Binary files differnew file mode 100644 index 00000000000..750f9589233 --- /dev/null +++ b/app/assets/images/emoji/wrestlers_tone4.png diff --git a/app/assets/images/emoji/wrestlers_tone5.png b/app/assets/images/emoji/wrestlers_tone5.png Binary files differnew file mode 100644 index 00000000000..36ab9bb3f42 --- /dev/null +++ b/app/assets/images/emoji/wrestlers_tone5.png diff --git a/app/assets/images/emoji/writing_hand.png b/app/assets/images/emoji/writing_hand.png Binary files differnew file mode 100644 index 00000000000..85639f8ac40 --- /dev/null +++ b/app/assets/images/emoji/writing_hand.png diff --git a/app/assets/images/emoji/writing_hand_tone1.png b/app/assets/images/emoji/writing_hand_tone1.png Binary files differnew file mode 100644 index 00000000000..7923d8ebb17 --- /dev/null +++ b/app/assets/images/emoji/writing_hand_tone1.png diff --git a/app/assets/images/emoji/writing_hand_tone2.png b/app/assets/images/emoji/writing_hand_tone2.png Binary files differnew file mode 100644 index 00000000000..bcb304e15d2 --- /dev/null +++ b/app/assets/images/emoji/writing_hand_tone2.png diff --git a/app/assets/images/emoji/writing_hand_tone3.png b/app/assets/images/emoji/writing_hand_tone3.png Binary files differnew file mode 100644 index 00000000000..fd885fd2d90 --- /dev/null +++ b/app/assets/images/emoji/writing_hand_tone3.png diff --git a/app/assets/images/emoji/writing_hand_tone4.png b/app/assets/images/emoji/writing_hand_tone4.png Binary files differnew file mode 100644 index 00000000000..d065b8c64ab --- /dev/null +++ b/app/assets/images/emoji/writing_hand_tone4.png diff --git a/app/assets/images/emoji/writing_hand_tone5.png b/app/assets/images/emoji/writing_hand_tone5.png Binary files differnew file mode 100644 index 00000000000..a44b3dd757c --- /dev/null +++ b/app/assets/images/emoji/writing_hand_tone5.png diff --git a/app/assets/images/emoji/x.png b/app/assets/images/emoji/x.png Binary files differnew file mode 100644 index 00000000000..9f9ed0f7ad2 --- /dev/null +++ b/app/assets/images/emoji/x.png diff --git a/app/assets/images/emoji/yellow_heart.png b/app/assets/images/emoji/yellow_heart.png Binary files differnew file mode 100644 index 00000000000..7901a9d0103 --- /dev/null +++ b/app/assets/images/emoji/yellow_heart.png diff --git a/app/assets/images/emoji/yen.png b/app/assets/images/emoji/yen.png Binary files differnew file mode 100644 index 00000000000..63ee4799d66 --- /dev/null +++ b/app/assets/images/emoji/yen.png diff --git a/app/assets/images/emoji/yin_yang.png b/app/assets/images/emoji/yin_yang.png Binary files differnew file mode 100644 index 00000000000..f2900f6338f --- /dev/null +++ b/app/assets/images/emoji/yin_yang.png diff --git a/app/assets/images/emoji/yum.png b/app/assets/images/emoji/yum.png Binary files differnew file mode 100644 index 00000000000..2df15753ca1 --- /dev/null +++ b/app/assets/images/emoji/yum.png diff --git a/app/assets/images/emoji/zap.png b/app/assets/images/emoji/zap.png Binary files differnew file mode 100644 index 00000000000..47e68e48e49 --- /dev/null +++ b/app/assets/images/emoji/zap.png diff --git a/app/assets/images/emoji/zero.png b/app/assets/images/emoji/zero.png Binary files differnew file mode 100644 index 00000000000..13aca83e018 --- /dev/null +++ b/app/assets/images/emoji/zero.png diff --git a/app/assets/images/emoji/zipper_mouth.png b/app/assets/images/emoji/zipper_mouth.png Binary files differnew file mode 100644 index 00000000000..f8ced2502a7 --- /dev/null +++ b/app/assets/images/emoji/zipper_mouth.png diff --git a/app/assets/images/emoji/zzz.png b/app/assets/images/emoji/zzz.png Binary files differnew file mode 100644 index 00000000000..9bc72b4469f --- /dev/null +++ b/app/assets/images/emoji/zzz.png diff --git a/app/assets/images/emoji@2x.png b/app/assets/images/emoji@2x.png Binary files differindex dc9cae1d44c..b0fa9e1139e 100644 --- a/app/assets/images/emoji@2x.png +++ b/app/assets/images/emoji@2x.png diff --git a/app/assets/javascripts/abuse_reports.js.es6 b/app/assets/javascripts/abuse_reports.js index 8a260aae1b1..8a260aae1b1 100644 --- a/app/assets/javascripts/abuse_reports.js.es6 +++ b/app/assets/javascripts/abuse_reports.js diff --git a/app/assets/javascripts/activities.js.es6 b/app/assets/javascripts/activities.js index 648cb4d5d85..648cb4d5d85 100644 --- a/app/assets/javascripts/activities.js.es6 +++ b/app/assets/javascripts/activities.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js deleted file mode 100644 index c51860d1604..00000000000 --- a/app/assets/javascripts/application.js +++ /dev/null @@ -1,401 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import */ -/* global bp */ -/* global Cookies */ -/* global Flash */ -/* global ConfirmDangerModal */ -/* global AwardsHandler */ -/* global Aside */ - -window.$ = window.jQuery = require('jquery'); -require('jquery-ujs'); -require('vendor/jquery.endless-scroll'); -require('vendor/jquery.highlight'); -require('vendor/jquery.waitforimages'); -require('vendor/jquery.caret'); -require('vendor/jquery.atwho'); -require('vendor/jquery.scrollTo'); -window.Cookies = require('js-cookie'); -require('./autosave'); -require('bootstrap/js/affix'); -require('bootstrap/js/alert'); -require('bootstrap/js/button'); -require('bootstrap/js/collapse'); -require('bootstrap/js/dropdown'); -require('bootstrap/js/modal'); -require('bootstrap/js/scrollspy'); -require('bootstrap/js/tab'); -require('bootstrap/js/transition'); -require('bootstrap/js/tooltip'); -require('bootstrap/js/popover'); -require('select2/select2.js'); -window.Pikaday = require('pikaday'); -window._ = require('underscore'); -window.Dropzone = require('dropzone'); -window.Sortable = require('vendor/Sortable'); -require('mousetrap'); -require('mousetrap/plugins/pause/mousetrap-pause'); -require('./shortcuts'); -require('./shortcuts_navigation'); -require('./shortcuts_dashboard_navigation'); -require('./shortcuts_issuable'); -require('./shortcuts_network'); -require('vendor/jquery.nicescroll'); - -// behaviors -require('./behaviors/autosize'); -require('./behaviors/details_behavior'); -require('./behaviors/quick_submit'); -require('./behaviors/requires_input'); -require('./behaviors/toggler_behavior'); - -// blob -require('./blob/blob_ci_yaml'); -require('./blob/blob_dockerfile_selector'); -require('./blob/blob_dockerfile_selectors'); -require('./blob/blob_file_dropzone'); -require('./blob/blob_gitignore_selector'); -require('./blob/blob_gitignore_selectors'); -require('./blob/blob_license_selector'); -require('./blob/blob_license_selectors'); -require('./blob/template_selector'); - -// templates -require('./templates/issuable_template_selector'); -require('./templates/issuable_template_selectors'); - -// commit -require('./commit/file.js'); -require('./commit/image_file.js'); - -// extensions -require('./extensions/array'); -require('./extensions/custom_event'); -require('./extensions/element'); -require('./extensions/jquery'); -require('./extensions/object'); - -// lib/utils -require('./lib/utils/animate'); -require('./lib/utils/bootstrap_linked_tabs'); -require('./lib/utils/common_utils'); -require('./lib/utils/datetime_utility'); -require('./lib/utils/notify'); -require('./lib/utils/pretty_time'); -require('./lib/utils/text_utility'); -require('./lib/utils/type_utility'); -require('./lib/utils/url_utility'); - -// u2f -require('./u2f/authenticate'); -require('./u2f/error'); -require('./u2f/register'); -require('./u2f/util'); - -// droplab -require('./droplab/droplab'); -require('./droplab/droplab_ajax'); -require('./droplab/droplab_ajax_filter'); -require('./droplab/droplab_filter'); - -// everything else -require('./abuse_reports'); -require('./activities'); -require('./admin'); -require('./ajax_loading_spinner'); -require('./api'); -require('./aside'); -require('./autosave'); -require('./awards_handler'); -require('./breakpoints'); -require('./broadcast_message'); -require('./build'); -require('./build_artifacts'); -require('./build_variables'); -require('./ci_lint_editor'); -require('./commit'); -require('./commits'); -require('./compare'); -require('./compare_autocomplete'); -require('./confirm_danger_modal'); -require('./copy_as_gfm'); -require('./copy_to_clipboard'); -require('./create_label'); -require('./diff'); -require('./dispatcher'); -require('./dropzone_input'); -require('./due_date_select'); -require('./files_comment_button'); -require('./flash'); -require('./gfm_auto_complete'); -require('./gl_dropdown'); -require('./gl_field_error'); -require('./gl_field_errors'); -require('./gl_form'); -require('./group_avatar'); -require('./group_label_subscription'); -require('./groups_select'); -require('./header'); -require('./importer_status'); -require('./issuable'); -require('./issuable_context'); -require('./issuable_form'); -require('./issue'); -require('./issue_status_select'); -require('./issues_bulk_assignment'); -require('./label_manager'); -require('./labels'); -require('./labels_select'); -require('./layout_nav'); -require('./line_highlighter'); -require('./logo'); -require('./member_expiration_date'); -require('./members'); -require('./merge_request'); -require('./merge_request_tabs'); -require('./merge_request_widget'); -require('./merged_buttons'); -require('./milestone'); -require('./milestone_select'); -require('./mini_pipeline_graph_dropdown'); -require('./namespace_select'); -require('./new_branch_form'); -require('./new_commit_form'); -require('./notes'); -require('./notifications_dropdown'); -require('./notifications_form'); -require('./pager'); -require('./pipelines'); -require('./preview_markdown'); -require('./project'); -require('./project_avatar'); -require('./project_find_file'); -require('./project_fork'); -require('./project_import'); -require('./project_label_subscription'); -require('./project_new'); -require('./project_select'); -require('./project_show'); -require('./project_variables'); -require('./projects_list'); -require('./render_gfm'); -require('./render_math'); -require('./right_sidebar'); -require('./search'); -require('./search_autocomplete'); -require('./shortcuts'); -require('./shortcuts_blob'); -require('./shortcuts_dashboard_navigation'); -require('./shortcuts_find_file'); -require('./shortcuts_issuable'); -require('./shortcuts_navigation'); -require('./shortcuts_network'); -require('./signin_tabs_memoizer'); -require('./single_file_diff'); -require('./smart_interval'); -require('./snippets_list'); -require('./star'); -require('./subbable_resource'); -require('./subscription'); -require('./subscription_select'); -require('./syntax_highlight'); -require('./task_list'); -require('./todos'); -require('./tree'); -require('./user'); -require('./user_tabs'); -require('./username_validator'); -require('./users_select'); -require('./version_check_image'); -require('./visibility_select'); -require('./wikis'); -require('./zen_mode'); - -require('vendor/fuzzaldrin-plus'); -require('es6-promise').polyfill(); - -(function () { - document.addEventListener('beforeunload', function () { - // Unbind scroll events - $(document).off('scroll'); - // Close any open tooltips - $('.has-tooltip, [data-toggle="tooltip"]').tooltip('destroy'); - }); - - window.addEventListener('hashchange', gl.utils.handleLocationHash); - window.addEventListener('load', function onLoad() { - window.removeEventListener('load', onLoad, false); - gl.utils.handleLocationHash(); - }, false); - - $(function () { - var $body = $('body'); - var $document = $(document); - var $window = $(window); - var $sidebarGutterToggle = $('.js-sidebar-toggle'); - var $flash = $('.flash-container'); - var bootstrapBreakpoint = bp.getBreakpointSize(); - var fitSidebarForSize; - - // Set the default path for all cookies to GitLab's root directory - Cookies.defaults.path = gon.relative_url_root || '/'; - - // `hashchange` is not triggered when link target is already in window.location - $body.on('click', 'a[href^="#"]', function() { - var href = this.getAttribute('href'); - if (href.substr(1) === gl.utils.getLocationHash()) { - setTimeout(gl.utils.handleLocationHash, 1); - } - }); - - // prevent default action for disabled buttons - $('.btn').click(function(e) { - if ($(this).hasClass('disabled')) { - e.preventDefault(); - e.stopImmediatePropagation(); - return false; - } - }); - - $('.js-select-on-focus').on('focusin', function () { - return $(this).select().one('mouseup', function (e) { - return e.preventDefault(); - }); - // Click a .js-select-on-focus field, select the contents - // Prevent a mouseup event from deselecting the input - }); - $('.remove-row').bind('ajax:success', function () { - $(this).tooltip('destroy') - .closest('li') - .fadeOut(); - }); - $('.js-remove-tr').bind('ajax:before', function () { - return $(this).hide(); - }); - $('.js-remove-tr').bind('ajax:success', function () { - return $(this).closest('tr').fadeOut(); - }); - $('select.select2').select2({ - width: 'resolve', - // Initialize select2 selects - dropdownAutoWidth: true - }); - $('.js-select2').bind('select2-close', function () { - return setTimeout((function () { - $('.select2-container-active').removeClass('select2-container-active'); - return $(':focus').blur(); - }), 1); - // Close select2 on escape - }); - // Initialize tooltips - $.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover'; - $body.tooltip({ - selector: '.has-tooltip, [data-toggle="tooltip"]', - placement: function (_, el) { - return $(el).data('placement') || 'bottom'; - } - }); - $('.trigger-submit').on('change', function () { - return $(this).parents('form').submit(); - // Form submitter - }); - gl.utils.localTimeAgo($('abbr.timeago, .js-timeago'), true); - // Flash - if ($flash.length > 0) { - $flash.click(function () { - return $(this).fadeOut(); - }); - $flash.show(); - } - // Disable form buttons while a form is submitting - $body.on('ajax:complete, ajax:beforeSend, submit', 'form', function (e) { - var buttons; - buttons = $('[type="submit"]', this); - switch (e.type) { - case 'ajax:beforeSend': - case 'submit': - return buttons.disable(); - default: - return buttons.enable(); - } - }); - $(document).ajaxError(function (e, xhrObj) { - var ref = xhrObj.status; - if (xhrObj.status === 401) { - return new Flash('You need to be logged in.', 'alert'); - } else if (ref === 404 || ref === 500) { - return new Flash('Something went wrong on our end.', 'alert'); - } - }); - $('.account-box').hover(function () { - // Show/Hide the profile menu when hovering the account box - return $(this).toggleClass('hover'); - }); - $document.on('click', '.diff-content .js-show-suppressed-diff', function () { - var $container; - $container = $(this).parent(); - $container.next('table').show(); - return $container.remove(); - // Commit show suppressed diff - }); - $('.navbar-toggle').on('click', function () { - $('.header-content .title').toggle(); - $('.header-content .header-logo').toggle(); - $('.header-content .navbar-collapse').toggle(); - return $('.navbar-toggle').toggleClass('active'); - }); - // Show/hide comments on diff - $body.on('click', '.js-toggle-diff-comments', function (e) { - var $this = $(this); - var notesHolders = $this.closest('.diff-file').find('.notes_holder'); - $this.toggleClass('active'); - if ($this.hasClass('active')) { - notesHolders.show().find('.hide').show(); - } else { - notesHolders.hide(); - } - $this.trigger('blur'); - return e.preventDefault(); - }); - $document.off('click', '.js-confirm-danger'); - $document.on('click', '.js-confirm-danger', function (e) { - var btn = $(e.target); - var form = btn.closest('form'); - var text = btn.data('confirm-danger-message'); - e.preventDefault(); - return new ConfirmDangerModal(form, text); - }); - $('input[type="search"]').each(function () { - var $this = $(this); - $this.attr('value', $this.val()); - }); - $document.off('keyup', 'input[type="search"]').on('keyup', 'input[type="search"]', function () { - var $this; - $this = $(this); - return $this.attr('value', $this.val()); - }); - $document.off('breakpoint:change').on('breakpoint:change', function (e, breakpoint) { - var $gutterIcon; - if (breakpoint === 'sm' || breakpoint === 'xs') { - $gutterIcon = $sidebarGutterToggle.find('i'); - if ($gutterIcon.hasClass('fa-angle-double-right')) { - return $sidebarGutterToggle.trigger('click'); - } - } - }); - fitSidebarForSize = function () { - var oldBootstrapBreakpoint; - oldBootstrapBreakpoint = bootstrapBreakpoint; - bootstrapBreakpoint = bp.getBreakpointSize(); - if (bootstrapBreakpoint !== oldBootstrapBreakpoint) { - return $document.trigger('breakpoint:change', [bootstrapBreakpoint]); - } - }; - $window.off('resize.app').on('resize.app', function () { - return fitSidebarForSize(); - }); - gl.awardsHandler = new AwardsHandler(); - new Aside(); - - gl.utils.initTimeagoTimeout(); - }); -}).call(window); diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index a4ccb30e447..4667980a960 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -1,380 +1,518 @@ -/* eslint-disable func-names, space-before-function-paren, wrap-iife, max-len, no-var, prefer-arrow-callback, consistent-return, one-var, one-var-declaration-per-line, no-unused-vars, no-else-return, prefer-template, quotes, comma-dangle, no-param-reassign, no-void, brace-style, no-underscore-dangle, no-return-assign, camelcase */ /* global Cookies */ -var emojiAliases = require('emoji-aliases'); - -(function() { - this.AwardsHandler = (function() { - var FROM_SENTENCE_REGEX = /(?:, and | and |, )/; // For separating lists produced by ruby's Array#toSentence - function AwardsHandler() { - this.aliases = emojiAliases; - $(document).off('click', '.js-add-award').on('click', '.js-add-award', (function(_this) { - return function(e) { - e.stopPropagation(); - e.preventDefault(); - return _this.showEmojiMenu($(e.currentTarget)); - }; - })(this)); - $('html').on('click', function(e) { - var $target; - $target = $(e.target); - if (!$target.closest('.emoji-menu-content').length) { - $('.js-awards-block.current').removeClass('current'); - } - if (!$target.closest('.emoji-menu').length) { - if ($('.emoji-menu').is(':visible')) { - $('.js-add-award.is-active').removeClass('is-active'); - return $('.emoji-menu').removeClass('is-visible'); - } - } - }); - $(document).off('click', '.js-emoji-btn').on('click', '.js-emoji-btn', (function(_this) { - return function(e) { - var $target, emoji; - e.preventDefault(); - $target = $(e.currentTarget); - emoji = $target.find('.icon').data('emoji'); - $target.closest('.js-awards-block').addClass('current'); - return _this.addAward(_this.getVotesBlock(), _this.getAwardUrl(), emoji); - }; - })(this)); +const emojiMap = require('emoji-map'); +const emojiAliases = require('emoji-aliases'); +const glEmoji = require('./behaviors/gl_emoji'); + +const glEmojiTag = glEmoji.glEmojiTag; + +const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd'; +const requestAnimationFrame = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.setTimeout; + +const FROM_SENTENCE_REGEX = /(?:, and | and |, )/; // For separating lists produced by ruby's Array#toSentence + +let categoryMap = null; + +const categoryLabelMap = { + activity: 'Activity', + people: 'People', + nature: 'Nature', + food: 'Food', + travel: 'Travel', + objects: 'Objects', + symbols: 'Symbols', + flags: 'Flags', +}; + +function buildCategoryMap() { + return Object.keys(emojiMap).reduce((currentCategoryMap, emojiNameKey) => { + const emojiInfo = emojiMap[emojiNameKey]; + if (currentCategoryMap[emojiInfo.category]) { + currentCategoryMap[emojiInfo.category].push(emojiNameKey); } - AwardsHandler.prototype.showEmojiMenu = function($addBtn) { - var $holder, $menu, url; - $menu = $('.emoji-menu'); - if ($addBtn.hasClass('js-note-emoji')) { - $addBtn.closest('.note').find('.js-awards-block').addClass('current'); - } else { - $addBtn.closest('.js-awards-block').addClass('current'); - } - if ($menu.length) { - $holder = $addBtn.closest('.js-award-holder'); - if ($menu.is('.is-visible')) { - $addBtn.removeClass('is-active'); - $menu.removeClass('is-visible'); - return $('#emoji_search').blur(); - } else { - $addBtn.addClass('is-active'); - this.positionMenu($menu, $addBtn); - $menu.addClass('is-visible'); - return $('#emoji_search').focus(); - } - } else { - $addBtn.addClass('is-loading is-active'); - url = this.getAwardMenuUrl(); - return this.createEmojiMenu(url, (function(_this) { - return function() { - $addBtn.removeClass('is-loading'); - $menu = $('.emoji-menu'); - _this.positionMenu($menu, $addBtn); - if (!_this.frequentEmojiBlockRendered) { - _this.renderFrequentlyUsedBlock(); - } - return setTimeout(function() { - $menu.addClass('is-visible'); - $('#emoji_search').focus(); - return _this.setupSearch(); - }, 200); - }; - })(this)); - } - }; - - AwardsHandler.prototype.createEmojiMenu = function(awardMenuUrl, callback) { - return $.get(awardMenuUrl, function(response) { - $('body').append(response); - return callback(); + return currentCategoryMap; + }, { + activity: [], + people: [], + nature: [], + food: [], + travel: [], + objects: [], + symbols: [], + flags: [], + }); +} + +function renderCategory(name, emojiList) { + return ` + <h5 class="emoji-menu-title"> + ${name} + </h5> + <ul class="clearfix emoji-menu-list"> + ${emojiList.map(emojiName => ` + <li class="emoji-menu-list-item"> + <button class="emoji-menu-btn text-center js-emoji-btn" type="button"> + ${glEmojiTag(emojiName, { + sprite: true, + })} + </button> + </li> + `).join('\n')} + </ul> + `; +} + +function AwardsHandler() { + this.eventListeners = []; + this.aliases = emojiAliases; + // If the user shows intent let's pre-build the menu + this.registerEventListener('one', $(document), 'mouseenter focus', '.js-add-award', 'mouseenter focus', () => { + const $menu = $('.emoji-menu'); + if ($menu.length === 0) { + requestAnimationFrame(() => { + this.createEmojiMenu(); }); - }; - - AwardsHandler.prototype.positionMenu = function($menu, $addBtn) { - var css, position; - position = $addBtn.data('position'); - // The menu could potentially be off-screen or in a hidden overflow element - // So we position the element absolute in the body - css = { - top: ($addBtn.offset().top + $addBtn.outerHeight()) + "px" - }; - if (position === 'right') { - css.left = (($addBtn.offset().left - $menu.outerWidth()) + 20) + "px"; - $menu.addClass('is-aligned-right'); - } else { - css.left = ($addBtn.offset().left) + "px"; - $menu.removeClass('is-aligned-right'); - } - return $menu.css(css); - }; - - AwardsHandler.prototype.addAward = function(votesBlock, awardUrl, emoji, checkMutuality, callback) { - if (checkMutuality == null) { - checkMutuality = true; - } - emoji = this.normilizeEmojiName(emoji); - this.postEmoji(awardUrl, emoji, (function(_this) { - return function() { - _this.addAwardToEmojiBar(votesBlock, emoji, checkMutuality); - return typeof callback === "function" ? callback() : void 0; - }; - })(this)); - return $('.emoji-menu').removeClass('is-visible'); - }; - - AwardsHandler.prototype.addAwardToEmojiBar = function(votesBlock, emoji, checkForMutuality) { - var $emojiButton, counter; - if (checkForMutuality == null) { - checkForMutuality = true; - } - if (checkForMutuality) { - this.checkMutuality(votesBlock, emoji); - } - this.addEmojiToFrequentlyUsedList(emoji); - emoji = this.normilizeEmojiName(emoji); - $emojiButton = this.findEmojiIcon(votesBlock, emoji).parent(); - if ($emojiButton.length > 0) { - if (this.isActive($emojiButton)) { - return this.decrementCounter($emojiButton, emoji); - } else { - counter = $emojiButton.find('.js-counter'); - counter.text(parseInt(counter.text(), 10) + 1); - $emojiButton.addClass('active'); - this.addYouToUserList(votesBlock, emoji); - return this.animateEmoji($emojiButton); - } - } else { - votesBlock.removeClass('hidden'); - return this.createEmoji(votesBlock, emoji); - } - }; - - AwardsHandler.prototype.getVotesBlock = function() { - var currentBlock; - currentBlock = $('.js-awards-block.current'); - if (currentBlock.length) { - return currentBlock; - } else { - return $('.js-awards-block').eq(0); - } - }; - - AwardsHandler.prototype.getAwardUrl = function() { - return this.getVotesBlock().data('award-url'); - }; - - AwardsHandler.prototype.checkMutuality = function(votesBlock, emoji) { - var $emojiButton, awardUrl, isAlreadyVoted, mutualVote; - awardUrl = this.getAwardUrl(); - if (emoji === 'thumbsup' || emoji === 'thumbsdown') { - mutualVote = emoji === 'thumbsup' ? 'thumbsdown' : 'thumbsup'; - $emojiButton = votesBlock.find("[data-emoji=" + mutualVote + "]").parent(); - isAlreadyVoted = $emojiButton.hasClass('active'); - if (isAlreadyVoted) { - this.addAward(votesBlock, awardUrl, mutualVote, false); - } - } - }; - - AwardsHandler.prototype.isActive = function($emojiButton) { - return $emojiButton.hasClass('active'); - }; - - AwardsHandler.prototype.decrementCounter = function($emojiButton, emoji) { - var counter, counterNumber; - counter = $('.js-counter', $emojiButton); - counterNumber = parseInt(counter.text(), 10); - if (counterNumber > 1) { - counter.text(counterNumber - 1); - this.removeYouFromUserList($emojiButton, emoji); - } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') { - $emojiButton.tooltip('destroy'); - counter.text('0'); - this.removeYouFromUserList($emojiButton, emoji); - if ($emojiButton.parents('.note').length) { - this.removeEmoji($emojiButton); - } - } else { - this.removeEmoji($emojiButton); - } - return $emojiButton.removeClass('active'); - }; - - AwardsHandler.prototype.removeEmoji = function($emojiButton) { - var $votesBlock; - $emojiButton.tooltip('destroy'); - $emojiButton.remove(); - $votesBlock = this.getVotesBlock(); - if ($votesBlock.find('.js-emoji-btn').length === 0) { - return $votesBlock.addClass('hidden'); - } - }; - - AwardsHandler.prototype.getAwardTooltip = function($awardBlock) { - return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || ''; - }; - - AwardsHandler.prototype.toSentence = function(list) { - if (list.length <= 2) { - return list.join(' and '); + } + // Prebuild the categoryMap + categoryMap = categoryMap || buildCategoryMap(); + }); + this.registerEventListener('on', $(document), 'click', '.js-add-award', (e) => { + e.stopPropagation(); + e.preventDefault(); + this.showEmojiMenu($(e.currentTarget)); + }); + + this.registerEventListener('on', $('html'), 'click', (e) => { + const $target = $(e.target); + if (!$target.closest('.emoji-menu-content').length) { + $('.js-awards-block.current').removeClass('current'); + } + if (!$target.closest('.emoji-menu').length) { + if ($('.emoji-menu').is(':visible')) { + $('.js-add-award.is-active').removeClass('is-active'); + $('.emoji-menu').removeClass('is-visible'); } - else { - return list.slice(0, -1).join(', ') + ', and ' + list[list.length - 1]; + } + }); + this.registerEventListener('on', $(document), 'click', '.js-emoji-btn', (e) => { + e.preventDefault(); + const $target = $(e.currentTarget); + const $glEmojiElement = $target.find('gl-emoji'); + const $spriteIconElement = $target.find('.icon'); + const emoji = ($glEmojiElement.length ? $glEmojiElement : $spriteIconElement).data('name'); + $target.closest('.js-awards-block').addClass('current'); + return this.addAward(this.getVotesBlock(), this.getAwardUrl(), emoji); + }); +} + +AwardsHandler.prototype.registerEventListener = function registerEventListener(method = 'on', element, ...args) { + element[method].call(element, ...args); + this.eventListeners.push({ + element, + args, + }); +}; + +AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) { + if ($addBtn.hasClass('js-note-emoji')) { + $addBtn.closest('.note').find('.js-awards-block').addClass('current'); + } else { + $addBtn.closest('.js-awards-block').addClass('current'); + } + + const $menu = $('.emoji-menu'); + if ($menu.length) { + if ($menu.is('.is-visible')) { + $addBtn.removeClass('is-active'); + $menu.removeClass('is-visible'); + $('#emoji_search').blur(); + } else { + $addBtn.addClass('is-active'); + this.positionMenu($menu, $addBtn); + $menu.addClass('is-visible'); + $('#emoji_search').focus(); + } + } else { + $addBtn.addClass('is-loading is-active'); + this.createEmojiMenu(() => { + const $createdMenu = $('.emoji-menu'); + $addBtn.removeClass('is-loading'); + this.positionMenu($createdMenu, $addBtn); + if (!this.frequentEmojiBlockRendered) { + this.renderFrequentlyUsedBlock(); } - }; - - AwardsHandler.prototype.removeYouFromUserList = function($emojiButton, emoji) { - var authors, awardBlock, newAuthors, originalTitle; - awardBlock = $emojiButton; - originalTitle = this.getAwardTooltip(awardBlock); - authors = originalTitle.split(FROM_SENTENCE_REGEX); - authors.splice(authors.indexOf('You'), 1); - return awardBlock - .closest('.js-emoji-btn') - .removeData('title') - .removeAttr('data-title') - .removeAttr('data-original-title') - .attr('title', this.toSentence(authors)) - .tooltip('fixTitle'); - }; - - AwardsHandler.prototype.addYouToUserList = function(votesBlock, emoji) { - var awardBlock, origTitle, users; - awardBlock = this.findEmojiIcon(votesBlock, emoji).parent(); - origTitle = this.getAwardTooltip(awardBlock); - users = []; - if (origTitle) { - users = origTitle.trim().split(FROM_SENTENCE_REGEX); + return setTimeout(() => { + $createdMenu.addClass('is-visible'); + $('#emoji_search').focus(); + }, 200); + }); + } +}; + +// Create the emoji menu with the first category of emojis. +// Then render the remaining categories of emojis one by one to avoid jank. +AwardsHandler.prototype.createEmojiMenu = function createEmojiMenu(callback) { + if (this.isCreatingEmojiMenu) { + return; + } + this.isCreatingEmojiMenu = true; + + // Render the first category + categoryMap = categoryMap || buildCategoryMap(); + const categoryNameKey = Object.keys(categoryMap)[0]; + const emojisInCategory = categoryMap[categoryNameKey]; + const firstCategory = renderCategory(categoryLabelMap[categoryNameKey], emojisInCategory); + + const emojiMenuMarkup = ` + <div class="emoji-menu"> + <input type="text" name="emoji_search" id="emoji_search" value="" class="emoji-search search-input form-control" placeholder="Search emoji" /> + + <div class="emoji-menu-content"> + ${firstCategory} + </div> + </div> + `; + + document.body.insertAdjacentHTML('beforeend', emojiMenuMarkup); + + this.addRemainingEmojiMenuCategories(); + this.setupSearch(); + if (callback) { + callback(); + } +}; + +AwardsHandler + .prototype + .addRemainingEmojiMenuCategories = function addRemainingEmojiMenuCategories() { + if (this.isAddingRemainingEmojiMenuCategories) { + return; + } + this.isAddingRemainingEmojiMenuCategories = true; + + categoryMap = categoryMap || buildCategoryMap(); + + // Avoid the jank and render the remaining categories separately + // This will take more time, but makes UI more responsive + const menu = document.querySelector('.emoji-menu'); + const emojiContentElement = menu.querySelector('.emoji-menu-content'); + const remainingCategories = Object.keys(categoryMap).slice(1); + const allCategoriesAddedPromise = remainingCategories.reduce( + (promiseChain, categoryNameKey) => + promiseChain.then(() => + new Promise((resolve) => { + const emojisInCategory = categoryMap[categoryNameKey]; + const categoryMarkup = renderCategory( + categoryLabelMap[categoryNameKey], + emojisInCategory, + ); + requestAnimationFrame(() => { + emojiContentElement.insertAdjacentHTML('beforeend', categoryMarkup); + resolve(); + }); + }), + ), + Promise.resolve(), + ); + + allCategoriesAddedPromise.then(() => { + // Used for tests + // We check for the menu in case it was destroyed in the meantime + if (menu) { + menu.dispatchEvent(new CustomEvent('build-emoji-menu-finish')); } - users.unshift('You'); - return awardBlock - .attr('title', this.toSentence(users)) - .tooltip('fixTitle'); - }; - - AwardsHandler.prototype.createEmoji_ = function(votesBlock, emoji) { - var $emojiButton, buttonHtml, emojiCssClass; - emojiCssClass = this.resolveNameToCssClass(emoji); - buttonHtml = "<button class='btn award-control js-emoji-btn has-tooltip active' title='You' data-placement='bottom'> <div class='icon emoji-icon " + emojiCssClass + "' data-emoji='" + emoji + "'></div> <span class='award-control-text js-counter'>1</span> </button>"; - $emojiButton = $(buttonHtml); - $emojiButton.insertBefore(votesBlock.find('.js-award-holder')).find('.emoji-icon').data('emoji', emoji); + }); + }; + +AwardsHandler.prototype.positionMenu = function positionMenu($menu, $addBtn) { + const position = $addBtn.data('position'); + // The menu could potentially be off-screen or in a hidden overflow element + // So we position the element absolute in the body + const css = { + top: `${$addBtn.offset().top + $addBtn.outerHeight()}px`, + }; + if (position === 'right') { + css.left = `${($addBtn.offset().left - $menu.outerWidth()) + 20}px`; + $menu.addClass('is-aligned-right'); + } else { + css.left = `${$addBtn.offset().left}px`; + $menu.removeClass('is-aligned-right'); + } + return $menu.css(css); +}; + +AwardsHandler.prototype.addAward = function addAward( + votesBlock, + awardUrl, + emoji, + checkMutuality, + callback, +) { + const normalizedEmoji = this.normalizeEmojiName(emoji); + this.postEmoji(awardUrl, normalizedEmoji, () => { + this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality); + return typeof callback === 'function' ? callback() : undefined; + }); + return $('.emoji-menu').removeClass('is-visible'); +}; + +AwardsHandler.prototype.addAwardToEmojiBar = function addAwardToEmojiBar( + votesBlock, + emoji, + checkForMutuality, +) { + if (checkForMutuality || checkForMutuality === null) { + this.checkMutuality(votesBlock, emoji); + } + this.addEmojiToFrequentlyUsedList(emoji); + const normalizedEmoji = this.normalizeEmojiName(emoji); + const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent(); + if ($emojiButton.length > 0) { + if (this.isActive($emojiButton)) { + this.decrementCounter($emojiButton, normalizedEmoji); + } else { + const counter = $emojiButton.find('.js-counter'); + counter.text(parseInt(counter.text(), 10) + 1); + $emojiButton.addClass('active'); + this.addYouToUserList(votesBlock, normalizedEmoji); this.animateEmoji($emojiButton); - $('.award-control').tooltip(); - return votesBlock.removeClass('current'); - }; - - AwardsHandler.prototype.animateEmoji = function($emoji) { - var className = 'pulse animated once short'; - $emoji.addClass(className); + } + } else { + votesBlock.removeClass('hidden'); + this.createEmoji(votesBlock, normalizedEmoji); + } +}; + +AwardsHandler.prototype.getVotesBlock = function getVotesBlock() { + const currentBlock = $('.js-awards-block.current'); + let resultantVotesBlock = currentBlock; + if (currentBlock.length === 0) { + resultantVotesBlock = $('.js-awards-block').eq(0); + } + + return resultantVotesBlock; +}; + +AwardsHandler.prototype.getAwardUrl = function getAwardUrl() { + return this.getVotesBlock().data('award-url'); +}; + +AwardsHandler.prototype.checkMutuality = function checkMutuality(votesBlock, emoji) { + const awardUrl = this.getAwardUrl(); + if (emoji === 'thumbsup' || emoji === 'thumbsdown') { + const mutualVote = emoji === 'thumbsup' ? 'thumbsdown' : 'thumbsup'; + const $emojiButton = votesBlock.find(`[data-name="${mutualVote}"]`).parent(); + const isAlreadyVoted = $emojiButton.hasClass('active'); + if (isAlreadyVoted) { + this.addAward(votesBlock, awardUrl, mutualVote, false); + } + } +}; + +AwardsHandler.prototype.isActive = function isActive($emojiButton) { + return $emojiButton.hasClass('active'); +}; + +AwardsHandler.prototype.decrementCounter = function decrementCounter($emojiButton, emoji) { + const counter = $('.js-counter', $emojiButton); + const counterNumber = parseInt(counter.text(), 10); + if (counterNumber > 1) { + counter.text(counterNumber - 1); + this.removeYouFromUserList($emojiButton); + } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') { + $emojiButton.tooltip('destroy'); + counter.text('0'); + this.removeYouFromUserList($emojiButton); + if ($emojiButton.parents('.note').length) { + this.removeEmoji($emojiButton); + } + } else { + this.removeEmoji($emojiButton); + } + return $emojiButton.removeClass('active'); +}; + +AwardsHandler.prototype.removeEmoji = function removeEmoji($emojiButton) { + $emojiButton.tooltip('destroy'); + $emojiButton.remove(); + const $votesBlock = this.getVotesBlock(); + if ($votesBlock.find('.js-emoji-btn').length === 0) { + $votesBlock.addClass('hidden'); + } +}; + +AwardsHandler.prototype.getAwardTooltip = function getAwardTooltip($awardBlock) { + return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || ''; +}; + +AwardsHandler.prototype.toSentence = function toSentence(list) { + let sentence; + if (list.length <= 2) { + sentence = list.join(' and '); + } else { + sentence = `${list.slice(0, -1).join(', ')}, and ${list[list.length - 1]}`; + } + + return sentence; +}; + +AwardsHandler.prototype.removeYouFromUserList = function removeYouFromUserList($emojiButton) { + const awardBlock = $emojiButton; + const originalTitle = this.getAwardTooltip(awardBlock); + const authors = originalTitle.split(FROM_SENTENCE_REGEX); + authors.splice(authors.indexOf('You'), 1); + return awardBlock + .closest('.js-emoji-btn') + .removeData('title') + .removeAttr('data-title') + .removeAttr('data-original-title') + .attr('title', this.toSentence(authors)) + .tooltip('fixTitle'); +}; + +AwardsHandler.prototype.addYouToUserList = function addYouToUserList(votesBlock, emoji) { + const awardBlock = this.findEmojiIcon(votesBlock, emoji).parent(); + const origTitle = this.getAwardTooltip(awardBlock); + let users = []; + if (origTitle) { + users = origTitle.trim().split(FROM_SENTENCE_REGEX); + } + users.unshift('You'); + return awardBlock + .attr('title', this.toSentence(users)) + .tooltip('fixTitle'); +}; + +AwardsHandler + .prototype + .createAwardButtonForVotesBlock = function createAwardButtonForVotesBlock(votesBlock, emojiName) { + const buttonHtml = ` + <button class="btn award-control js-emoji-btn has-tooltip active" title="You" data-placement="bottom"> + ${glEmojiTag(emojiName)} + <span class="award-control-text js-counter">1</span> + </button> + `; + const $emojiButton = $(buttonHtml); + $emojiButton.insertBefore(votesBlock.find('.js-award-holder')).find('.emoji-icon').data('name', emojiName); + this.animateEmoji($emojiButton); + $('.award-control').tooltip(); + votesBlock.removeClass('current'); + }; + +AwardsHandler.prototype.animateEmoji = function animateEmoji($emoji) { + const className = 'pulse animated once short'; + $emoji.addClass(className); + + this.registerEventListener('on', $emoji, animationEndEventString, (e) => { + $(e.currentTarget).removeClass(className); + }); +}; + +AwardsHandler.prototype.createEmoji = function createEmoji(votesBlock, emoji) { + if ($('.emoji-menu').length) { + this.createAwardButtonForVotesBlock(votesBlock, emoji); + } + this.createEmojiMenu(() => { + this.createAwardButtonForVotesBlock(votesBlock, emoji); + }); +}; + +AwardsHandler.prototype.postEmoji = function postEmoji(awardUrl, emoji, callback) { + return $.post(awardUrl, { + name: emoji, + }, (data) => { + if (data.ok) { + callback(); + } + }); +}; + +AwardsHandler.prototype.findEmojiIcon = function findEmojiIcon(votesBlock, emoji) { + return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`); +}; + +AwardsHandler.prototype.scrollToAwards = function scrollToAwards() { + const options = { + scrollTop: $('.awards').offset().top - 110, + }; + return $('body, html').animate(options, 200); +}; + +AwardsHandler.prototype.normalizeEmojiName = function normalizeEmojiName(emoji) { + return Object.prototype.hasOwnProperty.call(this.aliases, emoji) ? this.aliases[emoji] : emoji; +}; + +AwardsHandler + .prototype + .addEmojiToFrequentlyUsedList = function addEmojiToFrequentlyUsedList(emoji) { + const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis(); + frequentlyUsedEmojis.push(emoji); + Cookies.set('frequently_used_emojis', frequentlyUsedEmojis.join(','), { expires: 365 }); + }; + +AwardsHandler.prototype.getFrequentlyUsedEmojis = function getFrequentlyUsedEmojis() { + const frequentlyUsedEmojis = (Cookies.get('frequently_used_emojis') || '').split(','); + return _.compact(_.uniq(frequentlyUsedEmojis)); +}; + +AwardsHandler.prototype.renderFrequentlyUsedBlock = function renderFrequentlyUsedBlock() { + if (Cookies.get('frequently_used_emojis')) { + const frequentlyUsedEmojis = this.getFrequentlyUsedEmojis(); + const ul = $('<ul class="clearfix emoji-menu-list frequent-emojis">'); + for (let i = 0, len = frequentlyUsedEmojis.length; i < len; i += 1) { + const emoji = frequentlyUsedEmojis[i]; + $(`.emoji-menu-content [data-name="${emoji}"]`).closest('li').clone().appendTo(ul); + } + $('.emoji-menu-content').prepend(ul).prepend($('<h5>').text('Frequently used')); + } + this.frequentEmojiBlockRendered = true; +}; + +AwardsHandler.prototype.setupSearch = function setupSearch() { + this.registerEventListener('on', $('input.emoji-search'), 'input', (e) => { + const term = $(e.target).val().trim(); + // Clean previous search results + $('ul.emoji-menu-search, h5.emoji-search').remove(); + if (term.length > 0) { + // Generate a search result block + const h5 = $('<h5 class="emoji-search" />').text('Search results'); + const foundEmojis = this.searchEmojis(term).show(); + const ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(foundEmojis); + $('.emoji-menu-content ul, .emoji-menu-content h5').hide(); + $('.emoji-menu-content').append(h5).append(ul); + } else { + $('.emoji-menu-content').children().show(); + } + }); +}; - $emoji.on('webkitAnimationEnd animationEnd', function() { - $(this).removeClass(className); - }); - }; +AwardsHandler.prototype.searchEmojis = function searchEmojis(term) { + const safeTerm = term.toLowerCase(); - AwardsHandler.prototype.createEmoji = function(votesBlock, emoji) { - if ($('.emoji-menu').length) { - return this.createEmoji_(votesBlock, emoji); - } - return this.createEmojiMenu(this.getAwardMenuUrl(), (function(_this) { - return function() { - return _this.createEmoji_(votesBlock, emoji); - }; - })(this)); - }; - - AwardsHandler.prototype.getAwardMenuUrl = function() { - return gon.award_menu_url; - }; - - AwardsHandler.prototype.resolveNameToCssClass = function(emoji) { - var emojiIcon, unicodeName; - emojiIcon = $(".emoji-menu-content [data-emoji='" + emoji + "']"); - if (emojiIcon.length > 0) { - unicodeName = emojiIcon.data('unicode-name'); - } else { - // Find by alias - unicodeName = $(".emoji-menu-content [data-aliases*=':" + emoji + ":']").data('unicode-name'); - } - return "emoji-" + unicodeName; - }; - - AwardsHandler.prototype.postEmoji = function(awardUrl, emoji, callback) { - return $.post(awardUrl, { - name: emoji - }, function(data) { - if (data.ok) { - return callback(); - } - }); - }; - - AwardsHandler.prototype.findEmojiIcon = function(votesBlock, emoji) { - return votesBlock.find(".js-emoji-btn [data-emoji='" + emoji + "']"); - }; - - AwardsHandler.prototype.scrollToAwards = function() { - var options; - options = { - scrollTop: $('.awards').offset().top - 110 - }; - return $('body, html').animate(options, 200); - }; - - AwardsHandler.prototype.normilizeEmojiName = function(emoji) { - return this.aliases[emoji] || emoji; - }; - - AwardsHandler.prototype.addEmojiToFrequentlyUsedList = function(emoji) { - var frequentlyUsedEmojis; - frequentlyUsedEmojis = this.getFrequentlyUsedEmojis(); - frequentlyUsedEmojis.push(emoji); - Cookies.set('frequently_used_emojis', frequentlyUsedEmojis.join(','), { expires: 365 }); - }; - - AwardsHandler.prototype.getFrequentlyUsedEmojis = function() { - var frequentlyUsedEmojis; - frequentlyUsedEmojis = (Cookies.get('frequently_used_emojis') || '').split(','); - return _.compact(_.uniq(frequentlyUsedEmojis)); - }; - - AwardsHandler.prototype.renderFrequentlyUsedBlock = function() { - var emoji, frequentlyUsedEmojis, i, len, ul; - if (Cookies.get('frequently_used_emojis')) { - frequentlyUsedEmojis = this.getFrequentlyUsedEmojis(); - ul = $("<ul class='clearfix emoji-menu-list frequent-emojis'>"); - for (i = 0, len = frequentlyUsedEmojis.length; i < len; i += 1) { - emoji = frequentlyUsedEmojis[i]; - $(".emoji-menu-content [data-emoji='" + emoji + "']").closest('li').clone().appendTo(ul); - } - $('.emoji-menu-content').prepend(ul).prepend($('<h5>').text('Frequently used')); - } - return this.frequentEmojiBlockRendered = true; - }; - - AwardsHandler.prototype.setupSearch = function() { - return $('input.emoji-search').on('keyup', (function(_this) { - return function(ev) { - var found_emojis, h5, term, ul; - term = $(ev.target).val(); - // Clean previous search results - $('ul.emoji-menu-search, h5.emoji-search').remove(); - if (term) { - // Generate a search result block - h5 = $('<h5 class="emoji-search" />').text('Search results'); - found_emojis = _this.searchEmojis(term).show(); - ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(found_emojis); - $('.emoji-menu-content ul, .emoji-menu-content h5').hide(); - return $('.emoji-menu-content').append(h5).append(ul); - } else { - return $('.emoji-menu-content').children().show(); - } - }; - })(this)); - }; - - AwardsHandler.prototype.searchEmojis = function(term) { - return $(".emoji-menu-list:not(.frequent-emojis) [data-emoji*='" + term + "']").closest('li').clone(); - }; - - return AwardsHandler; - })(); -}).call(window); + const namesMatchingAlias = []; + Object.keys(emojiAliases).forEach((alias) => { + if (alias.indexOf(safeTerm) >= 0) { + namesMatchingAlias.push(emojiAliases[alias]); + } + }); + const $matchingElements = namesMatchingAlias.concat(safeTerm) + .reduce( + ($result, searchTerm) => + $result.add($(`.emoji-menu-list:not(.frequent-emojis) [data-name*="${searchTerm}"]`)), + $([]), + ); + return $matchingElements.closest('li').clone(); +}; + +AwardsHandler.prototype.destroy = function destroy() { + this.eventListeners.forEach((entry) => { + entry.element.off.call(entry.element, ...entry.args); + }); + $('.emoji-menu').remove(); +}; + +module.exports = AwardsHandler; diff --git a/app/assets/javascripts/behaviors/bind_in_out.js b/app/assets/javascripts/behaviors/bind_in_out.js new file mode 100644 index 00000000000..886f127b06b --- /dev/null +++ b/app/assets/javascripts/behaviors/bind_in_out.js @@ -0,0 +1,47 @@ +class BindInOut { + constructor(bindIn, bindOut) { + this.in = bindIn; + this.out = bindOut; + + this.eventWrapper = {}; + this.eventType = /(INPUT|TEXTAREA)/.test(bindIn.tagName) ? 'keyup' : 'change'; + } + + addEvents() { + this.eventWrapper.updateOut = this.updateOut.bind(this); + + this.in.addEventListener(this.eventType, this.eventWrapper.updateOut); + + return this; + } + + updateOut() { + this.out.textContent = this.in.value; + + return this; + } + + removeEvents() { + this.in.removeEventListener(this.eventType, this.eventWrapper.updateOut); + + return this; + } + + static initAll() { + const ins = document.querySelectorAll('*[data-bind-in]'); + + return [].map.call(ins, anIn => BindInOut.init(anIn)); + } + + static init(anIn, anOut) { + const out = anOut || document.querySelector(`*[data-bind-out="${anIn.dataset.bindIn}"]`); + + if (!out) return null; + + const bindInOut = new BindInOut(anIn, out); + + return bindInOut.addEvents().updateOut(); + } +} + +export default BindInOut; diff --git a/app/assets/javascripts/behaviors/gl_emoji.js b/app/assets/javascripts/behaviors/gl_emoji.js new file mode 100644 index 00000000000..d1d98c3919f --- /dev/null +++ b/app/assets/javascripts/behaviors/gl_emoji.js @@ -0,0 +1,217 @@ +const installCustomElements = require('document-register-element'); +const emojiMap = require('emoji-map'); +const emojiAliases = require('emoji-aliases'); +const generatedUnicodeSupportMap = require('./gl_emoji/unicode_support_map'); +const spreadString = require('./gl_emoji/spread_string'); + +installCustomElements(window); + +function emojiImageTag(name, src) { + return `<img class="emoji" title=":${name}:" alt=":${name}:" src="${src}" width="20" height="20" align="absmiddle" />`; +} + +function assembleFallbackImageSrc(inputName) { + const name = Object.prototype.hasOwnProperty.call(emojiAliases, inputName) ? + emojiAliases[inputName] : inputName; + const emojiInfo = emojiMap[name]; + const fallbackImageSrc = `${gon.asset_host || ''}${gon.relative_url_root || ''}/assets/emoji/${name}-${emojiInfo.digest}.png`; + + return fallbackImageSrc; +} +const glEmojiTagDefaults = { + sprite: false, + forceFallback: false, +}; +function glEmojiTag(inputName, options) { + const opts = Object.assign({}, glEmojiTagDefaults, options); + const name = Object.prototype.hasOwnProperty.call(emojiAliases, inputName) ? + emojiAliases[inputName] : inputName; + const emojiInfo = emojiMap[name]; + const fallbackImageSrc = assembleFallbackImageSrc(name); + const fallbackSpriteClass = `emoji-${name}`; + + const classList = []; + if (opts.forceFallback && opts.sprite) { + classList.push('emoji-icon'); + classList.push(fallbackSpriteClass); + } + const classAttribute = classList.length > 0 ? `class="${classList.join(' ')}"` : ''; + const fallbackSpriteAttribute = opts.sprite ? `data-fallback-sprite-class="${fallbackSpriteClass}"` : ''; + let contents = emojiInfo.moji; + if (opts.forceFallback && !opts.sprite) { + contents = emojiImageTag(name, fallbackImageSrc); + } + + return ` + <gl-emoji + ${classAttribute} + data-name="${name}" + data-fallback-src="${fallbackImageSrc}" + ${fallbackSpriteAttribute} + data-unicode-version="${emojiInfo.unicodeVersion}" + > + ${contents} + </gl-emoji> + `; +} + +// On Windows, flags render as two-letter country codes, see http://emojipedia.org/flags/ +const flagACodePoint = 127462; // parseInt('1F1E6', 16) +const flagZCodePoint = 127487; // parseInt('1F1FF', 16) +function isFlagEmoji(emojiUnicode) { + const cp = emojiUnicode.codePointAt(0); + // Length 4 because flags are made of 2 characters which are surrogate pairs + return emojiUnicode.length === 4 && cp >= flagACodePoint && cp <= flagZCodePoint; +} + +// Chrome <57 renders keycaps oddly +// See https://bugs.chromium.org/p/chromium/issues/detail?id=632294 +// Same issue on Windows also fixed in Chrome 57, http://i.imgur.com/rQF7woO.png +function isKeycapEmoji(emojiUnicode) { + return emojiUnicode.length === 3 && emojiUnicode[2] === '\u20E3'; +} + +// Check for a skin tone variation emoji which aren't always supported +const tone1 = 127995;// parseInt('1F3FB', 16) +const tone5 = 127999;// parseInt('1F3FF', 16) +function isSkinToneComboEmoji(emojiUnicode) { + return emojiUnicode.length > 2 && spreadString(emojiUnicode).some((char) => { + const cp = char.codePointAt(0); + return cp >= tone1 && cp <= tone5; + }); +} + +// macOS supports most skin tone emoji's but +// doesn't support the skin tone versions of horse racing +const horseRacingCodePoint = 127943;// parseInt('1F3C7', 16) +function isHorceRacingSkinToneComboEmoji(emojiUnicode) { + return spreadString(emojiUnicode)[0].codePointAt(0) === horseRacingCodePoint && + isSkinToneComboEmoji(emojiUnicode); +} + +// Check for `family_*`, `kiss_*`, `couple_*` +// For ex. Windows 8.1 Firefox 51.0.1, doesn't support these +const zwj = 8205; // parseInt('200D', 16) +const personStartCodePoint = 128102; // parseInt('1F466', 16) +const personEndCodePoint = 128105; // parseInt('1F469', 16) +function isPersonZwjEmoji(emojiUnicode) { + let hasPersonEmoji = false; + let hasZwj = false; + spreadString(emojiUnicode).forEach((character) => { + const cp = character.codePointAt(0); + if (cp === zwj) { + hasZwj = true; + } else if (cp >= personStartCodePoint && cp <= personEndCodePoint) { + hasPersonEmoji = true; + } + }); + + return hasPersonEmoji && hasZwj; +} + +// Helper so we don't have to run `isFlagEmoji` twice +// in `isEmojiUnicodeSupported` logic +function checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) { + const isFlagResult = isFlagEmoji(emojiUnicode); + return ( + (unicodeSupportMap.flag && isFlagResult) || + !isFlagResult + ); +} + +// Helper so we don't have to run `isSkinToneComboEmoji` twice +// in `isEmojiUnicodeSupported` logic +function checkSkinToneModifierSupport(unicodeSupportMap, emojiUnicode) { + const isSkinToneResult = isSkinToneComboEmoji(emojiUnicode); + return ( + (unicodeSupportMap.skinToneModifier && isSkinToneResult) || + !isSkinToneResult + ); +} + +// Helper func so we don't have to run `isHorceRacingSkinToneComboEmoji` twice +// in `isEmojiUnicodeSupported` logic +function checkHorseRacingSkinToneComboEmojiSupport(unicodeSupportMap, emojiUnicode) { + const isHorseRacingSkinToneResult = isHorceRacingSkinToneComboEmoji(emojiUnicode); + return ( + (unicodeSupportMap.horseRacing && isHorseRacingSkinToneResult) || + !isHorseRacingSkinToneResult + ); +} + +// Helper so we don't have to run `isPersonZwjEmoji` twice +// in `isEmojiUnicodeSupported` logic +function checkPersonEmojiSupport(unicodeSupportMap, emojiUnicode) { + const isPersonZwjResult = isPersonZwjEmoji(emojiUnicode); + return ( + (unicodeSupportMap.personZwj && isPersonZwjResult) || + !isPersonZwjResult + ); +} + +// Takes in a support map and determines whether +// the given unicode emoji is supported on the platform. +// +// Combines all the edge case tests into a one-stop shop method +function isEmojiUnicodeSupported(unicodeSupportMap = {}, emojiUnicode, unicodeVersion) { + const isOlderThanChrome57 = unicodeSupportMap.meta && unicodeSupportMap.meta.isChrome && + unicodeSupportMap.meta.chromeVersion < 57; + + // For comments about each scenario, see the comments above each individual respective function + return unicodeSupportMap[unicodeVersion] && + !(isOlderThanChrome57 && isKeycapEmoji(emojiUnicode)) && + checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) && + checkSkinToneModifierSupport(unicodeSupportMap, emojiUnicode) && + checkHorseRacingSkinToneComboEmojiSupport(unicodeSupportMap, emojiUnicode) && + checkPersonEmojiSupport(unicodeSupportMap, emojiUnicode); +} + +const GlEmojiElementProto = Object.create(HTMLElement.prototype); +GlEmojiElementProto.createdCallback = function createdCallback() { + const emojiUnicode = this.textContent.trim(); + const { + name, + unicodeVersion, + fallbackSrc, + fallbackSpriteClass, + } = this.dataset; + + const isEmojiUnicode = this.childNodes && Array.prototype.every.call( + this.childNodes, + childNode => childNode.nodeType === 3, + ); + const hasImageFallback = fallbackSrc && fallbackSrc.length > 0; + const hasCssSpriteFalback = fallbackSpriteClass && fallbackSpriteClass.length > 0; + + if ( + isEmojiUnicode && + !isEmojiUnicodeSupported(generatedUnicodeSupportMap, emojiUnicode, unicodeVersion) + ) { + // CSS sprite fallback takes precedence over image fallback + if (hasCssSpriteFalback) { + // IE 11 doesn't like adding multiple at once :( + this.classList.add('emoji-icon'); + this.classList.add(fallbackSpriteClass); + } else if (hasImageFallback) { + this.innerHTML = emojiImageTag(name, fallbackSrc); + } else { + const src = assembleFallbackImageSrc(name); + this.innerHTML = emojiImageTag(name, src); + } + } +}; + +document.registerElement('gl-emoji', { + prototype: GlEmojiElementProto, +}); + +module.exports = { + emojiImageTag, + glEmojiTag, + isEmojiUnicodeSupported, + isFlagEmoji, + isKeycapEmoji, + isSkinToneComboEmoji, + isHorceRacingSkinToneComboEmoji, + isPersonZwjEmoji, +}; diff --git a/app/assets/javascripts/behaviors/gl_emoji/spread_string.js b/app/assets/javascripts/behaviors/gl_emoji/spread_string.js new file mode 100644 index 00000000000..2380349c4fa --- /dev/null +++ b/app/assets/javascripts/behaviors/gl_emoji/spread_string.js @@ -0,0 +1,50 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt#Fixing_charCodeAt()_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_known +function knownCharCodeAt(givenString, index) { + const str = `${givenString}`; + const end = str.length; + + const surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + let idx = index; + while ((surrogatePairs.exec(str)) != null) { + const li = surrogatePairs.lastIndex; + if (li - 2 < idx) { + idx += 1; + } else { + break; + } + } + + if (idx >= end || idx < 0) { + return NaN; + } + + const code = str.charCodeAt(idx); + + let high; + let low; + if (code >= 0xD800 && code <= 0xDBFF) { + high = code; + low = str.charCodeAt(idx + 1); + // Go one further, since one of the "characters" is part of a surrogate pair + return ((high - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + } + return code; +} + +// See http://stackoverflow.com/a/38901550/796832 +// ES5/PhantomJS compatible version of spreading a string +// +// [...'foo'] -> ['f', 'o', 'o'] +// [...'🖐🏿'] -> ['🖐', '🏿'] +function spreadString(str) { + const arr = []; + let i = 0; + while (!isNaN(knownCharCodeAt(str, i))) { + const codePoint = knownCharCodeAt(str, i); + arr.push(String.fromCodePoint(codePoint)); + i += 1; + } + return arr; +} + +module.exports = spreadString; diff --git a/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js b/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js new file mode 100644 index 00000000000..f31716d4c07 --- /dev/null +++ b/app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js @@ -0,0 +1,154 @@ +const unicodeSupportTestMap = { + // man, student (emojione does not have any of these yet), http://emojipedia.org/emoji-zwj-sequences/ + // occupationZwj: '\u{1F468}\u{200D}\u{1F393}', + // woman, biking (emojione does not have any of these yet), http://emojipedia.org/emoji-zwj-sequences/ + // sexZwj: '\u{1F6B4}\u{200D}\u{2640}', + // family_mwgb + // Windows 8.1, Firefox 51.0.1 does not support `family_`, `kiss_`, `couple_` + personZwj: '\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}', + // horse_racing_tone5 + // Special case that is not supported on macOS 10.12 even though `skinToneModifier` succeeds + horseRacing: '\u{1F3C7}\u{1F3FF}', + // US flag, http://emojipedia.org/flags/ + flag: '\u{1F1FA}\u{1F1F8}', + // http://emojipedia.org/modifiers/ + skinToneModifier: [ + // spy_tone5 + '\u{1F575}\u{1F3FF}', + // person_with_ball_tone5 + '\u{26F9}\u{1F3FF}', + // angel_tone5 + '\u{1F47C}\u{1F3FF}', + ], + // rofl, http://emojipedia.org/unicode-9.0/ + '9.0': '\u{1F923}', + // metal, http://emojipedia.org/unicode-8.0/ + '8.0': '\u{1F918}', + // spy, http://emojipedia.org/unicode-7.0/ + '7.0': '\u{1F575}', + // expressionless, http://emojipedia.org/unicode-6.1/ + 6.1: '\u{1F611}', + // japanese_goblin, http://emojipedia.org/unicode-6.0/ + '6.0': '\u{1F47A}', + // sailboat, http://emojipedia.org/unicode-5.2/ + 5.2: '\u{26F5}', + // mahjong, http://emojipedia.org/unicode-5.1/ + 5.1: '\u{1F004}', + // gear, http://emojipedia.org/unicode-4.1/ + 4.1: '\u{2699}', + // zap, http://emojipedia.org/unicode-4.0/ + '4.0': '\u{26A1}', + // recycle, http://emojipedia.org/unicode-3.2/ + 3.2: '\u{267B}', + // information_source, http://emojipedia.org/unicode-3.0/ + '3.0': '\u{2139}', + // heart, http://emojipedia.org/unicode-1.1/ + 1.1: '\u{2764}', +}; + +function checkPixelInImageDataArray(pixelOffset, imageDataArray) { + // `4 *` because RGBA + const indexOffset = 4 * pixelOffset; + const hasColor = imageDataArray[indexOffset + 0] || + imageDataArray[indexOffset + 1] || + imageDataArray[indexOffset + 2]; + const isVisible = imageDataArray[indexOffset + 3]; + // Check for some sort of color other than black + if (hasColor && isVisible) { + return true; + } + return false; +} + +const chromeMatches = navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9]+)\./); +const isChrome = chromeMatches && chromeMatches.length > 0; +const chromeVersion = chromeMatches && chromeMatches[1] && parseInt(chromeMatches[1], 10); + +// We use 16px because mobile Safari (iOS 9.3) doesn't properly scale emojis :/ +// See 32px, https://i.imgur.com/htY6Zym.png +// See 16px, https://i.imgur.com/FPPsIF8.png +const fontSize = 16; +function testUnicodeSupportMap(testMap) { + const testMapKeys = Object.keys(testMap); + const numTestEntries = testMapKeys + .reduce((list, testKey) => list.concat(testMap[testKey]), []).length; + + const canvas = document.createElement('canvas'); + (window.gl || window).testEmojiUnicodeSupportMapCanvas = canvas; + const ctx = canvas.getContext('2d'); + canvas.width = (2 * fontSize); + canvas.height = (numTestEntries * fontSize); + ctx.fillStyle = '#000000'; + ctx.textBaseline = 'middle'; + ctx.font = `${fontSize}px "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"`; + // Write each emoji to the canvas vertically + let writeIndex = 0; + testMapKeys.forEach((testKey) => { + const testEntry = testMap[testKey]; + [].concat(testEntry).forEach((emojiUnicode) => { + ctx.fillText(emojiUnicode, 0, (writeIndex * fontSize) + (fontSize / 2)); + writeIndex += 1; + }); + }); + + // Read from the canvas + const resultMap = {}; + let readIndex = 0; + testMapKeys.forEach((testKey) => { + const testEntry = testMap[testKey]; + // This needs to be a `reduce` instead of `every` because we need to + // keep the `readIndex` in sync from the writes by running all entries + const isTestSatisfied = [].concat(testEntry).reduce((isSatisfied) => { + // Sample along the vertical-middle for a couple of characters + const imageData = ctx.getImageData( + 0, + (readIndex * fontSize) + (fontSize / 2), + 2 * fontSize, + 1, + ).data; + + let isValidEmoji = false; + for (let currentPixel = 0; currentPixel < 64; currentPixel += 1) { + const isLookingAtFirstChar = currentPixel < fontSize; + const isLookingAtSecondChar = currentPixel >= (fontSize + (fontSize / 2)); + // Check for the emoji somewhere along the row + if (isLookingAtFirstChar && checkPixelInImageDataArray(currentPixel, imageData)) { + isValidEmoji = true; + + // Check to see that nothing is rendered next to the first character + // to ensure that the ZWJ sequence rendered as one piece + } else if (isLookingAtSecondChar && checkPixelInImageDataArray(currentPixel, imageData)) { + isValidEmoji = false; + break; + } + } + + readIndex += 1; + return isSatisfied && isValidEmoji; + }, true); + + resultMap[testKey] = isTestSatisfied; + }); + + resultMap.meta = { + isChrome, + chromeVersion, + }; + + return resultMap; +} + +let unicodeSupportMap; +const userAgentFromCache = window.localStorage.getItem('gl-emoji-user-agent'); +try { + unicodeSupportMap = JSON.parse(window.localStorage.getItem('gl-emoji-unicode-support-map')); +} catch (err) { + // swallow +} +if (!unicodeSupportMap || userAgentFromCache !== navigator.userAgent) { + unicodeSupportMap = testUnicodeSupportMap(unicodeSupportTestMap); + window.localStorage.setItem('gl-emoji-user-agent', navigator.userAgent); + window.localStorage.setItem('gl-emoji-unicode-support-map', JSON.stringify(unicodeSupportMap)); +} + +module.exports = unicodeSupportMap; diff --git a/app/assets/javascripts/behaviors/toggler_behavior.js b/app/assets/javascripts/behaviors/toggler_behavior.js index a7181904ac9..0726c6c9636 100644 --- a/app/assets/javascripts/behaviors/toggler_behavior.js +++ b/app/assets/javascripts/behaviors/toggler_behavior.js @@ -21,8 +21,7 @@ // %a.js-toggle-button // %div.js-toggle-content // - $('body').on('click', '.js-toggle-button', function(e) { - e.preventDefault(); + $('body').on('click', '.js-toggle-button', function() { toggleContainer($(this).closest('.js-toggle-container')); }); diff --git a/app/assets/javascripts/blob/blob_ci_yaml.js.es6 b/app/assets/javascripts/blob/blob_ci_yaml.js index ec1c018424d..ec1c018424d 100644 --- a/app/assets/javascripts/blob/blob_ci_yaml.js.es6 +++ b/app/assets/javascripts/blob/blob_ci_yaml.js diff --git a/app/assets/javascripts/blob/blob_dockerfile_selector.js.es6 b/app/assets/javascripts/blob/blob_dockerfile_selector.js index d4f60cc6ecd..d4f60cc6ecd 100644 --- a/app/assets/javascripts/blob/blob_dockerfile_selector.js.es6 +++ b/app/assets/javascripts/blob/blob_dockerfile_selector.js diff --git a/app/assets/javascripts/blob/blob_dockerfile_selectors.js.es6 b/app/assets/javascripts/blob/blob_dockerfile_selectors.js index 9cee79fa5d5..9cee79fa5d5 100644 --- a/app/assets/javascripts/blob/blob_dockerfile_selectors.js.es6 +++ b/app/assets/javascripts/blob/blob_dockerfile_selectors.js diff --git a/app/assets/javascripts/blob/blob_license_selectors.js.es6 b/app/assets/javascripts/blob/blob_license_selectors.js index c5067b0feae..c5067b0feae 100644 --- a/app/assets/javascripts/blob/blob_license_selectors.js.es6 +++ b/app/assets/javascripts/blob/blob_license_selectors.js diff --git a/app/assets/javascripts/blob/template_selector.js.es6 b/app/assets/javascripts/blob/template_selector.js index 7e03ec3b391..7e03ec3b391 100644 --- a/app/assets/javascripts/blob/template_selector.js.es6 +++ b/app/assets/javascripts/blob/template_selector.js diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js index 55d13be6e5f..55d13be6e5f 100644 --- a/app/assets/javascripts/boards/boards_bundle.js.es6 +++ b/app/assets/javascripts/boards/boards_bundle.js diff --git a/app/assets/javascripts/boards/components/board.js.es6 b/app/assets/javascripts/boards/components/board.js index 18324de18b3..18324de18b3 100644 --- a/app/assets/javascripts/boards/components/board.js.es6 +++ b/app/assets/javascripts/boards/components/board.js diff --git a/app/assets/javascripts/boards/components/board_blank_state.js.es6 b/app/assets/javascripts/boards/components/board_blank_state.js index d76314c1892..d76314c1892 100644 --- a/app/assets/javascripts/boards/components/board_blank_state.js.es6 +++ b/app/assets/javascripts/boards/components/board_blank_state.js diff --git a/app/assets/javascripts/boards/components/board_delete.js.es6 b/app/assets/javascripts/boards/components/board_delete.js index 861600424a5..861600424a5 100644 --- a/app/assets/javascripts/boards/components/board_delete.js.es6 +++ b/app/assets/javascripts/boards/components/board_delete.js diff --git a/app/assets/javascripts/boards/components/board_list.js.es6 b/app/assets/javascripts/boards/components/board_list.js index 2d52e96e7fb..2d52e96e7fb 100644 --- a/app/assets/javascripts/boards/components/board_list.js.es6 +++ b/app/assets/javascripts/boards/components/board_list.js diff --git a/app/assets/javascripts/boards/components/board_sidebar.js.es6 b/app/assets/javascripts/boards/components/board_sidebar.js index dfc6eed785c..dfc6eed785c 100644 --- a/app/assets/javascripts/boards/components/board_sidebar.js.es6 +++ b/app/assets/javascripts/boards/components/board_sidebar.js diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js.es6 b/app/assets/javascripts/boards/components/issue_card_inner.js index 22a8b971ff8..22a8b971ff8 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.js.es6 +++ b/app/assets/javascripts/boards/components/issue_card_inner.js diff --git a/app/assets/javascripts/boards/components/modal/empty_state.js.es6 b/app/assets/javascripts/boards/components/modal/empty_state.js index 9538f5b69e9..9538f5b69e9 100644 --- a/app/assets/javascripts/boards/components/modal/empty_state.js.es6 +++ b/app/assets/javascripts/boards/components/modal/empty_state.js diff --git a/app/assets/javascripts/boards/components/modal/filters.js.es6 b/app/assets/javascripts/boards/components/modal/filters.js index 6de06811d94..6de06811d94 100644 --- a/app/assets/javascripts/boards/components/modal/filters.js.es6 +++ b/app/assets/javascripts/boards/components/modal/filters.js diff --git a/app/assets/javascripts/boards/components/modal/filters/label.js.es6 b/app/assets/javascripts/boards/components/modal/filters/label.js index 4fc8f72a145..4fc8f72a145 100644 --- a/app/assets/javascripts/boards/components/modal/filters/label.js.es6 +++ b/app/assets/javascripts/boards/components/modal/filters/label.js diff --git a/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6 b/app/assets/javascripts/boards/components/modal/filters/milestone.js index d555599d300..d555599d300 100644 --- a/app/assets/javascripts/boards/components/modal/filters/milestone.js.es6 +++ b/app/assets/javascripts/boards/components/modal/filters/milestone.js diff --git a/app/assets/javascripts/boards/components/modal/filters/user.js.es6 b/app/assets/javascripts/boards/components/modal/filters/user.js index 8523028c29c..8523028c29c 100644 --- a/app/assets/javascripts/boards/components/modal/filters/user.js.es6 +++ b/app/assets/javascripts/boards/components/modal/filters/user.js diff --git a/app/assets/javascripts/boards/components/modal/footer.js.es6 b/app/assets/javascripts/boards/components/modal/footer.js index 1cbc422c961..1cbc422c961 100644 --- a/app/assets/javascripts/boards/components/modal/footer.js.es6 +++ b/app/assets/javascripts/boards/components/modal/footer.js diff --git a/app/assets/javascripts/boards/components/modal/header.js.es6 b/app/assets/javascripts/boards/components/modal/header.js index 70c088f9054..70c088f9054 100644 --- a/app/assets/javascripts/boards/components/modal/header.js.es6 +++ b/app/assets/javascripts/boards/components/modal/header.js diff --git a/app/assets/javascripts/boards/components/modal/index.js.es6 b/app/assets/javascripts/boards/components/modal/index.js index f290cd13763..f290cd13763 100644 --- a/app/assets/javascripts/boards/components/modal/index.js.es6 +++ b/app/assets/javascripts/boards/components/modal/index.js diff --git a/app/assets/javascripts/boards/components/modal/list.js.es6 b/app/assets/javascripts/boards/components/modal/list.js index 3730c1ecaeb..3730c1ecaeb 100644 --- a/app/assets/javascripts/boards/components/modal/list.js.es6 +++ b/app/assets/javascripts/boards/components/modal/list.js diff --git a/app/assets/javascripts/boards/components/modal/lists_dropdown.js.es6 b/app/assets/javascripts/boards/components/modal/lists_dropdown.js index 3c05120a2da..3c05120a2da 100644 --- a/app/assets/javascripts/boards/components/modal/lists_dropdown.js.es6 +++ b/app/assets/javascripts/boards/components/modal/lists_dropdown.js diff --git a/app/assets/javascripts/boards/components/modal/tabs.js.es6 b/app/assets/javascripts/boards/components/modal/tabs.js index e8cb43f3503..e8cb43f3503 100644 --- a/app/assets/javascripts/boards/components/modal/tabs.js.es6 +++ b/app/assets/javascripts/boards/components/modal/tabs.js diff --git a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 b/app/assets/javascripts/boards/components/new_list_dropdown.js index 556826a9148..556826a9148 100644 --- a/app/assets/javascripts/boards/components/new_list_dropdown.js.es6 +++ b/app/assets/javascripts/boards/components/new_list_dropdown.js diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.js.es6 b/app/assets/javascripts/boards/components/sidebar/remove_issue.js index e74935e1cb0..e74935e1cb0 100644 --- a/app/assets/javascripts/boards/components/sidebar/remove_issue.js.es6 +++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.js diff --git a/app/assets/javascripts/boards/filters/due_date_filters.js.es6 b/app/assets/javascripts/boards/filters/due_date_filters.js index 03425bb145b..03425bb145b 100644 --- a/app/assets/javascripts/boards/filters/due_date_filters.js.es6 +++ b/app/assets/javascripts/boards/filters/due_date_filters.js diff --git a/app/assets/javascripts/boards/mixins/modal_mixins.js.es6 b/app/assets/javascripts/boards/mixins/modal_mixins.js index d378b7d4baf..d378b7d4baf 100644 --- a/app/assets/javascripts/boards/mixins/modal_mixins.js.es6 +++ b/app/assets/javascripts/boards/mixins/modal_mixins.js diff --git a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6 b/app/assets/javascripts/boards/mixins/sortable_default_options.js index b6c6d17274f..b6c6d17274f 100644 --- a/app/assets/javascripts/boards/mixins/sortable_default_options.js.es6 +++ b/app/assets/javascripts/boards/mixins/sortable_default_options.js diff --git a/app/assets/javascripts/boards/models/issue.js.es6 b/app/assets/javascripts/boards/models/issue.js index 2d0a295ae4d..2d0a295ae4d 100644 --- a/app/assets/javascripts/boards/models/issue.js.es6 +++ b/app/assets/javascripts/boards/models/issue.js diff --git a/app/assets/javascripts/boards/models/label.js.es6 b/app/assets/javascripts/boards/models/label.js index 9af88d167d6..9af88d167d6 100644 --- a/app/assets/javascripts/boards/models/label.js.es6 +++ b/app/assets/javascripts/boards/models/label.js diff --git a/app/assets/javascripts/boards/models/list.js.es6 b/app/assets/javascripts/boards/models/list.js index 8158ed4ec2c..8158ed4ec2c 100644 --- a/app/assets/javascripts/boards/models/list.js.es6 +++ b/app/assets/javascripts/boards/models/list.js diff --git a/app/assets/javascripts/boards/models/milestone.js.es6 b/app/assets/javascripts/boards/models/milestone.js index c867b06d320..c867b06d320 100644 --- a/app/assets/javascripts/boards/models/milestone.js.es6 +++ b/app/assets/javascripts/boards/models/milestone.js diff --git a/app/assets/javascripts/boards/models/user.js.es6 b/app/assets/javascripts/boards/models/user.js index 8e9de4d4cbb..8e9de4d4cbb 100644 --- a/app/assets/javascripts/boards/models/user.js.es6 +++ b/app/assets/javascripts/boards/models/user.js diff --git a/app/assets/javascripts/boards/services/board_service.js.es6 b/app/assets/javascripts/boards/services/board_service.js index 065e90518df..065e90518df 100644 --- a/app/assets/javascripts/boards/services/board_service.js.es6 +++ b/app/assets/javascripts/boards/services/board_service.js diff --git a/app/assets/javascripts/boards/stores/boards_store.js.es6 b/app/assets/javascripts/boards/stores/boards_store.js index 56436c8fdc7..56436c8fdc7 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js.es6 +++ b/app/assets/javascripts/boards/stores/boards_store.js diff --git a/app/assets/javascripts/boards/stores/modal_store.js.es6 b/app/assets/javascripts/boards/stores/modal_store.js index 15fc6c79e8d..15fc6c79e8d 100644 --- a/app/assets/javascripts/boards/stores/modal_store.js.es6 +++ b/app/assets/javascripts/boards/stores/modal_store.js diff --git a/app/assets/javascripts/build_variables.js.es6 b/app/assets/javascripts/build_variables.js index 99082b412e2..99082b412e2 100644 --- a/app/assets/javascripts/build_variables.js.es6 +++ b/app/assets/javascripts/build_variables.js diff --git a/app/assets/javascripts/ci_lint_editor.js.es6 b/app/assets/javascripts/ci_lint_editor.js index 56ffaa765a8..56ffaa765a8 100644 --- a/app/assets/javascripts/ci_lint_editor.js.es6 +++ b/app/assets/javascripts/ci_lint_editor.js diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js index b5a988df897..b5a988df897 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6 +++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js diff --git a/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_service.js index 8ae98f9bf97..8ae98f9bf97 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_service.js.es6 +++ b/app/assets/javascripts/commit/pipelines/pipelines_service.js diff --git a/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_store.js index f1b80e45444..f1b80e45444 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_store.js.es6 +++ b/app/assets/javascripts/commit/pipelines/pipelines_store.js diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js new file mode 100644 index 00000000000..631ed34851c --- /dev/null +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.js @@ -0,0 +1,104 @@ +/* eslint-disable no-new, no-param-reassign */ +/* global Vue, CommitsPipelineStore, PipelinesService, Flash */ + +window.Vue = require('vue'); +window.Vue.use(require('vue-resource')); +require('../../lib/utils/common_utils'); +require('../../vue_shared/vue_resource_interceptor'); +require('../../vue_shared/components/pipelines_table'); +require('./pipelines_service'); +const PipelineStore = require('./pipelines_store'); + +/** + * + * Uses `pipelines-table-component` to render Pipelines table with an API call. + * Endpoint is provided in HTML and passed as `endpoint`. + * We need a store to store the received environemnts. + * We need a service to communicate with the server. + * + * Necessary SVG in the table are provided as props. This should be refactored + * as soon as we have Webpack and can load them directly into JS files. + */ + +(() => { + window.gl = window.gl || {}; + gl.commits = gl.commits || {}; + gl.commits.pipelines = gl.commits.pipelines || {}; + + gl.commits.pipelines.PipelinesTableView = Vue.component('pipelines-table', { + + components: { + 'pipelines-table-component': gl.pipelines.PipelinesTableComponent, + }, + + /** + * Accesses the DOM to provide the needed data. + * Returns the necessary props to render `pipelines-table-component` component. + * + * @return {Object} + */ + data() { + const pipelinesTableData = document.querySelector('#commit-pipeline-table-view').dataset; + const store = new PipelineStore(); + + return { + endpoint: pipelinesTableData.endpoint, + store, + state: store.state, + isLoading: false, + }; + }, + + /** + * When the component is about to be mounted, tell the service to fetch the data + * + * A request to fetch the pipelines will be made. + * In case of a successfull response we will store the data in the provided + * store, in case of a failed response we need to warn the user. + * + */ + beforeMount() { + const pipelinesService = new gl.commits.pipelines.PipelinesService(this.endpoint); + + this.isLoading = true; + return pipelinesService.all() + .then(response => response.json()) + .then((json) => { + // depending of the endpoint the response can either bring a `pipelines` key or not. + const pipelines = json.pipelines || json; + this.store.storePipelines(pipelines); + this.isLoading = false; + }) + .catch(() => { + this.isLoading = false; + new Flash('An error occurred while fetching the pipelines, please reload the page again.', 'alert'); + }); + }, + + beforeUpdate() { + if (this.state.pipelines.length && this.$children) { + PipelineStore.startTimeAgoLoops.call(this, Vue); + } + }, + + template: ` + <div class="pipelines"> + <div class="realtime-loading" v-if="isLoading"> + <i class="fa fa-spinner fa-spin"></i> + </div> + + <div class="blank-state blank-state-no-icon" + v-if="!isLoading && state.pipelines.length === 0"> + <h2 class="blank-state-title js-blank-state-title"> + No pipelines to show + </h2> + </div> + + <div class="table-holder pipelines" + v-if="!isLoading && state.pipelines.length > 0"> + <pipelines-table-component :pipelines="state.pipelines"/> + </div> + </div> + `, + }); +})(); diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js.es6 b/app/assets/javascripts/commit/pipelines/pipelines_table.js.es6 deleted file mode 100644 index cd2bd883d32..00000000000 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.js.es6 +++ /dev/null @@ -1,112 +0,0 @@ -/* eslint-disable no-new, no-param-reassign */ -/* global Vue, CommitsPipelineStore, PipelinesService, Flash */ - -window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -require('../../lib/utils/common_utils'); -require('../../vue_shared/vue_resource_interceptor'); -require('../../vue_shared/components/pipelines_table'); -require('./pipelines_service'); -const PipelineStore = require('./pipelines_store'); - -/** - * - * Uses `pipelines-table-component` to render Pipelines table with an API call. - * Endpoint is provided in HTML and passed as `endpoint`. - * We need a store to store the received environemnts. - * We need a service to communicate with the server. - * - * Necessary SVG in the table are provided as props. This should be refactored - * as soon as we have Webpack and can load them directly into JS files. - */ - -(() => { - window.gl = window.gl || {}; - gl.commits = gl.commits || {}; - gl.commits.pipelines = gl.commits.pipelines || {}; - - gl.commits.pipelines.PipelinesTableView = Vue.component('pipelines-table', { - - components: { - 'pipelines-table-component': gl.pipelines.PipelinesTableComponent, - }, - - /** - * Accesses the DOM to provide the needed data. - * Returns the necessary props to render `pipelines-table-component` component. - * - * @return {Object} - */ - data() { - const pipelinesTableData = document.querySelector('#commit-pipeline-table-view').dataset; - const svgsData = document.querySelector('.pipeline-svgs').dataset; - const store = new PipelineStore(); - - // Transform svgs DOMStringMap to a plain Object. - const svgsObject = gl.utils.DOMStringMapToObject(svgsData); - - return { - endpoint: pipelinesTableData.endpoint, - svgs: svgsObject, - store, - state: store.state, - isLoading: false, - }; - }, - - /** - * When the component is about to be mounted, tell the service to fetch the data - * - * A request to fetch the pipelines will be made. - * In case of a successfull response we will store the data in the provided - * store, in case of a failed response we need to warn the user. - * - */ - beforeMount() { - const pipelinesService = new gl.commits.pipelines.PipelinesService(this.endpoint); - - this.isLoading = true; - return pipelinesService.all() - .then(response => response.json()) - .then((json) => { - // depending of the endpoint the response can either bring a `pipelines` key or not. - const pipelines = json.pipelines || json; - this.store.storePipelines(pipelines); - this.isLoading = false; - }) - .catch(() => { - this.isLoading = false; - new Flash('An error occurred while fetching the pipelines, please reload the page again.', 'alert'); - }); - }, - - beforeUpdate() { - if (this.state.pipelines.length && this.$children) { - PipelineStore.startTimeAgoLoops.call(this, Vue); - } - }, - - template: ` - <div class="pipelines"> - <div class="realtime-loading" v-if="isLoading"> - <i class="fa fa-spinner fa-spin"></i> - </div> - - <div class="blank-state blank-state-no-icon" - v-if="!isLoading && state.pipelines.length === 0"> - <h2 class="blank-state-title js-blank-state-title"> - No pipelines to show - </h2> - </div> - - <div class="table-holder pipelines" - v-if="!isLoading && state.pipelines.length > 0"> - <pipelines-table-component - :pipelines="state.pipelines" - :svgs="svgs"> - </pipelines-table-component> - </div> - </div> - `, - }); -})(); diff --git a/app/assets/javascripts/commons/bootstrap.js b/app/assets/javascripts/commons/bootstrap.js new file mode 100644 index 00000000000..db0cbfd87c3 --- /dev/null +++ b/app/assets/javascripts/commons/bootstrap.js @@ -0,0 +1,10 @@ +import 'jquery'; + +// bootstrap jQuery plugins +import 'bootstrap-sass/assets/javascripts/bootstrap/affix'; +import 'bootstrap-sass/assets/javascripts/bootstrap/alert'; +import 'bootstrap-sass/assets/javascripts/bootstrap/dropdown'; +import 'bootstrap-sass/assets/javascripts/bootstrap/modal'; +import 'bootstrap-sass/assets/javascripts/bootstrap/tab'; +import 'bootstrap-sass/assets/javascripts/bootstrap/transition'; +import 'bootstrap-sass/assets/javascripts/bootstrap/tooltip'; diff --git a/app/assets/javascripts/commons/index.js b/app/assets/javascripts/commons/index.js new file mode 100644 index 00000000000..72ede1d621a --- /dev/null +++ b/app/assets/javascripts/commons/index.js @@ -0,0 +1,2 @@ +import './jquery'; +import './bootstrap'; diff --git a/app/assets/javascripts/commons/jquery.js b/app/assets/javascripts/commons/jquery.js new file mode 100644 index 00000000000..b53f6284afc --- /dev/null +++ b/app/assets/javascripts/commons/jquery.js @@ -0,0 +1,11 @@ +import 'jquery'; + +// common jQuery plugins +import 'jquery-ujs'; +import 'vendor/jquery.endless-scroll'; +import 'vendor/jquery.caret'; +import 'vendor/jquery.atwho'; +import 'vendor/jquery.scrollTo'; +import 'vendor/jquery.nicescroll'; +import 'vendor/jquery.waitforimages'; +import 'select2/select2'; diff --git a/app/assets/javascripts/compare_autocomplete.js.es6 b/app/assets/javascripts/compare_autocomplete.js index 1eca973e069..1eca973e069 100644 --- a/app/assets/javascripts/compare_autocomplete.js.es6 +++ b/app/assets/javascripts/compare_autocomplete.js diff --git a/app/assets/javascripts/copy_as_gfm.js b/app/assets/javascripts/copy_as_gfm.js new file mode 100644 index 00000000000..8883c339335 --- /dev/null +++ b/app/assets/javascripts/copy_as_gfm.js @@ -0,0 +1,364 @@ +/* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */ +/* jshint esversion: 6 */ + +require('./lib/utils/common_utils'); + +(() => { + const gfmRules = { + // The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert + // GitLab Flavored Markdown (GFM) to HTML. + // These handlers consequently convert that same HTML to GFM to be copied to the clipboard. + // Every filter in lib/banzai/pipeline/gfm_pipeline.rb that generates HTML + // from GFM should have a handler here, in reverse order. + // The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb. + InlineDiffFilter: { + 'span.idiff.addition'(el, text) { + return `{+${text}+}`; + }, + 'span.idiff.deletion'(el, text) { + return `{-${text}-}`; + }, + }, + TaskListFilter: { + 'input[type=checkbox].task-list-item-checkbox'(el, text) { + return `[${el.checked ? 'x' : ' '}]`; + }, + }, + ReferenceFilter: { + '.tooltip'(el, text) { + return ''; + }, + 'a.gfm:not([data-link=true])'(el, text) { + return el.dataset.original || text; + }, + }, + AutolinkFilter: { + 'a'(el, text) { + // Fallback on the regular MarkdownFilter's `a` handler. + if (text !== el.getAttribute('href')) return false; + + return text; + }, + }, + TableOfContentsFilter: { + 'ul.section-nav'(el, text) { + return '[[_TOC_]]'; + }, + }, + EmojiFilter: { + 'img.emoji'(el, text) { + return el.getAttribute('alt'); + }, + 'gl-emoji'(el, text) { + return `:${el.getAttribute('data-name')}:`; + }, + }, + ImageLinkFilter: { + 'a.no-attachment-icon'(el, text) { + return text; + }, + }, + VideoLinkFilter: { + '.video-container'(el, text) { + const videoEl = el.querySelector('video'); + if (!videoEl) return false; + + return CopyAsGFM.nodeToGFM(videoEl); + }, + 'video'(el, text) { + return `![${el.dataset.title}](${el.getAttribute('src')})`; + }, + }, + MathFilter: { + 'pre.code.math[data-math-style=display]'(el, text) { + return `\`\`\`math\n${text.trim()}\n\`\`\``; + }, + 'code.code.math[data-math-style=inline]'(el, text) { + return `$\`${text}\`$`; + }, + 'span.katex-display span.katex-mathml'(el, text) { + const mathAnnotation = el.querySelector('annotation[encoding="application/x-tex"]'); + if (!mathAnnotation) return false; + + return `\`\`\`math\n${CopyAsGFM.nodeToGFM(mathAnnotation)}\n\`\`\``; + }, + 'span.katex-mathml'(el, text) { + const mathAnnotation = el.querySelector('annotation[encoding="application/x-tex"]'); + if (!mathAnnotation) return false; + + return `$\`${CopyAsGFM.nodeToGFM(mathAnnotation)}\`$`; + }, + 'span.katex-html'(el, text) { + // We don't want to include the content of this element in the copied text. + return ''; + }, + 'annotation[encoding="application/x-tex"]'(el, text) { + return text.trim(); + }, + }, + SanitizationFilter: { + 'a[name]:not([href]):empty'(el, text) { + return el.outerHTML; + }, + 'dl'(el, text) { + let lines = text.trim().split('\n'); + // Add two spaces to the front of subsequent list items lines, + // or leave the line entirely blank. + lines = lines.map((l) => { + const line = l.trim(); + if (line.length === 0) return ''; + + return ` ${line}`; + }); + + return `<dl>\n${lines.join('\n')}\n</dl>`; + }, + 'sub, dt, dd, kbd, q, samp, var, ruby, rt, rp, abbr, summary, details'(el, text) { + const tag = el.nodeName.toLowerCase(); + return `<${tag}>${text}</${tag}>`; + }, + }, + SyntaxHighlightFilter: { + 'pre.code.highlight'(el, t) { + const text = t.trim(); + + let lang = el.getAttribute('lang'); + if (lang === 'plaintext') { + lang = ''; + } + + // Prefixes lines with 4 spaces if the code contains triple backticks + if (lang === '' && text.match(/^```/gm)) { + return text.split('\n').map((l) => { + const line = l.trim(); + if (line.length === 0) return ''; + + return ` ${line}`; + }).join('\n'); + } + + return `\`\`\`${lang}\n${text}\n\`\`\``; + }, + 'pre > code'(el, text) { + // Don't wrap code blocks in `` + return text; + }, + }, + MarkdownFilter: { + 'br'(el, text) { + // Two spaces at the end of a line are turned into a BR + return ' '; + }, + 'code'(el, text) { + let backtickCount = 1; + const backtickMatch = text.match(/`+/); + if (backtickMatch) { + backtickCount = backtickMatch[0].length + 1; + } + + const backticks = Array(backtickCount + 1).join('`'); + const spaceOrNoSpace = backtickCount > 1 ? ' ' : ''; + + return backticks + spaceOrNoSpace + text + spaceOrNoSpace + backticks; + }, + 'blockquote'(el, text) { + return text.trim().split('\n').map(s => `> ${s}`.trim()).join('\n'); + }, + 'img'(el, text) { + return `![${el.getAttribute('alt')}](${el.getAttribute('src')})`; + }, + 'a.anchor'(el, text) { + // Don't render a Markdown link for the anchor link inside a heading + return text; + }, + 'a'(el, text) { + return `[${text}](${el.getAttribute('href')})`; + }, + 'li'(el, text) { + const lines = text.trim().split('\n'); + const firstLine = `- ${lines.shift()}`; + // Add four spaces to the front of subsequent list items lines, + // or leave the line entirely blank. + const nextLines = lines.map((s) => { + if (s.trim().length === 0) return ''; + + return ` ${s}`; + }); + + return `${firstLine}\n${nextLines.join('\n')}`; + }, + 'ul'(el, text) { + return text; + }, + 'ol'(el, text) { + // LIs get a `- ` prefix by default, which we replace by `1. ` for ordered lists. + return text.replace(/^- /mg, '1. '); + }, + 'h1'(el, text) { + return `# ${text.trim()}`; + }, + 'h2'(el, text) { + return `## ${text.trim()}`; + }, + 'h3'(el, text) { + return `### ${text.trim()}`; + }, + 'h4'(el, text) { + return `#### ${text.trim()}`; + }, + 'h5'(el, text) { + return `##### ${text.trim()}`; + }, + 'h6'(el, text) { + return `###### ${text.trim()}`; + }, + 'strong'(el, text) { + return `**${text}**`; + }, + 'em'(el, text) { + return `_${text}_`; + }, + 'del'(el, text) { + return `~~${text}~~`; + }, + 'sup'(el, text) { + return `^${text}`; + }, + 'hr'(el, text) { + return '-----'; + }, + 'table'(el, text) { + const theadEl = el.querySelector('thead'); + const tbodyEl = el.querySelector('tbody'); + if (!theadEl || !tbodyEl) return false; + + const theadText = CopyAsGFM.nodeToGFM(theadEl); + const tbodyText = CopyAsGFM.nodeToGFM(tbodyEl); + + return theadText + tbodyText; + }, + 'thead'(el, text) { + const cells = _.map(el.querySelectorAll('th'), (cell) => { + let chars = CopyAsGFM.nodeToGFM(cell).trim().length + 2; + + let before = ''; + let after = ''; + switch (cell.style.textAlign) { + case 'center': + before = ':'; + after = ':'; + chars -= 2; + break; + case 'right': + after = ':'; + chars -= 1; + break; + default: + break; + } + + chars = Math.max(chars, 3); + + const middle = Array(chars + 1).join('-'); + + return before + middle + after; + }); + + return `${text}|${cells.join('|')}|`; + }, + 'tr'(el, text) { + const cells = _.map(el.querySelectorAll('td, th'), cell => CopyAsGFM.nodeToGFM(cell).trim()); + return `| ${cells.join(' | ')} |`; + }, + }, + }; + + class CopyAsGFM { + constructor() { + $(document).on('copy', '.md, .wiki', this.handleCopy); + $(document).on('paste', '.js-gfm-input', this.handlePaste); + } + + handleCopy(e) { + const clipboardData = e.originalEvent.clipboardData; + if (!clipboardData) return; + + const documentFragment = window.gl.utils.getSelectedFragment(); + if (!documentFragment) return; + + // If the documentFragment contains more than just Markdown, don't copy as GFM. + if (documentFragment.querySelector('.md, .wiki')) return; + + e.preventDefault(); + clipboardData.setData('text/plain', documentFragment.textContent); + + const gfm = CopyAsGFM.nodeToGFM(documentFragment); + clipboardData.setData('text/x-gfm', gfm); + } + + handlePaste(e) { + const clipboardData = e.originalEvent.clipboardData; + if (!clipboardData) return; + + const gfm = clipboardData.getData('text/x-gfm'); + if (!gfm) return; + + e.preventDefault(); + + window.gl.utils.insertText(e.target, gfm); + } + + static nodeToGFM(node) { + if (node.nodeType === Node.TEXT_NODE) { + return node.textContent; + } + + const text = this.innerGFM(node); + + if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { + return text; + } + + for (const filter in gfmRules) { + const rules = gfmRules[filter]; + + for (const selector in rules) { + const func = rules[selector]; + + if (!window.gl.utils.nodeMatchesSelector(node, selector)) continue; + + const result = func(node, text); + if (result === false) continue; + + return result; + } + } + + return text; + } + + static innerGFM(parentNode) { + const nodes = parentNode.childNodes; + + const clonedParentNode = parentNode.cloneNode(true); + const clonedNodes = Array.prototype.slice.call(clonedParentNode.childNodes, 0); + + for (let i = 0; i < nodes.length; i += 1) { + const node = nodes[i]; + const clonedNode = clonedNodes[i]; + + const text = this.nodeToGFM(node); + + // `clonedNode.replaceWith(text)` is not yet widely supported + clonedNode.parentNode.replaceChild(document.createTextNode(text), clonedNode); + } + + return clonedParentNode.innerText || clonedParentNode.textContent; + } + } + + window.gl = window.gl || {}; + window.gl.CopyAsGFM = CopyAsGFM; + + new CopyAsGFM(); +})(); diff --git a/app/assets/javascripts/copy_as_gfm.js.es6 b/app/assets/javascripts/copy_as_gfm.js.es6 deleted file mode 100644 index 2bc3d85fba4..00000000000 --- a/app/assets/javascripts/copy_as_gfm.js.es6 +++ /dev/null @@ -1,361 +0,0 @@ -/* eslint-disable class-methods-use-this, object-shorthand, no-unused-vars, no-use-before-define, no-new, max-len, no-restricted-syntax, guard-for-in, no-continue */ -/* jshint esversion: 6 */ - -require('./lib/utils/common_utils'); - -(() => { - const gfmRules = { - // The filters referenced in lib/banzai/pipeline/gfm_pipeline.rb convert - // GitLab Flavored Markdown (GFM) to HTML. - // These handlers consequently convert that same HTML to GFM to be copied to the clipboard. - // Every filter in lib/banzai/pipeline/gfm_pipeline.rb that generates HTML - // from GFM should have a handler here, in reverse order. - // The GFM-to-HTML-to-GFM cycle is tested in spec/features/copy_as_gfm_spec.rb. - InlineDiffFilter: { - 'span.idiff.addition'(el, text) { - return `{+${text}+}`; - }, - 'span.idiff.deletion'(el, text) { - return `{-${text}-}`; - }, - }, - TaskListFilter: { - 'input[type=checkbox].task-list-item-checkbox'(el, text) { - return `[${el.checked ? 'x' : ' '}]`; - }, - }, - ReferenceFilter: { - '.tooltip'(el, text) { - return ''; - }, - 'a.gfm:not([data-link=true])'(el, text) { - return el.dataset.original || text; - }, - }, - AutolinkFilter: { - 'a'(el, text) { - // Fallback on the regular MarkdownFilter's `a` handler. - if (text !== el.getAttribute('href')) return false; - - return text; - }, - }, - TableOfContentsFilter: { - 'ul.section-nav'(el, text) { - return '[[_TOC_]]'; - }, - }, - EmojiFilter: { - 'img.emoji'(el, text) { - return el.getAttribute('alt'); - }, - }, - ImageLinkFilter: { - 'a.no-attachment-icon'(el, text) { - return text; - }, - }, - VideoLinkFilter: { - '.video-container'(el, text) { - const videoEl = el.querySelector('video'); - if (!videoEl) return false; - - return CopyAsGFM.nodeToGFM(videoEl); - }, - 'video'(el, text) { - return `![${el.dataset.title}](${el.getAttribute('src')})`; - }, - }, - MathFilter: { - 'pre.code.math[data-math-style=display]'(el, text) { - return `\`\`\`math\n${text.trim()}\n\`\`\``; - }, - 'code.code.math[data-math-style=inline]'(el, text) { - return `$\`${text}\`$`; - }, - 'span.katex-display span.katex-mathml'(el, text) { - const mathAnnotation = el.querySelector('annotation[encoding="application/x-tex"]'); - if (!mathAnnotation) return false; - - return `\`\`\`math\n${CopyAsGFM.nodeToGFM(mathAnnotation)}\n\`\`\``; - }, - 'span.katex-mathml'(el, text) { - const mathAnnotation = el.querySelector('annotation[encoding="application/x-tex"]'); - if (!mathAnnotation) return false; - - return `$\`${CopyAsGFM.nodeToGFM(mathAnnotation)}\`$`; - }, - 'span.katex-html'(el, text) { - // We don't want to include the content of this element in the copied text. - return ''; - }, - 'annotation[encoding="application/x-tex"]'(el, text) { - return text.trim(); - }, - }, - SanitizationFilter: { - 'a[name]:not([href]):empty'(el, text) { - return el.outerHTML; - }, - 'dl'(el, text) { - let lines = text.trim().split('\n'); - // Add two spaces to the front of subsequent list items lines, - // or leave the line entirely blank. - lines = lines.map((l) => { - const line = l.trim(); - if (line.length === 0) return ''; - - return ` ${line}`; - }); - - return `<dl>\n${lines.join('\n')}\n</dl>`; - }, - 'sub, dt, dd, kbd, q, samp, var, ruby, rt, rp, abbr'(el, text) { - const tag = el.nodeName.toLowerCase(); - return `<${tag}>${text}</${tag}>`; - }, - }, - SyntaxHighlightFilter: { - 'pre.code.highlight'(el, t) { - const text = t.trim(); - - let lang = el.getAttribute('lang'); - if (lang === 'plaintext') { - lang = ''; - } - - // Prefixes lines with 4 spaces if the code contains triple backticks - if (lang === '' && text.match(/^```/gm)) { - return text.split('\n').map((l) => { - const line = l.trim(); - if (line.length === 0) return ''; - - return ` ${line}`; - }).join('\n'); - } - - return `\`\`\`${lang}\n${text}\n\`\`\``; - }, - 'pre > code'(el, text) { - // Don't wrap code blocks in `` - return text; - }, - }, - MarkdownFilter: { - 'br'(el, text) { - // Two spaces at the end of a line are turned into a BR - return ' '; - }, - 'code'(el, text) { - let backtickCount = 1; - const backtickMatch = text.match(/`+/); - if (backtickMatch) { - backtickCount = backtickMatch[0].length + 1; - } - - const backticks = Array(backtickCount + 1).join('`'); - const spaceOrNoSpace = backtickCount > 1 ? ' ' : ''; - - return backticks + spaceOrNoSpace + text + spaceOrNoSpace + backticks; - }, - 'blockquote'(el, text) { - return text.trim().split('\n').map(s => `> ${s}`.trim()).join('\n'); - }, - 'img'(el, text) { - return `![${el.getAttribute('alt')}](${el.getAttribute('src')})`; - }, - 'a.anchor'(el, text) { - // Don't render a Markdown link for the anchor link inside a heading - return text; - }, - 'a'(el, text) { - return `[${text}](${el.getAttribute('href')})`; - }, - 'li'(el, text) { - const lines = text.trim().split('\n'); - const firstLine = `- ${lines.shift()}`; - // Add four spaces to the front of subsequent list items lines, - // or leave the line entirely blank. - const nextLines = lines.map((s) => { - if (s.trim().length === 0) return ''; - - return ` ${s}`; - }); - - return `${firstLine}\n${nextLines.join('\n')}`; - }, - 'ul'(el, text) { - return text; - }, - 'ol'(el, text) { - // LIs get a `- ` prefix by default, which we replace by `1. ` for ordered lists. - return text.replace(/^- /mg, '1. '); - }, - 'h1'(el, text) { - return `# ${text.trim()}`; - }, - 'h2'(el, text) { - return `## ${text.trim()}`; - }, - 'h3'(el, text) { - return `### ${text.trim()}`; - }, - 'h4'(el, text) { - return `#### ${text.trim()}`; - }, - 'h5'(el, text) { - return `##### ${text.trim()}`; - }, - 'h6'(el, text) { - return `###### ${text.trim()}`; - }, - 'strong'(el, text) { - return `**${text}**`; - }, - 'em'(el, text) { - return `_${text}_`; - }, - 'del'(el, text) { - return `~~${text}~~`; - }, - 'sup'(el, text) { - return `^${text}`; - }, - 'hr'(el, text) { - return '-----'; - }, - 'table'(el, text) { - const theadEl = el.querySelector('thead'); - const tbodyEl = el.querySelector('tbody'); - if (!theadEl || !tbodyEl) return false; - - const theadText = CopyAsGFM.nodeToGFM(theadEl); - const tbodyText = CopyAsGFM.nodeToGFM(tbodyEl); - - return theadText + tbodyText; - }, - 'thead'(el, text) { - const cells = _.map(el.querySelectorAll('th'), (cell) => { - let chars = CopyAsGFM.nodeToGFM(cell).trim().length + 2; - - let before = ''; - let after = ''; - switch (cell.style.textAlign) { - case 'center': - before = ':'; - after = ':'; - chars -= 2; - break; - case 'right': - after = ':'; - chars -= 1; - break; - default: - break; - } - - chars = Math.max(chars, 3); - - const middle = Array(chars + 1).join('-'); - - return before + middle + after; - }); - - return `${text}|${cells.join('|')}|`; - }, - 'tr'(el, text) { - const cells = _.map(el.querySelectorAll('td, th'), cell => CopyAsGFM.nodeToGFM(cell).trim()); - return `| ${cells.join(' | ')} |`; - }, - }, - }; - - class CopyAsGFM { - constructor() { - $(document).on('copy', '.md, .wiki', this.handleCopy); - $(document).on('paste', '.js-gfm-input', this.handlePaste); - } - - handleCopy(e) { - const clipboardData = e.originalEvent.clipboardData; - if (!clipboardData) return; - - const documentFragment = window.gl.utils.getSelectedFragment(); - if (!documentFragment) return; - - // If the documentFragment contains more than just Markdown, don't copy as GFM. - if (documentFragment.querySelector('.md, .wiki')) return; - - e.preventDefault(); - clipboardData.setData('text/plain', documentFragment.textContent); - - const gfm = CopyAsGFM.nodeToGFM(documentFragment); - clipboardData.setData('text/x-gfm', gfm); - } - - handlePaste(e) { - const clipboardData = e.originalEvent.clipboardData; - if (!clipboardData) return; - - const gfm = clipboardData.getData('text/x-gfm'); - if (!gfm) return; - - e.preventDefault(); - - window.gl.utils.insertText(e.target, gfm); - } - - static nodeToGFM(node) { - if (node.nodeType === Node.TEXT_NODE) { - return node.textContent; - } - - const text = this.innerGFM(node); - - if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) { - return text; - } - - for (const filter in gfmRules) { - const rules = gfmRules[filter]; - - for (const selector in rules) { - const func = rules[selector]; - - if (!window.gl.utils.nodeMatchesSelector(node, selector)) continue; - - const result = func(node, text); - if (result === false) continue; - - return result; - } - } - - return text; - } - - static innerGFM(parentNode) { - const nodes = parentNode.childNodes; - - const clonedParentNode = parentNode.cloneNode(true); - const clonedNodes = Array.prototype.slice.call(clonedParentNode.childNodes, 0); - - for (let i = 0; i < nodes.length; i += 1) { - const node = nodes[i]; - const clonedNode = clonedNodes[i]; - - const text = this.nodeToGFM(node); - - // `clonedNode.replaceWith(text)` is not yet widely supported - clonedNode.parentNode.replaceChild(document.createTextNode(text), clonedNode); - } - - return clonedParentNode.innerText || clonedParentNode.textContent; - } - } - - window.gl = window.gl || {}; - window.gl.CopyAsGFM = CopyAsGFM; - - new CopyAsGFM(); -})(); diff --git a/app/assets/javascripts/create_label.js.es6 b/app/assets/javascripts/create_label.js index 85384d98126..85384d98126 100644 --- a/app/assets/javascripts/create_label.js.es6 +++ b/app/assets/javascripts/create_label.js diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js index b83a4c63fad..b83a4c63fad 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6 +++ b/app/assets/javascripts/cycle_analytics/components/stage_code_component.js diff --git a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js index cb1687dcc7a..cb1687dcc7a 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6 +++ b/app/assets/javascripts/cycle_analytics/components/stage_issue_component.js diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js new file mode 100644 index 00000000000..42e1bbce744 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js @@ -0,0 +1,56 @@ +/* eslint-disable no-param-reassign */ +import Vue from 'vue'; +import iconCommit from '../svg/icon_commit.svg'; + +((global) => { + global.cycleAnalytics = global.cycleAnalytics || {}; + + global.cycleAnalytics.StagePlanComponent = Vue.extend({ + props: { + items: Array, + stage: Object, + }, + + data() { + return { iconCommit }; + }, + + template: ` + <div> + <div class="events-description"> + {{ stage.description }} + <span v-if="items.length === 50" class="events-info pull-right"> + <i class="fa fa-warning has-tooltip" + title="Limited to showing 50 events at most" + data-placement="top"></i> + Showing 50 events + </span> + </div> + <ul class="stage-event-list"> + <li v-for="commit in items" class="stage-event-item"> + <div class="item-details item-conmmit-component"> + <img class="avatar" :src="commit.author.avatarUrl"> + <h5 class="item-title commit-title"> + <a :href="commit.commitUrl"> + {{ commit.title }} + </a> + </h5> + <span> + First + <span class="commit-icon">${iconCommit}</span> + <a :href="commit.commitUrl" class="commit-hash-link monospace">{{ commit.shortSha }}</a> + pushed by + <a :href="commit.author.webUrl" class="commit-author-link"> + {{ commit.author.name }} + </a> + </span> + </div> + <div class="item-time"> + <total-time :time="commit.totalTime"></total-time> + </div> + </li> + </ul> + </div> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6 deleted file mode 100644 index 8652479e7bf..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es6 +++ /dev/null @@ -1,50 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* global Vue */ - -((global) => { - global.cycleAnalytics = global.cycleAnalytics || {}; - - global.cycleAnalytics.StagePlanComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - template: ` - <div> - <div class="events-description"> - {{ stage.description }} - <span v-if="items.length === 50" class="events-info pull-right"> - <i class="fa fa-warning has-tooltip" - title="Limited to showing 50 events at most" - data-placement="top"></i> - Showing 50 events - </span> - </div> - <ul class="stage-event-list"> - <li v-for="commit in items" class="stage-event-item"> - <div class="item-details item-conmmit-component"> - <img class="avatar" :src="commit.author.avatarUrl"> - <h5 class="item-title commit-title"> - <a :href="commit.commitUrl"> - {{ commit.title }} - </a> - </h5> - <span> - First - <span class="commit-icon">${global.cycleAnalytics.svgs.iconCommit}</span> - <a :href="commit.commitUrl" class="commit-hash-link monospace">{{ commit.shortSha }}</a> - pushed by - <a :href="commit.author.webUrl" class="commit-author-link"> - {{ commit.author.name }} - </a> - </span> - </div> - <div class="item-time"> - <total-time :time="commit.totalTime"></total-time> - </div> - </li> - </ul> - </div> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js index 73f4205b578..73f4205b578 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6 +++ b/app/assets/javascripts/cycle_analytics/components/stage_production_component.js diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js index 501ffb1fac9..501ffb1fac9 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6 +++ b/app/assets/javascripts/cycle_analytics/components/stage_review_component.js diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js new file mode 100644 index 00000000000..8fa63734cf1 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js @@ -0,0 +1,48 @@ +/* eslint-disable no-param-reassign */ +import Vue from 'vue'; +import iconBranch from '../svg/icon_branch.svg'; + +((global) => { + global.cycleAnalytics = global.cycleAnalytics || {}; + + global.cycleAnalytics.StageStagingComponent = Vue.extend({ + props: { + items: Array, + stage: Object, + }, + data() { + return { iconBranch }; + }, + template: ` + <div> + <div class="events-description"> + {{ stage.description }} + </div> + <ul class="stage-event-list"> + <li v-for="build in items" class="stage-event-item item-build-component"> + <div class="item-details"> + <img class="avatar" :src="build.author.avatarUrl"> + <h5 class="item-title"> + <a :href="build.url" class="pipeline-id">#{{ build.id }}</a> + <i class="fa fa-code-fork"></i> + <a :href="build.branch.url" class="branch-name monospace">{{ build.branch.name }}</a> + <span class="icon-branch">${iconBranch}</span> + <a :href="build.commitUrl" class="short-sha monospace">{{ build.shortSha }}</a> + </h5> + <span> + <a :href="build.url" class="build-date">{{ build.date }}</a> + by + <a :href="build.author.webUrl" class="issue-author-link"> + {{ build.author.name }} + </a> + </span> + </div> + <div class="item-time"> + <total-time :time="build.totalTime"></total-time> + </div> + </li> + </ul> + </div> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6 deleted file mode 100644 index 82622232f64..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es6 +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* global Vue */ - -((global) => { - global.cycleAnalytics = global.cycleAnalytics || {}; - - global.cycleAnalytics.StageStagingComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - template: ` - <div> - <div class="events-description"> - {{ stage.description }} - </div> - <ul class="stage-event-list"> - <li v-for="build in items" class="stage-event-item item-build-component"> - <div class="item-details"> - <img class="avatar" :src="build.author.avatarUrl"> - <h5 class="item-title"> - <a :href="build.url" class="pipeline-id">#{{ build.id }}</a> - <i class="fa fa-code-fork"></i> - <a :href="build.branch.url" class="branch-name monospace">{{ build.branch.name }}</a> - <span class="icon-branch">${global.cycleAnalytics.svgs.iconBranch}</span> - <a :href="build.commitUrl" class="short-sha monospace">{{ build.shortSha }}</a> - </h5> - <span> - <a :href="build.url" class="build-date">{{ build.date }}</a> - by - <a :href="build.author.webUrl" class="issue-author-link"> - {{ build.author.name }} - </a> - </span> - </div> - <div class="item-time"> - <total-time :time="build.totalTime"></total-time> - </div> - </li> - </ul> - </div> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js new file mode 100644 index 00000000000..0015249cfaa --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js @@ -0,0 +1,49 @@ +/* eslint-disable no-param-reassign */ +import Vue from 'vue'; +import iconBuildStatus from '../svg/icon_build_status.svg'; +import iconBranch from '../svg/icon_branch.svg'; + +((global) => { + global.cycleAnalytics = global.cycleAnalytics || {}; + + global.cycleAnalytics.StageTestComponent = Vue.extend({ + props: { + items: Array, + stage: Object, + }, + data() { + return { iconBuildStatus, iconBranch }; + }, + template: ` + <div> + <div class="events-description"> + {{ stage.description }} + </div> + <ul class="stage-event-list"> + <li v-for="build in items" class="stage-event-item item-build-component"> + <div class="item-details"> + <h5 class="item-title"> + <span class="icon-build-status">${iconBuildStatus}</span> + <a :href="build.url" class="item-build-name">{{ build.name }}</a> + · + <a :href="build.url" class="pipeline-id">#{{ build.id }}</a> + <i class="fa fa-code-fork"></i> + <a :href="build.branch.url" class="branch-name monospace">{{ build.branch.name }}</a> + <span class="icon-branch">${iconBranch}</span> + <a :href="build.commitUrl" class="short-sha monospace">{{ build.shortSha }}</a> + </h5> + <span> + <a :href="build.url" class="issue-date"> + {{ build.date }} + </a> + </span> + </div> + <div class="item-time"> + <total-time :time="build.totalTime"></total-time> + </div> + </li> + </ul> + </div> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6 deleted file mode 100644 index 4bfd363a1f1..00000000000 --- a/app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es6 +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* global Vue */ - -((global) => { - global.cycleAnalytics = global.cycleAnalytics || {}; - - global.cycleAnalytics.StageTestComponent = Vue.extend({ - props: { - items: Array, - stage: Object, - }, - template: ` - <div> - <div class="events-description"> - {{ stage.description }} - </div> - <ul class="stage-event-list"> - <li v-for="build in items" class="stage-event-item item-build-component"> - <div class="item-details"> - <h5 class="item-title"> - <span class="icon-build-status">${global.cycleAnalytics.svgs.iconBuildStatus}</span> - <a :href="build.url" class="item-build-name">{{ build.name }}</a> - · - <a :href="build.url" class="pipeline-id">#{{ build.id }}</a> - <i class="fa fa-code-fork"></i> - <a :href="build.branch.url" class="branch-name monospace">{{ build.branch.name }}</a> - <span class="icon-branch">${global.cycleAnalytics.svgs.iconBranch}</span> - <a :href="build.commitUrl" class="short-sha monospace">{{ build.shortSha }}</a> - </h5> - <span> - <a :href="build.url" class="issue-date"> - {{ build.date }} - </a> - </span> - </div> - <div class="item-time"> - <total-time :time="build.totalTime"></total-time> - </div> - </li> - </ul> - </div> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6 b/app/assets/javascripts/cycle_analytics/components/total_time_component.js index 0d85e1a4678..0d85e1a4678 100644 --- a/app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6 +++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.js diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js new file mode 100644 index 00000000000..beff293b587 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js @@ -0,0 +1,135 @@ +/* global Vue */ +/* global Cookies */ +/* global Flash */ + +window.Vue = require('vue'); +window.Cookies = require('js-cookie'); +require('./components/stage_code_component'); +require('./components/stage_issue_component'); +require('./components/stage_plan_component'); +require('./components/stage_production_component'); +require('./components/stage_review_component'); +require('./components/stage_staging_component'); +require('./components/stage_test_component'); +require('./components/total_time_component'); +require('./cycle_analytics_service'); +require('./cycle_analytics_store'); +require('./default_event_objects'); + +$(() => { + const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed'; + const cycleAnalyticsEl = document.querySelector('#cycle-analytics'); + const cycleAnalyticsStore = gl.cycleAnalytics.CycleAnalyticsStore; + const cycleAnalyticsService = new gl.cycleAnalytics.CycleAnalyticsService({ + requestPath: cycleAnalyticsEl.dataset.requestPath, + }); + + gl.cycleAnalyticsApp = new Vue({ + el: '#cycle-analytics', + name: 'CycleAnalytics', + data: { + state: cycleAnalyticsStore.state, + isLoading: false, + isLoadingStage: false, + isEmptyStage: false, + hasError: false, + startDate: 30, + isOverviewDialogDismissed: Cookies.get(OVERVIEW_DIALOG_COOKIE), + }, + computed: { + currentStage() { + return cycleAnalyticsStore.currentActiveStage(); + }, + }, + components: { + 'stage-issue-component': gl.cycleAnalytics.StageIssueComponent, + 'stage-plan-component': gl.cycleAnalytics.StagePlanComponent, + 'stage-code-component': gl.cycleAnalytics.StageCodeComponent, + 'stage-test-component': gl.cycleAnalytics.StageTestComponent, + 'stage-review-component': gl.cycleAnalytics.StageReviewComponent, + 'stage-staging-component': gl.cycleAnalytics.StageStagingComponent, + 'stage-production-component': gl.cycleAnalytics.StageProductionComponent, + }, + created() { + this.fetchCycleAnalyticsData(); + }, + methods: { + handleError() { + cycleAnalyticsStore.setErrorState(true); + return new Flash('There was an error while fetching cycle analytics data.'); + }, + initDropdown() { + const $dropdown = $('.js-ca-dropdown'); + const $label = $dropdown.find('.dropdown-label'); + + $dropdown.find('li a').off('click').on('click', (e) => { + e.preventDefault(); + const $target = $(e.currentTarget); + this.startDate = $target.data('value'); + + $label.text($target.text().trim()); + this.fetchCycleAnalyticsData({ startDate: this.startDate }); + }); + }, + fetchCycleAnalyticsData(options) { + const fetchOptions = options || { startDate: this.startDate }; + + this.isLoading = true; + + cycleAnalyticsService + .fetchCycleAnalyticsData(fetchOptions) + .done((response) => { + cycleAnalyticsStore.setCycleAnalyticsData(response); + this.selectDefaultStage(); + this.initDropdown(); + }) + .error(() => { + this.handleError(); + }) + .always(() => { + this.isLoading = false; + }); + }, + selectDefaultStage() { + const stage = this.state.stages.first(); + this.selectStage(stage); + }, + selectStage(stage) { + if (this.isLoadingStage) return; + if (this.currentStage === stage) return; + + if (!stage.isUserAllowed) { + cycleAnalyticsStore.setActiveStage(stage); + return; + } + + this.isLoadingStage = true; + cycleAnalyticsStore.setStageEvents([], stage); + cycleAnalyticsStore.setActiveStage(stage); + + cycleAnalyticsService + .fetchStageData({ + stage, + startDate: this.startDate, + }) + .done((response) => { + this.isEmptyStage = !response.events.length; + cycleAnalyticsStore.setStageEvents(response.events, stage); + }) + .error(() => { + this.isEmptyStage = true; + }) + .always(() => { + this.isLoadingStage = false; + }); + }, + dismissOverviewDialog() { + this.isOverviewDialogDismissed = true; + Cookies.set(OVERVIEW_DIALOG_COOKIE, '1'); + }, + }, + }); + + // Register global components + Vue.component('total-time', gl.cycleAnalytics.TotalTimeComponent); +}); diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 deleted file mode 100644 index 411ac7b24b2..00000000000 --- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6 +++ /dev/null @@ -1,138 +0,0 @@ -/* global Vue */ -/* global Cookies */ -/* global Flash */ - -window.Vue = require('vue'); -window.Cookies = require('js-cookie'); -require('./svg/icon_branch'); -require('./svg/icon_build_status'); -require('./svg/icon_commit'); -require('./components/stage_code_component'); -require('./components/stage_issue_component'); -require('./components/stage_plan_component'); -require('./components/stage_production_component'); -require('./components/stage_review_component'); -require('./components/stage_staging_component'); -require('./components/stage_test_component'); -require('./components/total_time_component'); -require('./cycle_analytics_service'); -require('./cycle_analytics_store'); -require('./default_event_objects'); - -$(() => { - const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed'; - const cycleAnalyticsEl = document.querySelector('#cycle-analytics'); - const cycleAnalyticsStore = gl.cycleAnalytics.CycleAnalyticsStore; - const cycleAnalyticsService = new gl.cycleAnalytics.CycleAnalyticsService({ - requestPath: cycleAnalyticsEl.dataset.requestPath, - }); - - gl.cycleAnalyticsApp = new Vue({ - el: '#cycle-analytics', - name: 'CycleAnalytics', - data: { - state: cycleAnalyticsStore.state, - isLoading: false, - isLoadingStage: false, - isEmptyStage: false, - hasError: false, - startDate: 30, - isOverviewDialogDismissed: Cookies.get(OVERVIEW_DIALOG_COOKIE), - }, - computed: { - currentStage() { - return cycleAnalyticsStore.currentActiveStage(); - }, - }, - components: { - 'stage-issue-component': gl.cycleAnalytics.StageIssueComponent, - 'stage-plan-component': gl.cycleAnalytics.StagePlanComponent, - 'stage-code-component': gl.cycleAnalytics.StageCodeComponent, - 'stage-test-component': gl.cycleAnalytics.StageTestComponent, - 'stage-review-component': gl.cycleAnalytics.StageReviewComponent, - 'stage-staging-component': gl.cycleAnalytics.StageStagingComponent, - 'stage-production-component': gl.cycleAnalytics.StageProductionComponent, - }, - created() { - this.fetchCycleAnalyticsData(); - }, - methods: { - handleError() { - cycleAnalyticsStore.setErrorState(true); - return new Flash('There was an error while fetching cycle analytics data.'); - }, - initDropdown() { - const $dropdown = $('.js-ca-dropdown'); - const $label = $dropdown.find('.dropdown-label'); - - $dropdown.find('li a').off('click').on('click', (e) => { - e.preventDefault(); - const $target = $(e.currentTarget); - this.startDate = $target.data('value'); - - $label.text($target.text().trim()); - this.fetchCycleAnalyticsData({ startDate: this.startDate }); - }); - }, - fetchCycleAnalyticsData(options) { - const fetchOptions = options || { startDate: this.startDate }; - - this.isLoading = true; - - cycleAnalyticsService - .fetchCycleAnalyticsData(fetchOptions) - .done((response) => { - cycleAnalyticsStore.setCycleAnalyticsData(response); - this.selectDefaultStage(); - this.initDropdown(); - }) - .error(() => { - this.handleError(); - }) - .always(() => { - this.isLoading = false; - }); - }, - selectDefaultStage() { - const stage = this.state.stages.first(); - this.selectStage(stage); - }, - selectStage(stage) { - if (this.isLoadingStage) return; - if (this.currentStage === stage) return; - - if (!stage.isUserAllowed) { - cycleAnalyticsStore.setActiveStage(stage); - return; - } - - this.isLoadingStage = true; - cycleAnalyticsStore.setStageEvents([], stage); - cycleAnalyticsStore.setActiveStage(stage); - - cycleAnalyticsService - .fetchStageData({ - stage, - startDate: this.startDate, - }) - .done((response) => { - this.isEmptyStage = !response.events.length; - cycleAnalyticsStore.setStageEvents(response.events, stage); - }) - .error(() => { - this.isEmptyStage = true; - }) - .always(() => { - this.isLoadingStage = false; - }); - }, - dismissOverviewDialog() { - this.isOverviewDialogDismissed = true; - Cookies.set(OVERVIEW_DIALOG_COOKIE, '1'); - }, - }, - }); - - // Register global components - Vue.component('total-time', gl.cycleAnalytics.TotalTimeComponent); -}); diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js index 9f74b14c4b9..9f74b14c4b9 100644 --- a/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js.es6 +++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_service.js diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6 b/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js index 7ae9de7297c..7ae9de7297c 100644 --- a/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6 +++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_store.js diff --git a/app/assets/javascripts/cycle_analytics/default_event_objects.js.es6 b/app/assets/javascripts/cycle_analytics/default_event_objects.js index cfaf9835bf8..cfaf9835bf8 100644 --- a/app/assets/javascripts/cycle_analytics/default_event_objects.js.es6 +++ b/app/assets/javascripts/cycle_analytics/default_event_objects.js diff --git a/app/assets/javascripts/cycle_analytics/svg/icon_branch.js.es6 b/app/assets/javascripts/cycle_analytics/svg/icon_branch.js.es6 deleted file mode 100644 index 5d486bcaf66..00000000000 --- a/app/assets/javascripts/cycle_analytics/svg/icon_branch.js.es6 +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable no-param-reassign */ -((global) => { - global.cycleAnalytics = global.cycleAnalytics || {}; - global.cycleAnalytics.svgs = global.cycleAnalytics.svgs || {}; - - global.cycleAnalytics.svgs.iconBranch = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><path fill="#8C8C8C" fill-rule="evenodd" d="M9.678 6.722C9.353 5.167 8.053 4 6.5 4S3.647 5.167 3.322 6.722h-2.6c-.397 0-.722.35-.722.778 0 .428.325.778.722.778h2.6C3.647 9.833 4.947 11 6.5 11s2.853-1.167 3.178-2.722h2.6c.397 0 .722-.35.722-.778 0-.428-.325-.778-.722-.778h-2.6zM4.694 7.5c0-1.09.795-1.944 1.806-1.944 1.01 0 1.806.855 1.806 1.944 0 1.09-.795 1.944-1.806 1.944-1.01 0-1.806-.855-1.806-1.944z"/></svg>'; -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/svg/icon_branch.svg b/app/assets/javascripts/cycle_analytics/svg/icon_branch.svg new file mode 100644 index 00000000000..9f547d3d744 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/svg/icon_branch.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><path fill="#8C8C8C" fill-rule="evenodd" d="M9.678 6.722C9.353 5.167 8.053 4 6.5 4S3.647 5.167 3.322 6.722h-2.6c-.397 0-.722.35-.722.778 0 .428.325.778.722.778h2.6C3.647 9.833 4.947 11 6.5 11s2.853-1.167 3.178-2.722h2.6c.397 0 .722-.35.722-.778 0-.428-.325-.778-.722-.778h-2.6zM4.694 7.5c0-1.09.795-1.944 1.806-1.944 1.01 0 1.806.855 1.806 1.944 0 1.09-.795 1.944-1.806 1.944-1.01 0-1.806-.855-1.806-1.944z"/></svg> diff --git a/app/assets/javascripts/cycle_analytics/svg/icon_build_status.js.es6 b/app/assets/javascripts/cycle_analytics/svg/icon_build_status.js.es6 deleted file mode 100644 index 661bf9e9f1c..00000000000 --- a/app/assets/javascripts/cycle_analytics/svg/icon_build_status.js.es6 +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable no-param-reassign */ -((global) => { - global.cycleAnalytics = global.cycleAnalytics || {}; - global.cycleAnalytics.svgs = global.cycleAnalytics.svgs || {}; - - global.cycleAnalytics.svgs.iconBuildStatus = '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><g fill="#31AF64" fill-rule="evenodd"><path d="M12.5 7c0-3.038-2.462-5.5-5.5-5.5S1.5 3.962 1.5 7s2.462 5.5 5.5 5.5 5.5-2.462 5.5-5.5zM0 7c0-3.866 3.134-7 7-7s7 3.134 7 7-3.134 7-7 7-7-3.134-7-7z"/><path d="M6.28 7.697L5.045 6.464c-.117-.117-.305-.117-.42-.002l-.614.614c-.11.113-.11.303.007.42l1.91 1.91c.19.19.51.197.703.004l.264-.265L9.997 6.04c.108-.107.107-.293-.01-.408l-.612-.614c-.114-.113-.298-.12-.41-.01L6.28 7.7z"/></g></svg>'; -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/svg/icon_build_status.svg b/app/assets/javascripts/cycle_analytics/svg/icon_build_status.svg new file mode 100644 index 00000000000..b932d90618a --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/svg/icon_build_status.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14"><g fill="#31AF64" fill-rule="evenodd"><path d="M12.5 7c0-3.038-2.462-5.5-5.5-5.5S1.5 3.962 1.5 7s2.462 5.5 5.5 5.5 5.5-2.462 5.5-5.5zM0 7c0-3.866 3.134-7 7-7s7 3.134 7 7-3.134 7-7 7-7-3.134-7-7z"/><path d="M6.28 7.697L5.045 6.464c-.117-.117-.305-.117-.42-.002l-.614.614c-.11.113-.11.303.007.42l1.91 1.91c.19.19.51.197.703.004l.264-.265L9.997 6.04c.108-.107.107-.293-.01-.408l-.612-.614c-.114-.113-.298-.12-.41-.01L6.28 7.7z"/></g></svg> diff --git a/app/assets/javascripts/cycle_analytics/svg/icon_commit.js.es6 b/app/assets/javascripts/cycle_analytics/svg/icon_commit.js.es6 deleted file mode 100644 index 2208c27a619..00000000000 --- a/app/assets/javascripts/cycle_analytics/svg/icon_commit.js.es6 +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable no-param-reassign */ -((global) => { - global.cycleAnalytics = global.cycleAnalytics || {}; - global.cycleAnalytics.svgs = global.cycleAnalytics.svgs || {}; - - global.cycleAnalytics.svgs.iconCommit = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><path fill="#8F8F8F" fill-rule="evenodd" d="M28.777 18c-.91-4.008-4.494-7-8.777-7-4.283 0-7.868 2.992-8.777 7H4.01C2.9 18 2 18.895 2 20c0 1.112.9 2 2.01 2h7.213c.91 4.008 4.494 7 8.777 7 4.283 0 7.868-2.992 8.777-7h7.214C37.1 22 38 21.105 38 20c0-1.112-.9-2-2.01-2h-7.213zM20 25c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5z"/></svg>'; -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/cycle_analytics/svg/icon_commit.svg b/app/assets/javascripts/cycle_analytics/svg/icon_commit.svg new file mode 100644 index 00000000000..6a517756058 --- /dev/null +++ b/app/assets/javascripts/cycle_analytics/svg/icon_commit.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><path fill="#8F8F8F" fill-rule="evenodd" d="M28.777 18c-.91-4.008-4.494-7-8.777-7-4.283 0-7.868 2.992-8.777 7H4.01C2.9 18 2 18.895 2 20c0 1.112.9 2 2.01 2h7.213c.91 4.008 4.494 7 8.777 7 4.283 0 7.868-2.992 8.777-7h7.214C37.1 22 38 21.105 38 20c0-1.112-.9-2-2.01-2h-7.213zM20 25c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5z"/></svg> diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js new file mode 100644 index 00000000000..6829e8aeaea --- /dev/null +++ b/app/assets/javascripts/diff.js @@ -0,0 +1,130 @@ +/* eslint-disable class-methods-use-this */ + +require('./lib/utils/url_utility'); + +(() => { + const UNFOLD_COUNT = 20; + let isBound = false; + + class Diff { + constructor() { + const $diffFile = $('.files .diff-file'); + $diffFile.singleFileDiff(); + $diffFile.filesCommentButton(); + + $diffFile.each((index, file) => new gl.ImageFile(file)); + + if (this.diffViewType() === 'parallel') { + $('.content-wrapper .container-fluid').removeClass('container-limited'); + } + + if (!isBound) { + $(document) + .on('click', '.js-unfold', this.handleClickUnfold.bind(this)) + .on('click', '.diff-line-num a', this.handleClickLineNum.bind(this)); + isBound = true; + } + + if (gl.utils.getLocationHash()) { + this.highlightSelectedLine(); + } + + this.openAnchoredDiff(); + } + + handleClickUnfold(e) { + const $target = $(e.target); + // current babel config relies on iterators implementation, so we cannot simply do: + // const [oldLineNumber, newLineNumber] = this.lineNumbers($target.parent()); + const ref = this.lineNumbers($target.parent()); + const oldLineNumber = ref[0]; + const newLineNumber = ref[1]; + const offset = newLineNumber - oldLineNumber; + const bottom = $target.hasClass('js-unfold-bottom'); + let since; + let to; + let unfold = true; + + if (bottom) { + const lineNumber = newLineNumber + 1; + since = lineNumber; + to = lineNumber + UNFOLD_COUNT; + } else { + const lineNumber = newLineNumber - 1; + since = lineNumber - UNFOLD_COUNT; + to = lineNumber; + + // make sure we aren't loading more than we need + const prevNewLine = this.lineNumbers($target.parent().prev())[1]; + if (since <= prevNewLine + 1) { + since = prevNewLine + 1; + unfold = false; + } + } + + const file = $target.parents('.diff-file'); + const link = file.data('blob-diff-path'); + const view = file.data('view'); + + const params = { since, to, bottom, offset, unfold, view }; + $.get(link, params, response => $target.parent().replaceWith(response)); + } + + openAnchoredDiff(cb) { + const locationHash = gl.utils.getLocationHash(); + const anchoredDiff = locationHash && locationHash.split('_')[0]; + + if (!anchoredDiff) return; + + const diffTitle = $(`#${anchoredDiff}`); + const diffFile = diffTitle.closest('.diff-file'); + const nothingHereBlock = $('.nothing-here-block:visible', diffFile); + if (nothingHereBlock.length) { + const clickTarget = $('.js-file-title, .click-to-expand', diffFile); + diffFile.data('singleFileDiff').toggleDiff(clickTarget, () => { + this.highlightSelectedLine(); + if (cb) cb(); + }); + } else if (cb) { + cb(); + } + } + + handleClickLineNum(e) { + const hash = $(e.currentTarget).attr('href'); + e.preventDefault(); + if (window.history.pushState) { + window.history.pushState(null, null, hash); + } else { + window.location.hash = hash; + } + this.highlightSelectedLine(); + } + + diffViewType() { + return $('.inline-parallel-buttons a.active').data('view-type'); + } + + lineNumbers(line) { + if (!line.children().length) { + return [0, 0]; + } + return line.find('.diff-line-num').map((i, elm) => parseInt($(elm).data('linenumber'), 10)); + } + + highlightSelectedLine() { + const hash = gl.utils.getLocationHash(); + const $diffFiles = $('.diff-file'); + $diffFiles.find('.hll').removeClass('hll'); + + if (hash) { + $diffFiles + .find(`tr#${hash}:not(.match) td, td#${hash}, td[data-line-code="${hash}"]`) + .addClass('hll'); + } + } + } + + window.gl = window.gl || {}; + window.gl.Diff = Diff; +})(); diff --git a/app/assets/javascripts/diff.js.es6 b/app/assets/javascripts/diff.js.es6 deleted file mode 100644 index ccccd0a36ff..00000000000 --- a/app/assets/javascripts/diff.js.es6 +++ /dev/null @@ -1,126 +0,0 @@ -/* eslint-disable class-methods-use-this */ - -require('./lib/utils/url_utility'); - -(() => { - const UNFOLD_COUNT = 20; - let isBound = false; - - class Diff { - constructor() { - const $diffFile = $('.files .diff-file'); - $diffFile.singleFileDiff(); - $diffFile.filesCommentButton(); - - $diffFile.each((index, file) => new gl.ImageFile(file)); - - if (this.diffViewType() === 'parallel') { - $('.content-wrapper .container-fluid').removeClass('container-limited'); - } - - if (!isBound) { - $(document) - .on('click', '.js-unfold', this.handleClickUnfold.bind(this)) - .on('click', '.diff-line-num a', this.handleClickLineNum.bind(this)); - isBound = true; - } - - this.openAnchoredDiff(); - } - - handleClickUnfold(e) { - const $target = $(e.target); - // current babel config relies on iterators implementation, so we cannot simply do: - // const [oldLineNumber, newLineNumber] = this.lineNumbers($target.parent()); - const ref = this.lineNumbers($target.parent()); - const oldLineNumber = ref[0]; - const newLineNumber = ref[1]; - const offset = newLineNumber - oldLineNumber; - const bottom = $target.hasClass('js-unfold-bottom'); - let since; - let to; - let unfold = true; - - if (bottom) { - const lineNumber = newLineNumber + 1; - since = lineNumber; - to = lineNumber + UNFOLD_COUNT; - } else { - const lineNumber = newLineNumber - 1; - since = lineNumber - UNFOLD_COUNT; - to = lineNumber; - - // make sure we aren't loading more than we need - const prevNewLine = this.lineNumbers($target.parent().prev())[1]; - if (since <= prevNewLine + 1) { - since = prevNewLine + 1; - unfold = false; - } - } - - const file = $target.parents('.diff-file'); - const link = file.data('blob-diff-path'); - const view = file.data('view'); - - const params = { since, to, bottom, offset, unfold, view }; - $.get(link, params, response => $target.parent().replaceWith(response)); - } - - openAnchoredDiff(cb) { - const locationHash = gl.utils.getLocationHash(); - const anchoredDiff = locationHash && locationHash.split('_')[0]; - - if (!anchoredDiff) return; - - const diffTitle = $(`#${anchoredDiff}`); - const diffFile = diffTitle.closest('.diff-file'); - const nothingHereBlock = $('.nothing-here-block:visible', diffFile); - if (nothingHereBlock.length) { - const clickTarget = $('.js-file-title, .click-to-expand', diffFile); - diffFile.data('singleFileDiff').toggleDiff(clickTarget, () => { - this.highlighSelectedLine(); - if (cb) cb(); - }); - } else if (cb) { - cb(); - } - } - - handleClickLineNum(e) { - const hash = $(e.currentTarget).attr('href'); - e.preventDefault(); - if (window.history.pushState) { - window.history.pushState(null, null, hash); - } else { - window.location.hash = hash; - } - this.highlighSelectedLine(); - } - - diffViewType() { - return $('.inline-parallel-buttons a.active').data('view-type'); - } - - lineNumbers(line) { - if (!line.children().length) { - return [0, 0]; - } - return line.find('.diff-line-num').map((i, elm) => parseInt($(elm).data('linenumber'), 10)); - } - - highlighSelectedLine() { - const hash = gl.utils.getLocationHash(); - const $diffFiles = $('.diff-file'); - $diffFiles.find('.hll').removeClass('hll'); - - if (hash) { - $diffFiles - .find(`tr#${hash}:not(.match) td, td#${hash}, td[data-line-code="${hash}"]`) - .addClass('hll'); - } - } - } - - window.gl = window.gl || {}; - window.gl.Diff = Diff; -})(); diff --git a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6 b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js index d948dff58ec..d948dff58ec 100644 --- a/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6 +++ b/app/assets/javascripts/diff_notes/components/comment_resolve_btn.js diff --git a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js index 283dc330cad..283dc330cad 100644 --- a/app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6 +++ b/app/assets/javascripts/diff_notes/components/jump_to_discussion.js diff --git a/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_btn.js index d1873d6c7a2..d1873d6c7a2 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_btn.js.es6 +++ b/app/assets/javascripts/diff_notes/components/resolve_btn.js diff --git a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_count.js index de9367f2136..de9367f2136 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_count.js.es6 +++ b/app/assets/javascripts/diff_notes/components/resolve_count.js diff --git a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6 b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js index 7c5fcd04d2d..7c5fcd04d2d 100644 --- a/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6 +++ b/app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 b/app/assets/javascripts/diff_notes/diff_notes_bundle.js index cadf8b96b87..cadf8b96b87 100644 --- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6 +++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js diff --git a/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 b/app/assets/javascripts/diff_notes/mixins/discussion.js index 3c08c222f46..3c08c222f46 100644 --- a/app/assets/javascripts/diff_notes/mixins/discussion.js.es6 +++ b/app/assets/javascripts/diff_notes/mixins/discussion.js diff --git a/app/assets/javascripts/diff_notes/models/discussion.js.es6 b/app/assets/javascripts/diff_notes/models/discussion.js index fa518ba4d33..fa518ba4d33 100644 --- a/app/assets/javascripts/diff_notes/models/discussion.js.es6 +++ b/app/assets/javascripts/diff_notes/models/discussion.js diff --git a/app/assets/javascripts/diff_notes/models/note.js.es6 b/app/assets/javascripts/diff_notes/models/note.js index f3a7cba5ef6..f3a7cba5ef6 100644 --- a/app/assets/javascripts/diff_notes/models/note.js.es6 +++ b/app/assets/javascripts/diff_notes/models/note.js diff --git a/app/assets/javascripts/diff_notes/services/resolve.js.es6 b/app/assets/javascripts/diff_notes/services/resolve.js index 090c454e9e4..090c454e9e4 100644 --- a/app/assets/javascripts/diff_notes/services/resolve.js.es6 +++ b/app/assets/javascripts/diff_notes/services/resolve.js diff --git a/app/assets/javascripts/diff_notes/stores/comments.js.es6 b/app/assets/javascripts/diff_notes/stores/comments.js index c80d979b977..c80d979b977 100644 --- a/app/assets/javascripts/diff_notes/stores/comments.js.es6 +++ b/app/assets/javascripts/diff_notes/stores/comments.js diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js new file mode 100644 index 00000000000..31f10f89245 --- /dev/null +++ b/app/assets/javascripts/dispatcher.js @@ -0,0 +1,413 @@ +/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */ +/* global UsernameValidator */ +/* global ActiveTabMemoizer */ +/* global ShortcutsNavigation */ +/* global Build */ +/* global Issuable */ +/* global Issue */ +/* global ShortcutsIssuable */ +/* global ZenMode */ +/* global Milestone */ +/* global IssuableForm */ +/* global LabelsSelect */ +/* global MilestoneSelect */ +/* global MergedButtons */ +/* global Commit */ +/* global NotificationsForm */ +/* global TreeView */ +/* global NotificationsDropdown */ +/* global UsersSelect */ +/* global GroupAvatar */ +/* global LineHighlighter */ +/* global ProjectFork */ +/* global BuildArtifacts */ +/* global GroupsSelect */ +/* global Search */ +/* global Admin */ +/* global NamespaceSelects */ +/* global ShortcutsDashboardNavigation */ +/* global Project */ +/* global ProjectAvatar */ +/* global CompareAutocomplete */ +/* global ProjectNew */ +/* global Star */ +/* global ProjectShow */ +/* global Labels */ +/* global Shortcuts */ + +import BindInOut from './behaviors/bind_in_out'; +import GroupsList from './groups_list'; +import ProjectsList from './projects_list'; + +const ShortcutsBlob = require('./shortcuts_blob'); +const UserCallout = require('./user_callout'); + +(function() { + var Dispatcher; + + $(function() { + return new Dispatcher(); + }); + + Dispatcher = (function() { + function Dispatcher() { + this.initSearch(); + this.initFieldErrors(); + this.initPageScripts(); + } + + Dispatcher.prototype.initPageScripts = function() { + var page, path, shortcut_handler; + page = $('body').attr('data-page'); + if (!page) { + return false; + } + path = page.split(':'); + shortcut_handler = null; + switch (page) { + case 'sessions:new': + new UsernameValidator(); + new ActiveTabMemoizer(); + break; + case 'projects:boards:show': + case 'projects:boards:index': + shortcut_handler = new ShortcutsNavigation(); + break; + case 'projects:builds:show': + new Build(); + break; + case 'projects:merge_requests:index': + case 'projects:issues:index': + if (gl.FilteredSearchManager) { + new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests'); + } + Issuable.init(); + new gl.IssuableBulkActions({ + prefixId: page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_', + }); + shortcut_handler = new ShortcutsNavigation(); + break; + case 'projects:issues:show': + new Issue(); + shortcut_handler = new ShortcutsIssuable(); + new ZenMode(); + break; + case 'projects:milestones:show': + case 'groups:milestones:show': + case 'dashboard:milestones:show': + new Milestone(); + break; + case 'dashboard:todos:index': + new gl.Todos(); + break; + case 'dashboard:projects:index': + case 'dashboard:projects:starred': + case 'explore:projects:index': + case 'explore:projects:trending': + case 'explore:projects:starred': + case 'admin:projects:index': + new ProjectsList(); + break; + case 'dashboard:groups:index': + case 'explore:groups:index': + new GroupsList(); + break; + case 'projects:milestones:new': + case 'projects:milestones:edit': + case 'projects:milestones:update': + new ZenMode(); + new gl.DueDateSelectors(); + new gl.GLForm($('.milestone-form')); + break; + case 'groups:milestones:new': + new ZenMode(); + break; + case 'projects:compare:show': + new gl.Diff(); + break; + case 'projects:branches:index': + gl.AjaxLoadingSpinner.init(); + break; + case 'projects:issues:new': + case 'projects:issues:edit': + shortcut_handler = new ShortcutsNavigation(); + new gl.GLForm($('.issue-form')); + new IssuableForm($('.issue-form')); + new LabelsSelect(); + new MilestoneSelect(); + new gl.IssuableTemplateSelectors(); + break; + case 'projects:merge_requests:new': + case 'projects:merge_requests:new_diffs': + case 'projects:merge_requests:edit': + new gl.Diff(); + shortcut_handler = new ShortcutsNavigation(); + new gl.GLForm($('.merge-request-form')); + new IssuableForm($('.merge-request-form')); + new LabelsSelect(); + new MilestoneSelect(); + new gl.IssuableTemplateSelectors(); + break; + case 'projects:tags:new': + new ZenMode(); + new gl.GLForm($('.tag-form')); + break; + case 'projects:releases:edit': + new ZenMode(); + new gl.GLForm($('.release-form')); + break; + case 'projects:merge_requests:show': + new gl.Diff(); + shortcut_handler = new ShortcutsIssuable(true); + new ZenMode(); + new MergedButtons(); + break; + case 'projects:merge_requests:commits': + new MergedButtons(); + break; + case "projects:merge_requests:diffs": + new gl.Diff(); + new ZenMode(); + new MergedButtons(); + break; + case 'dashboard:activity': + new gl.Activities(); + break; + case 'projects:commit:show': + new Commit(); + new gl.Diff(); + new ZenMode(); + shortcut_handler = new ShortcutsNavigation(); + break; + case 'projects:commit:pipelines': + new gl.MiniPipelineGraph({ + container: '.js-pipeline-table', + }).bindEvents(); + break; + case 'projects:commits:show': + case 'projects:activity': + shortcut_handler = new ShortcutsNavigation(); + break; + case 'projects:show': + shortcut_handler = new ShortcutsNavigation(); + new NotificationsForm(); + if ($('#tree-slider').length) { + new TreeView(); + } + break; + case 'projects:pipelines:builds': + case 'projects:pipelines:show': + const { controllerAction } = document.querySelector('.js-pipeline-container').dataset; + + new gl.Pipelines({ + initTabs: true, + tabsOptions: { + action: controllerAction, + defaultAction: 'pipelines', + parentEl: '.pipelines-tabs', + }, + }); + break; + case 'groups:activity': + new gl.Activities(); + break; + case 'groups:show': + shortcut_handler = new ShortcutsNavigation(); + new NotificationsForm(); + new NotificationsDropdown(); + new ProjectsList(); + break; + case 'groups:group_members:index': + new gl.MemberExpirationDate(); + new gl.Members(); + new UsersSelect(); + break; + case 'projects:members:show': + new gl.MemberExpirationDate('.js-access-expiration-date-groups'); + new GroupsSelect(); + new gl.MemberExpirationDate(); + new gl.Members(); + new UsersSelect(); + break; + case 'groups:new': + case 'admin:groups:new': + case 'groups:create': + case 'admin:groups:create': + BindInOut.initAll(); + case 'groups:new': + case 'admin:groups:new': + case 'groups:edit': + case 'admin:groups:edit': + new GroupAvatar(); + break; + case 'projects:tree:show': + shortcut_handler = new ShortcutsNavigation(); + new TreeView(); + break; + case 'projects:find_file:show': + shortcut_handler = true; + break; + case 'projects:blob:show': + case 'projects:blame:show': + new LineHighlighter(); + shortcut_handler = new ShortcutsNavigation(); + const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url'); + const fileBlobPermalinkUrl = fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href'); + new ShortcutsBlob({ + skipResetBindings: true, + fileBlobPermalinkUrl, + }); + break; + case 'groups:labels:new': + case 'groups:labels:edit': + case 'projects:labels:new': + case 'projects:labels:edit': + new Labels(); + break; + case 'projects:labels:index': + if ($('.prioritized-labels').length) { + new gl.LabelManager(); + } + break; + case 'projects:network:show': + // Ensure we don't create a particular shortcut handler here. This is + // already created, where the network graph is created. + shortcut_handler = true; + break; + case 'projects:forks:new': + new ProjectFork(); + break; + case 'projects:artifacts:browse': + new BuildArtifacts(); + break; + case 'help:index': + gl.VersionCheckImage.bindErrorEvent($('img.js-version-status-badge')); + break; + case 'search:show': + new Search(); + break; + case 'projects:protected_branches:index': + new gl.ProtectedBranchCreate(); + new gl.ProtectedBranchEditList(); + break; + case 'projects:ci_cd:show': + new gl.ProjectVariables(); + break; + case 'ci:lints:create': + case 'ci:lints:show': + new gl.CILintEditor(); + break; + case 'users:show': + new UserCallout(); + break; + } + switch (path.first()) { + case 'sessions': + case 'omniauth_callbacks': + if (!gon.u2f) break; + gl.u2fAuthenticate = new gl.U2FAuthenticate( + $('#js-authenticate-u2f'), + '#js-login-u2f-form', + gon.u2f, + document.querySelector('#js-login-2fa-device'), + document.querySelector('.js-2fa-form'), + ); + gl.u2fAuthenticate.start(); + case 'admin': + new Admin(); + switch (path[1]) { + case 'groups': + new UsersSelect(); + break; + case 'projects': + new NamespaceSelects(); + break; + case 'labels': + switch (path[2]) { + case 'new': + case 'edit': + new Labels(); + } + case 'abuse_reports': + new gl.AbuseReports(); + break; + } + break; + case 'dashboard': + case 'root': + shortcut_handler = new ShortcutsDashboardNavigation(); + new UserCallout(); + break; + case 'profiles': + new NotificationsForm(); + new NotificationsDropdown(); + break; + case 'projects': + new Project(); + new ProjectAvatar(); + switch (path[1]) { + case 'compare': + new CompareAutocomplete(); + break; + case 'edit': + shortcut_handler = new ShortcutsNavigation(); + new ProjectNew(); + break; + case 'new': + new ProjectNew(); + break; + case 'show': + new Star(); + new ProjectNew(); + new ProjectShow(); + new NotificationsDropdown(); + break; + case 'wikis': + new gl.Wikis(); + shortcut_handler = new ShortcutsNavigation(); + new ZenMode(); + new gl.GLForm($('.wiki-form')); + break; + case 'snippets': + shortcut_handler = new ShortcutsNavigation(); + if (path[2] === 'show') { + new ZenMode(); + } + break; + case 'labels': + case 'graphs': + case 'compare': + case 'pipelines': + case 'forks': + case 'milestones': + case 'project_members': + case 'deploy_keys': + case 'builds': + case 'hooks': + case 'services': + case 'protected_branches': + shortcut_handler = new ShortcutsNavigation(); + } + } + // If we haven't installed a custom shortcut handler, install the default one + if (!shortcut_handler) { + new Shortcuts(); + } + }; + + Dispatcher.prototype.initSearch = function() { + // Only when search form is present + if ($('.search').length) { + return new gl.SearchAutocomplete(); + } + }; + + Dispatcher.prototype.initFieldErrors = function() { + $('.gl-show-field-errors').each((i, form) => { + new gl.GlFieldErrors(form); + }); + }; + + return Dispatcher; + })(); +}).call(window); diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6 deleted file mode 100644 index fc25122aedc..00000000000 --- a/app/assets/javascripts/dispatcher.js.es6 +++ /dev/null @@ -1,400 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren, no-var, prefer-arrow-callback, wrap-iife, no-shadow, consistent-return, one-var, one-var-declaration-per-line, camelcase, default-case, no-new, quotes, no-duplicate-case, no-case-declarations, no-fallthrough, max-len */ -/* global UsernameValidator */ -/* global ActiveTabMemoizer */ -/* global ShortcutsNavigation */ -/* global Build */ -/* global Issuable */ -/* global Issue */ -/* global ShortcutsIssuable */ -/* global ZenMode */ -/* global Milestone */ -/* global IssuableForm */ -/* global LabelsSelect */ -/* global MilestoneSelect */ -/* global MergedButtons */ -/* global Commit */ -/* global NotificationsForm */ -/* global TreeView */ -/* global NotificationsDropdown */ -/* global UsersSelect */ -/* global GroupAvatar */ -/* global LineHighlighter */ -/* global ProjectFork */ -/* global BuildArtifacts */ -/* global GroupsSelect */ -/* global Search */ -/* global Admin */ -/* global NamespaceSelects */ -/* global ShortcutsDashboardNavigation */ -/* global Project */ -/* global ProjectAvatar */ -/* global CompareAutocomplete */ -/* global ProjectNew */ -/* global Star */ -/* global ProjectShow */ -/* global Labels */ -/* global Shortcuts */ - -import GroupsList from './groups_list'; - -const ShortcutsBlob = require('./shortcuts_blob'); -const UserCallout = require('./user_callout'); - -(function() { - var Dispatcher; - - $(function() { - return new Dispatcher(); - }); - - Dispatcher = (function() { - function Dispatcher() { - this.initSearch(); - this.initFieldErrors(); - this.initPageScripts(); - } - - Dispatcher.prototype.initPageScripts = function() { - var page, path, shortcut_handler; - page = $('body').attr('data-page'); - if (!page) { - return false; - } - path = page.split(':'); - shortcut_handler = null; - switch (page) { - case 'sessions:new': - new UsernameValidator(); - new ActiveTabMemoizer(); - break; - case 'projects:boards:show': - case 'projects:boards:index': - shortcut_handler = new ShortcutsNavigation(); - break; - case 'projects:builds:show': - new Build(); - break; - case 'projects:merge_requests:index': - case 'projects:issues:index': - if (gl.FilteredSearchManager) { - new gl.FilteredSearchManager(page === 'projects:issues:index' ? 'issues' : 'merge_requests'); - } - Issuable.init(); - new gl.IssuableBulkActions({ - prefixId: page === 'projects:merge_requests:index' ? 'merge_request_' : 'issue_', - }); - shortcut_handler = new ShortcutsNavigation(); - break; - case 'projects:issues:show': - new Issue(); - shortcut_handler = new ShortcutsIssuable(); - new ZenMode(); - break; - case 'projects:milestones:show': - case 'groups:milestones:show': - case 'dashboard:milestones:show': - new Milestone(); - break; - case 'dashboard:todos:index': - new gl.Todos(); - break; - case 'dashboard:groups:index': - case 'explore:groups:index': - new GroupsList(); - break; - case 'projects:milestones:new': - case 'projects:milestones:edit': - case 'projects:milestones:update': - new ZenMode(); - new gl.DueDateSelectors(); - new gl.GLForm($('.milestone-form')); - break; - case 'groups:milestones:new': - new ZenMode(); - break; - case 'projects:compare:show': - new gl.Diff(); - break; - case 'projects:branches:index': - gl.AjaxLoadingSpinner.init(); - break; - case 'projects:issues:new': - case 'projects:issues:edit': - shortcut_handler = new ShortcutsNavigation(); - new gl.GLForm($('.issue-form')); - new IssuableForm($('.issue-form')); - new LabelsSelect(); - new MilestoneSelect(); - new gl.IssuableTemplateSelectors(); - break; - case 'projects:merge_requests:new': - case 'projects:merge_requests:new_diffs': - case 'projects:merge_requests:edit': - new gl.Diff(); - shortcut_handler = new ShortcutsNavigation(); - new gl.GLForm($('.merge-request-form')); - new IssuableForm($('.merge-request-form')); - new LabelsSelect(); - new MilestoneSelect(); - new gl.IssuableTemplateSelectors(); - break; - case 'projects:tags:new': - new ZenMode(); - new gl.GLForm($('.tag-form')); - break; - case 'projects:releases:edit': - new ZenMode(); - new gl.GLForm($('.release-form')); - break; - case 'projects:merge_requests:show': - new gl.Diff(); - shortcut_handler = new ShortcutsIssuable(true); - new ZenMode(); - new MergedButtons(); - break; - case 'projects:merge_requests:commits': - new MergedButtons(); - break; - case "projects:merge_requests:diffs": - new gl.Diff(); - new ZenMode(); - new MergedButtons(); - break; - case 'dashboard:activity': - new gl.Activities(); - break; - case 'dashboard:projects:starred': - new gl.Activities(); - break; - case 'projects:commit:show': - new Commit(); - new gl.Diff(); - new ZenMode(); - shortcut_handler = new ShortcutsNavigation(); - break; - case 'projects:commit:pipelines': - new gl.MiniPipelineGraph({ - container: '.js-pipeline-table', - }).bindEvents(); - break; - case 'projects:commits:show': - case 'projects:activity': - shortcut_handler = new ShortcutsNavigation(); - break; - case 'projects:show': - shortcut_handler = new ShortcutsNavigation(); - new NotificationsForm(); - if ($('#tree-slider').length) { - new TreeView(); - } - break; - case 'projects:pipelines:builds': - case 'projects:pipelines:show': - const { controllerAction } = document.querySelector('.js-pipeline-container').dataset; - - new gl.Pipelines({ - initTabs: true, - tabsOptions: { - action: controllerAction, - defaultAction: 'pipelines', - parentEl: '.pipelines-tabs', - }, - }); - break; - case 'groups:activity': - new gl.Activities(); - break; - case 'groups:show': - shortcut_handler = new ShortcutsNavigation(); - new NotificationsForm(); - new NotificationsDropdown(); - break; - case 'groups:group_members:index': - new gl.MemberExpirationDate(); - new gl.Members(); - new UsersSelect(); - break; - case 'projects:members:show': - new gl.MemberExpirationDate('.js-access-expiration-date-groups'); - new GroupsSelect(); - new gl.MemberExpirationDate(); - new gl.Members(); - new UsersSelect(); - break; - case 'groups:new': - case 'groups:edit': - case 'admin:groups:edit': - case 'admin:groups:new': - new GroupAvatar(); - break; - case 'projects:tree:show': - shortcut_handler = new ShortcutsNavigation(); - new TreeView(); - break; - case 'projects:find_file:show': - shortcut_handler = true; - break; - case 'projects:blob:show': - case 'projects:blame:show': - new LineHighlighter(); - shortcut_handler = new ShortcutsNavigation(); - const fileBlobPermalinkUrlElement = document.querySelector('.js-data-file-blob-permalink-url'); - const fileBlobPermalinkUrl = fileBlobPermalinkUrlElement && fileBlobPermalinkUrlElement.getAttribute('href'); - new ShortcutsBlob({ - skipResetBindings: true, - fileBlobPermalinkUrl, - }); - break; - case 'groups:labels:new': - case 'groups:labels:edit': - case 'projects:labels:new': - case 'projects:labels:edit': - new Labels(); - break; - case 'projects:labels:index': - if ($('.prioritized-labels').length) { - new gl.LabelManager(); - } - break; - case 'projects:network:show': - // Ensure we don't create a particular shortcut handler here. This is - // already created, where the network graph is created. - shortcut_handler = true; - break; - case 'projects:forks:new': - new ProjectFork(); - break; - case 'projects:artifacts:browse': - new BuildArtifacts(); - break; - case 'help:index': - gl.VersionCheckImage.bindErrorEvent($('img.js-version-status-badge')); - break; - case 'search:show': - new Search(); - break; - case 'projects:protected_branches:index': - new gl.ProtectedBranchCreate(); - new gl.ProtectedBranchEditList(); - break; - case 'projects:ci_cd:show': - new gl.ProjectVariables(); - break; - case 'ci:lints:create': - case 'ci:lints:show': - new gl.CILintEditor(); - break; - case 'users:show': - new UserCallout(); - break; - } - switch (path.first()) { - case 'sessions': - case 'omniauth_callbacks': - if (!gon.u2f) break; - gl.u2fAuthenticate = new gl.U2FAuthenticate( - $('#js-authenticate-u2f'), - '#js-login-u2f-form', - gon.u2f, - document.querySelector('#js-login-2fa-device'), - document.querySelector('.js-2fa-form'), - ); - gl.u2fAuthenticate.start(); - case 'admin': - new Admin(); - switch (path[1]) { - case 'groups': - new UsersSelect(); - break; - case 'projects': - new NamespaceSelects(); - break; - case 'labels': - switch (path[2]) { - case 'new': - case 'edit': - new Labels(); - } - case 'abuse_reports': - new gl.AbuseReports(); - break; - } - break; - case 'dashboard': - case 'root': - shortcut_handler = new ShortcutsDashboardNavigation(); - new UserCallout(); - break; - case 'profiles': - new NotificationsForm(); - new NotificationsDropdown(); - break; - case 'projects': - new Project(); - new ProjectAvatar(); - switch (path[1]) { - case 'compare': - new CompareAutocomplete(); - break; - case 'edit': - shortcut_handler = new ShortcutsNavigation(); - new ProjectNew(); - break; - case 'new': - new ProjectNew(); - break; - case 'show': - new Star(); - new ProjectNew(); - new ProjectShow(); - new NotificationsDropdown(); - break; - case 'wikis': - new gl.Wikis(); - shortcut_handler = new ShortcutsNavigation(); - new ZenMode(); - new gl.GLForm($('.wiki-form')); - break; - case 'snippets': - shortcut_handler = new ShortcutsNavigation(); - if (path[2] === 'show') { - new ZenMode(); - } - break; - case 'labels': - case 'graphs': - case 'compare': - case 'pipelines': - case 'forks': - case 'milestones': - case 'project_members': - case 'deploy_keys': - case 'builds': - case 'hooks': - case 'services': - case 'protected_branches': - shortcut_handler = new ShortcutsNavigation(); - } - } - // If we haven't installed a custom shortcut handler, install the default one - if (!shortcut_handler) { - new Shortcuts(); - } - }; - - Dispatcher.prototype.initSearch = function() { - // Only when search form is present - if ($('.search').length) { - return new gl.SearchAutocomplete(); - } - }; - - Dispatcher.prototype.initFieldErrors = function() { - $('.gl-show-field-errors').each((i, form) => { - new gl.GlFieldErrors(form); - }); - }; - - return Dispatcher; - })(); -}).call(window); diff --git a/app/assets/javascripts/due_date_select.js.es6 b/app/assets/javascripts/due_date_select.js index 9169fcd7328..9169fcd7328 100644 --- a/app/assets/javascripts/due_date_select.js.es6 +++ b/app/assets/javascripts/due_date_select.js diff --git a/app/assets/javascripts/environments/components/environment.js b/app/assets/javascripts/environments/components/environment.js new file mode 100644 index 00000000000..2cb48dde628 --- /dev/null +++ b/app/assets/javascripts/environments/components/environment.js @@ -0,0 +1,186 @@ +/* eslint-disable no-param-reassign, no-new */ +/* global Flash */ + +const Vue = window.Vue = require('vue'); +window.Vue.use(require('vue-resource')); +const EnvironmentsService = require('../services/environments_service'); +const EnvironmentTable = require('./environments_table'); +const EnvironmentsStore = require('../stores/environments_store'); +require('../../vue_shared/components/table_pagination'); +require('../../lib/utils/common_utils'); +require('../../vue_shared/vue_resource_interceptor'); + +module.exports = Vue.component('environment-component', { + + components: { + 'environment-table': EnvironmentTable, + 'table-pagination': gl.VueGlPagination, + }, + + data() { + const environmentsData = document.querySelector('#environments-list-view').dataset; + const store = new EnvironmentsStore(); + + return { + store, + state: store.state, + visibility: 'available', + isLoading: false, + cssContainerClass: environmentsData.cssClass, + endpoint: environmentsData.environmentsDataEndpoint, + canCreateDeployment: environmentsData.canCreateDeployment, + canReadEnvironment: environmentsData.canReadEnvironment, + canCreateEnvironment: environmentsData.canCreateEnvironment, + projectEnvironmentsPath: environmentsData.projectEnvironmentsPath, + projectStoppedEnvironmentsPath: environmentsData.projectStoppedEnvironmentsPath, + newEnvironmentPath: environmentsData.newEnvironmentPath, + helpPagePath: environmentsData.helpPagePath, + + // Pagination Properties, + paginationInformation: {}, + pageNumber: 1, + }; + }, + + computed: { + scope() { + return gl.utils.getParameterByName('scope'); + }, + + canReadEnvironmentParsed() { + return gl.utils.convertPermissionToBoolean(this.canReadEnvironment); + }, + + canCreateDeploymentParsed() { + return gl.utils.convertPermissionToBoolean(this.canCreateDeployment); + }, + + canCreateEnvironmentParsed() { + return gl.utils.convertPermissionToBoolean(this.canCreateEnvironment); + }, + + }, + + /** + * Fetches all the environments and stores them. + * Toggles loading property. + */ + created() { + const scope = gl.utils.getParameterByName('scope') || this.visibility; + const pageNumber = gl.utils.getParameterByName('page') || this.pageNumber; + + const endpoint = `${this.endpoint}?scope=${scope}&page=${pageNumber}`; + + const service = new EnvironmentsService(endpoint); + + this.isLoading = true; + + return service.get() + .then(resp => ({ + headers: resp.headers, + body: resp.json(), + })) + .then((response) => { + this.store.storeAvailableCount(response.body.available_count); + this.store.storeStoppedCount(response.body.stopped_count); + this.store.storeEnvironments(response.body.environments); + this.store.setPagination(response.headers); + }) + .then(() => { + this.isLoading = false; + }) + .catch(() => { + this.isLoading = false; + new Flash('An error occurred while fetching the environments.', 'alert'); + }); + }, + + methods: { + toggleRow(model) { + return this.store.toggleFolder(model.name); + }, + + /** + * Will change the page number and update the URL. + * + * @param {Number} pageNumber desired page to go to. + * @return {String} + */ + changePage(pageNumber) { + const param = gl.utils.setParamInURL('page', pageNumber); + + gl.utils.visitUrl(param); + return param; + }, + }, + + template: ` + <div :class="cssContainerClass"> + <div class="top-area"> + <ul v-if="!isLoading" class="nav-links"> + <li v-bind:class="{ 'active': scope === null || scope === 'available' }"> + <a :href="projectEnvironmentsPath"> + Available + <span class="badge js-available-environments-count"> + {{state.availableCounter}} + </span> + </a> + </li> + <li v-bind:class="{ 'active' : scope === 'stopped' }"> + <a :href="projectStoppedEnvironmentsPath"> + Stopped + <span class="badge js-stopped-environments-count"> + {{state.stoppedCounter}} + </span> + </a> + </li> + </ul> + <div v-if="canCreateEnvironmentParsed && !isLoading" class="nav-controls"> + <a :href="newEnvironmentPath" class="btn btn-create"> + New environment + </a> + </div> + </div> + + <div class="content-list environments-container"> + <div class="environments-list-loading text-center" v-if="isLoading"> + <i class="fa fa-spinner fa-spin"></i> + </div> + + <div class="blank-state blank-state-no-icon" + v-if="!isLoading && state.environments.length === 0"> + <h2 class="blank-state-title js-blank-state-title"> + You don't have any environments right now. + </h2> + <p class="blank-state-text"> + Environments are places where code gets deployed, such as staging or production. + <br /> + <a :href="helpPagePath"> + Read more about environments + </a> + </p> + + <a v-if="canCreateEnvironmentParsed" + :href="newEnvironmentPath" + class="btn btn-create js-new-environment-button"> + New Environment + </a> + </div> + + <div class="table-holder" + v-if="!isLoading && state.environments.length > 0"> + + <environment-table + :environments="state.environments" + :can-create-deployment="canCreateDeploymentParsed" + :can-read-environment="canReadEnvironmentParsed"/> + </div> + + <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" + :change="changePage" + :pageInfo="state.paginationInformation"> + </table-pagination> + </div> + </div> + `, +}); diff --git a/app/assets/javascripts/environments/components/environment.js.es6 b/app/assets/javascripts/environments/components/environment.js.es6 deleted file mode 100644 index 5869323d1e2..00000000000 --- a/app/assets/javascripts/environments/components/environment.js.es6 +++ /dev/null @@ -1,193 +0,0 @@ -/* eslint-disable no-param-reassign, no-new */ -/* global Flash */ - -const Vue = window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -const EnvironmentsService = require('../services/environments_service'); -const EnvironmentTable = require('./environments_table'); -const EnvironmentsStore = require('../stores/environments_store'); -require('../../vue_shared/components/table_pagination'); -require('../../lib/utils/common_utils'); -require('../../vue_shared/vue_resource_interceptor'); - -module.exports = Vue.component('environment-component', { - - components: { - 'environment-table': EnvironmentTable, - 'table-pagination': gl.VueGlPagination, - }, - - data() { - const environmentsData = document.querySelector('#environments-list-view').dataset; - const store = new EnvironmentsStore(); - - return { - store, - state: store.state, - visibility: 'available', - isLoading: false, - cssContainerClass: environmentsData.cssClass, - endpoint: environmentsData.environmentsDataEndpoint, - canCreateDeployment: environmentsData.canCreateDeployment, - canReadEnvironment: environmentsData.canReadEnvironment, - canCreateEnvironment: environmentsData.canCreateEnvironment, - projectEnvironmentsPath: environmentsData.projectEnvironmentsPath, - projectStoppedEnvironmentsPath: environmentsData.projectStoppedEnvironmentsPath, - newEnvironmentPath: environmentsData.newEnvironmentPath, - helpPagePath: environmentsData.helpPagePath, - commitIconSvg: environmentsData.commitIconSvg, - playIconSvg: environmentsData.playIconSvg, - terminalIconSvg: environmentsData.terminalIconSvg, - - // Pagination Properties, - paginationInformation: {}, - pageNumber: 1, - }; - }, - - computed: { - scope() { - return gl.utils.getParameterByName('scope'); - }, - - canReadEnvironmentParsed() { - return gl.utils.convertPermissionToBoolean(this.canReadEnvironment); - }, - - canCreateDeploymentParsed() { - return gl.utils.convertPermissionToBoolean(this.canCreateDeployment); - }, - - canCreateEnvironmentParsed() { - return gl.utils.convertPermissionToBoolean(this.canCreateEnvironment); - }, - - }, - - /** - * Fetches all the environments and stores them. - * Toggles loading property. - */ - created() { - const scope = gl.utils.getParameterByName('scope') || this.visibility; - const pageNumber = gl.utils.getParameterByName('page') || this.pageNumber; - - const endpoint = `${this.endpoint}?scope=${scope}&page=${pageNumber}`; - - const service = new EnvironmentsService(endpoint); - - this.isLoading = true; - - return service.all() - .then(resp => ({ - headers: resp.headers, - body: resp.json(), - })) - .then((response) => { - this.store.storeAvailableCount(response.body.available_count); - this.store.storeStoppedCount(response.body.stopped_count); - this.store.storeEnvironments(response.body.environments); - this.store.setPagination(response.headers); - }) - .then(() => { - this.isLoading = false; - }) - .catch(() => { - this.isLoading = false; - new Flash('An error occurred while fetching the environments.', 'alert'); - }); - }, - - methods: { - toggleRow(model) { - return this.store.toggleFolder(model.name); - }, - - /** - * Will change the page number and update the URL. - * - * @param {Number} pageNumber desired page to go to. - * @return {String} - */ - changePage(pageNumber) { - const param = gl.utils.setParamInURL('page', pageNumber); - - gl.utils.visitUrl(param); - return param; - }, - }, - - template: ` - <div :class="cssContainerClass"> - <div class="top-area"> - <ul v-if="!isLoading" class="nav-links"> - <li v-bind:class="{ 'active': scope === null || scope === 'available' }"> - <a :href="projectEnvironmentsPath"> - Available - <span class="badge js-available-environments-count"> - {{state.availableCounter}} - </span> - </a> - </li> - <li v-bind:class="{ 'active' : scope === 'stopped' }"> - <a :href="projectStoppedEnvironmentsPath"> - Stopped - <span class="badge js-stopped-environments-count"> - {{state.stoppedCounter}} - </span> - </a> - </li> - </ul> - <div v-if="canCreateEnvironmentParsed && !isLoading" class="nav-controls"> - <a :href="newEnvironmentPath" class="btn btn-create"> - New environment - </a> - </div> - </div> - - <div class="content-list environments-container"> - <div class="environments-list-loading text-center" v-if="isLoading"> - <i class="fa fa-spinner fa-spin"></i> - </div> - - <div class="blank-state blank-state-no-icon" - v-if="!isLoading && state.environments.length === 0"> - <h2 class="blank-state-title js-blank-state-title"> - You don't have any environments right now. - </h2> - <p class="blank-state-text"> - Environments are places where code gets deployed, such as staging or production. - <br /> - <a :href="helpPagePath"> - Read more about environments - </a> - </p> - - <a v-if="canCreateEnvironmentParsed" - :href="newEnvironmentPath" - class="btn btn-create js-new-environment-button"> - New Environment - </a> - </div> - - <div class="table-holder" - v-if="!isLoading && state.environments.length > 0"> - - <environment-table - :environments="state.environments" - :can-create-deployment="canCreateDeploymentParsed" - :can-read-environment="canReadEnvironmentParsed" - :play-icon-svg="playIconSvg" - :terminal-icon-svg="terminalIconSvg" - :commit-icon-svg="commitIconSvg"> - </environment-table> - </div> - - <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" - :change="changePage" - :pageInfo="state.paginationInformation"> - </table-pagination> - </div> - </div> - `, -}); diff --git a/app/assets/javascripts/environments/components/environment_actions.js b/app/assets/javascripts/environments/components/environment_actions.js new file mode 100644 index 00000000000..15e3f8823d2 --- /dev/null +++ b/app/assets/javascripts/environments/components/environment_actions.js @@ -0,0 +1,41 @@ +const Vue = require('vue'); +const playIconSvg = require('icons/_icon_play.svg'); + +module.exports = Vue.component('actions-component', { + props: { + actions: { + type: Array, + required: false, + default: () => [], + }, + }, + + data() { + return { playIconSvg }; + }, + + template: ` + <div class="btn-group" role="group"> + <button class="dropdown btn btn-default dropdown-new" data-toggle="dropdown"> + <span> + <span class="js-dropdown-play-icon-container" v-html="playIconSvg"></span> + <i class="fa fa-caret-down"></i> + </span> + + <ul class="dropdown-menu dropdown-menu-align-right"> + <li v-for="action in actions"> + <a :href="action.play_path" + data-method="post" + rel="nofollow" + class="js-manual-action-link"> + ${playIconSvg} + <span> + {{action.name}} + </span> + </a> + </li> + </ul> + </button> + </div> + `, +}); diff --git a/app/assets/javascripts/environments/components/environment_actions.js.es6 b/app/assets/javascripts/environments/components/environment_actions.js.es6 deleted file mode 100644 index 978d4dd8b6b..00000000000 --- a/app/assets/javascripts/environments/components/environment_actions.js.es6 +++ /dev/null @@ -1,43 +0,0 @@ -const Vue = require('vue'); - -module.exports = Vue.component('actions-component', { - props: { - actions: { - type: Array, - required: false, - default: () => [], - }, - - playIconSvg: { - type: String, - required: false, - }, - }, - - template: ` - <div class="btn-group" role="group"> - <button class="dropdown btn btn-default dropdown-new" data-toggle="dropdown"> - <span> - <span class="js-dropdown-play-icon-container" v-html="playIconSvg"></span> - <i class="fa fa-caret-down"></i> - </span> - - <ul class="dropdown-menu dropdown-menu-align-right"> - <li v-for="action in actions"> - <a :href="action.play_path" - data-method="post" - rel="nofollow" - class="js-manual-action-link"> - - <span class="js-action-play-icon-container" v-html="playIconSvg"></span> - - <span> - {{action.name}} - </span> - </a> - </li> - </ul> - </button> - </div> - `, -}); diff --git a/app/assets/javascripts/environments/components/environment_external_url.js.es6 b/app/assets/javascripts/environments/components/environment_external_url.js index 2599bba3c59..2599bba3c59 100644 --- a/app/assets/javascripts/environments/components/environment_external_url.js.es6 +++ b/app/assets/javascripts/environments/components/environment_external_url.js diff --git a/app/assets/javascripts/environments/components/environment_item.js b/app/assets/javascripts/environments/components/environment_item.js new file mode 100644 index 00000000000..7f4e070b229 --- /dev/null +++ b/app/assets/javascripts/environments/components/environment_item.js @@ -0,0 +1,510 @@ +const Vue = require('vue'); +const Timeago = require('timeago.js'); + +require('../../lib/utils/text_utility'); +require('../../vue_shared/components/commit'); +const ActionsComponent = require('./environment_actions'); +const ExternalUrlComponent = require('./environment_external_url'); +const StopComponent = require('./environment_stop'); +const RollbackComponent = require('./environment_rollback'); +const TerminalButtonComponent = require('./environment_terminal_button'); + +/** + * Envrionment Item Component + * + * Renders a table row for each environment. + */ + +const timeagoInstance = new Timeago(); + +module.exports = Vue.component('environment-item', { + + components: { + 'commit-component': gl.CommitComponent, + 'actions-component': ActionsComponent, + 'external-url-component': ExternalUrlComponent, + 'stop-component': StopComponent, + 'rollback-component': RollbackComponent, + 'terminal-button-component': TerminalButtonComponent, + }, + + props: { + model: { + type: Object, + required: true, + default: () => ({}), + }, + + canCreateDeployment: { + type: Boolean, + required: false, + default: false, + }, + + canReadEnvironment: { + type: Boolean, + required: false, + default: false, + }, + }, + + computed: { + /** + * Verifies if `last_deployment` key exists in the current Envrionment. + * This key is required to render most of the html - this method works has + * an helper. + * + * @returns {Boolean} + */ + hasLastDeploymentKey() { + if (this.model && + this.model.last_deployment && + !this.$options.isObjectEmpty(this.model.last_deployment)) { + return true; + } + return false; + }, + + /** + * Verifies is the given environment has manual actions. + * Used to verify if we should render them or nor. + * + * @returns {Boolean|Undefined} + */ + hasManualActions() { + return this.model && + this.model.last_deployment && + this.model.last_deployment.manual_actions && + this.model.last_deployment.manual_actions.length > 0; + }, + + /** + * Returns the value of the `stop_action?` key provided in the response. + * + * @returns {Boolean} + */ + hasStopAction() { + return this.model && this.model['stop_action?']; + }, + + /** + * Verifies if the `deployable` key is present in `last_deployment` key. + * Used to verify whether we should or not render the rollback partial. + * + * @returns {Boolean|Undefined} + */ + canRetry() { + return this.model && + this.hasLastDeploymentKey && + this.model.last_deployment && + this.model.last_deployment.deployable; + }, + + /** + * Verifies if the date to be shown is present. + * + * @returns {Boolean|Undefined} + */ + canShowDate() { + return this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable !== undefined; + }, + + /** + * Human readable date. + * + * @returns {String} + */ + createdDate() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable.created_at) { + return timeagoInstance.format(this.model.last_deployment.deployable.created_at); + } + return ''; + }, + + /** + * Returns the manual actions with the name parsed. + * + * @returns {Array.<Object>|Undefined} + */ + manualActions() { + if (this.hasManualActions) { + return this.model.last_deployment.manual_actions.map((action) => { + const parsedAction = { + name: gl.text.humanize(action.name), + play_path: action.play_path, + }; + return parsedAction; + }); + } + return []; + }, + + /** + * Builds the string used in the user image alt attribute. + * + * @returns {String} + */ + userImageAltDescription() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.user && + this.model.last_deployment.user.username) { + return `${this.model.last_deployment.user.username}'s avatar'`; + } + return ''; + }, + + /** + * If provided, returns the commit tag. + * + * @returns {String|Undefined} + */ + commitTag() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.tag) { + return this.model.last_deployment.tag; + } + return undefined; + }, + + /** + * If provided, returns the commit ref. + * + * @returns {Object|Undefined} + */ + commitRef() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.ref) { + return this.model.last_deployment.ref; + } + return undefined; + }, + + /** + * If provided, returns the commit url. + * + * @returns {String|Undefined} + */ + commitUrl() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.commit_path) { + return this.model.last_deployment.commit.commit_path; + } + return undefined; + }, + + /** + * If provided, returns the commit short sha. + * + * @returns {String|Undefined} + */ + commitShortSha() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.short_id) { + return this.model.last_deployment.commit.short_id; + } + return undefined; + }, + + /** + * If provided, returns the commit title. + * + * @returns {String|Undefined} + */ + commitTitle() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.title) { + return this.model.last_deployment.commit.title; + } + return undefined; + }, + + /** + * If provided, returns the commit tag. + * + * @returns {Object|Undefined} + */ + commitAuthor() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.author) { + return this.model.last_deployment.commit.author; + } + + return undefined; + }, + + /** + * Verifies if the `retry_path` key is present and returns its value. + * + * @returns {String|Undefined} + */ + retryUrl() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable.retry_path) { + return this.model.last_deployment.deployable.retry_path; + } + return undefined; + }, + + /** + * Verifies if the `last?` key is present and returns its value. + * + * @returns {Boolean|Undefined} + */ + isLastDeployment() { + return this.model && this.model.last_deployment && + this.model.last_deployment['last?']; + }, + + /** + * Builds the name of the builds needed to display both the name and the id. + * + * @returns {String} + */ + buildName() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable) { + return `${this.model.last_deployment.deployable.name} #${this.model.last_deployment.deployable.id}`; + } + return ''; + }, + + /** + * Builds the needed string to show the internal id. + * + * @returns {String} + */ + deploymentInternalId() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.iid) { + return `#${this.model.last_deployment.iid}`; + } + return ''; + }, + + /** + * Verifies if the user object is present under last_deployment object. + * + * @returns {Boolean} + */ + deploymentHasUser() { + return this.model && + !this.$options.isObjectEmpty(this.model.last_deployment) && + !this.$options.isObjectEmpty(this.model.last_deployment.user); + }, + + /** + * Returns the user object nested with the last_deployment object. + * Used to render the template. + * + * @returns {Object} + */ + deploymentUser() { + if (this.model && + !this.$options.isObjectEmpty(this.model.last_deployment) && + !this.$options.isObjectEmpty(this.model.last_deployment.user)) { + return this.model.last_deployment.user; + } + return {}; + }, + + /** + * Verifies if the build name column should be rendered by verifing + * if all the information needed is present + * and if the environment is not a folder. + * + * @returns {Boolean} + */ + shouldRenderBuildName() { + return !this.model.isFolder && + !this.$options.isObjectEmpty(this.model.last_deployment) && + !this.$options.isObjectEmpty(this.model.last_deployment.deployable); + }, + + /** + * Verifies the presence of all the keys needed to render the buil_path. + * + * @return {String} + */ + buildPath() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable.build_path) { + return this.model.last_deployment.deployable.build_path; + } + + return ''; + }, + + /** + * Verifies the presence of all the keys needed to render the external_url. + * + * @return {String} + */ + externalURL() { + if (this.model && this.model.external_url) { + return this.model.external_url; + } + + return ''; + }, + + /** + * Verifies if deplyment internal ID should be rendered by verifing + * if all the information needed is present + * and if the environment is not a folder. + * + * @returns {Boolean} + */ + shouldRenderDeploymentID() { + return !this.model.isFolder && + !this.$options.isObjectEmpty(this.model.last_deployment) && + this.model.last_deployment.iid !== undefined; + }, + + environmentPath() { + if (this.model && this.model.environment_path) { + return this.model.environment_path; + } + + return ''; + }, + + /** + * Constructs folder URL based on the current location and the folder id. + * + * @return {String} + */ + folderUrl() { + return `${window.location.pathname}/folders/${this.model.folderName}`; + }, + + }, + + /** + * Helper to verify if certain given object are empty. + * Should be replaced by lodash _.isEmpty - https://lodash.com/docs/4.17.2#isEmpty + * @param {Object} object + * @returns {Bollean} + */ + isObjectEmpty(object) { + for (const key in object) { // eslint-disable-line + if (hasOwnProperty.call(object, key)) { + return false; + } + } + return true; + }, + + template: ` + <tr> + <td> + <a v-if="!model.isFolder" + class="environment-name" + :href="environmentPath"> + {{model.name}} + </a> + <a v-else class="folder-name" :href="folderUrl"> + <span class="folder-icon"> + <i class="fa fa-folder" aria-hidden="true"></i> + </span> + + <span> + {{model.folderName}} + </span> + + <span class="badge"> + {{model.size}} + </span> + </a> + </td> + + <td class="deployment-column"> + <span v-if="shouldRenderDeploymentID"> + {{deploymentInternalId}} + </span> + + <span v-if="!model.isFolder && deploymentHasUser"> + by + <a :href="deploymentUser.web_url" class="js-deploy-user-container"> + <img class="avatar has-tooltip s20" + :src="deploymentUser.avatar_url" + :alt="userImageAltDescription" + :title="deploymentUser.username" /> + </a> + </span> + </td> + + <td class="environments-build-cell"> + <a v-if="shouldRenderBuildName" + class="build-link" + :href="buildPath"> + {{buildName}} + </a> + </td> + + <td> + <div v-if="!model.isFolder && hasLastDeploymentKey" class="js-commit-component"> + <commit-component + :tag="commitTag" + :commit-ref="commitRef" + :commit-url="commitUrl" + :short-sha="commitShortSha" + :title="commitTitle" + :author="commitAuthor"/> + </div> + <p v-if="!model.isFolder && !hasLastDeploymentKey" class="commit-title"> + No deployments yet + </p> + </td> + + <td> + <span v-if="!model.isFolder && canShowDate" + class="environment-created-date-timeago"> + {{createdDate}} + </span> + </td> + + <td class="environments-actions"> + <div v-if="!model.isFolder" class="btn-group pull-right" role="group"> + <actions-component v-if="hasManualActions && canCreateDeployment" + :actions="manualActions"/> + + <external-url-component v-if="externalURL && canReadEnvironment" + :external-url="externalURL"/> + + <stop-component v-if="hasStopAction && canCreateDeployment" + :stop-url="model.stop_path"/> + + <terminal-button-component v-if="model && model.terminal_path" + :terminal-path="model.terminal_path"/> + + <rollback-component v-if="canRetry && canCreateDeployment" + :is-last-deployment="isLastDeployment" + :retry-url="retryUrl"/> + </div> + </td> + </tr> + `, +}); diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js.es6 deleted file mode 100644 index 3f782742c56..00000000000 --- a/app/assets/javascripts/environments/components/environment_item.js.es6 +++ /dev/null @@ -1,534 +0,0 @@ -const Vue = require('vue'); -const Timeago = require('timeago.js'); - -require('../../lib/utils/text_utility'); -require('../../vue_shared/components/commit'); -const ActionsComponent = require('./environment_actions'); -const ExternalUrlComponent = require('./environment_external_url'); -const StopComponent = require('./environment_stop'); -const RollbackComponent = require('./environment_rollback'); -const TerminalButtonComponent = require('./environment_terminal_button'); - -/** - * Envrionment Item Component - * - * Renders a table row for each environment. - */ - -const timeagoInstance = new Timeago(); - -module.exports = Vue.component('environment-item', { - - components: { - 'commit-component': gl.CommitComponent, - 'actions-component': ActionsComponent, - 'external-url-component': ExternalUrlComponent, - 'stop-component': StopComponent, - 'rollback-component': RollbackComponent, - 'terminal-button-component': TerminalButtonComponent, - }, - - props: { - model: { - type: Object, - required: true, - default: () => ({}), - }, - - canCreateDeployment: { - type: Boolean, - required: false, - default: false, - }, - - canReadEnvironment: { - type: Boolean, - required: false, - default: false, - }, - - commitIconSvg: { - type: String, - required: false, - }, - - playIconSvg: { - type: String, - required: false, - }, - - terminalIconSvg: { - type: String, - required: false, - }, - }, - - computed: { - /** - * Verifies if `last_deployment` key exists in the current Envrionment. - * This key is required to render most of the html - this method works has - * an helper. - * - * @returns {Boolean} - */ - hasLastDeploymentKey() { - if (this.model && - this.model.last_deployment && - !this.$options.isObjectEmpty(this.model.last_deployment)) { - return true; - } - return false; - }, - - /** - * Verifies is the given environment has manual actions. - * Used to verify if we should render them or nor. - * - * @returns {Boolean|Undefined} - */ - hasManualActions() { - return this.model && - this.model.last_deployment && - this.model.last_deployment.manual_actions && - this.model.last_deployment.manual_actions.length > 0; - }, - - /** - * Returns the value of the `stop_action?` key provided in the response. - * - * @returns {Boolean} - */ - hasStopAction() { - return this.model && this.model['stop_action?']; - }, - - /** - * Verifies if the `deployable` key is present in `last_deployment` key. - * Used to verify whether we should or not render the rollback partial. - * - * @returns {Boolean|Undefined} - */ - canRetry() { - return this.model && - this.hasLastDeploymentKey && - this.model.last_deployment && - this.model.last_deployment.deployable; - }, - - /** - * Verifies if the date to be shown is present. - * - * @returns {Boolean|Undefined} - */ - canShowDate() { - return this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable !== undefined; - }, - - /** - * Human readable date. - * - * @returns {String} - */ - createdDate() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable.created_at) { - return timeagoInstance.format(this.model.last_deployment.deployable.created_at); - } - return ''; - }, - - /** - * Returns the manual actions with the name parsed. - * - * @returns {Array.<Object>|Undefined} - */ - manualActions() { - if (this.hasManualActions) { - return this.model.last_deployment.manual_actions.map((action) => { - const parsedAction = { - name: gl.text.humanize(action.name), - play_path: action.play_path, - }; - return parsedAction; - }); - } - return []; - }, - - /** - * Builds the string used in the user image alt attribute. - * - * @returns {String} - */ - userImageAltDescription() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.user && - this.model.last_deployment.user.username) { - return `${this.model.last_deployment.user.username}'s avatar'`; - } - return ''; - }, - - /** - * If provided, returns the commit tag. - * - * @returns {String|Undefined} - */ - commitTag() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.tag) { - return this.model.last_deployment.tag; - } - return undefined; - }, - - /** - * If provided, returns the commit ref. - * - * @returns {Object|Undefined} - */ - commitRef() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.ref) { - return this.model.last_deployment.ref; - } - return undefined; - }, - - /** - * If provided, returns the commit url. - * - * @returns {String|Undefined} - */ - commitUrl() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.commit_path) { - return this.model.last_deployment.commit.commit_path; - } - return undefined; - }, - - /** - * If provided, returns the commit short sha. - * - * @returns {String|Undefined} - */ - commitShortSha() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.short_id) { - return this.model.last_deployment.commit.short_id; - } - return undefined; - }, - - /** - * If provided, returns the commit title. - * - * @returns {String|Undefined} - */ - commitTitle() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.title) { - return this.model.last_deployment.commit.title; - } - return undefined; - }, - - /** - * If provided, returns the commit tag. - * - * @returns {Object|Undefined} - */ - commitAuthor() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.author) { - return this.model.last_deployment.commit.author; - } - - return undefined; - }, - - /** - * Verifies if the `retry_path` key is present and returns its value. - * - * @returns {String|Undefined} - */ - retryUrl() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable.retry_path) { - return this.model.last_deployment.deployable.retry_path; - } - return undefined; - }, - - /** - * Verifies if the `last?` key is present and returns its value. - * - * @returns {Boolean|Undefined} - */ - isLastDeployment() { - return this.model && this.model.last_deployment && - this.model.last_deployment['last?']; - }, - - /** - * Builds the name of the builds needed to display both the name and the id. - * - * @returns {String} - */ - buildName() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable) { - return `${this.model.last_deployment.deployable.name} #${this.model.last_deployment.deployable.id}`; - } - return ''; - }, - - /** - * Builds the needed string to show the internal id. - * - * @returns {String} - */ - deploymentInternalId() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.iid) { - return `#${this.model.last_deployment.iid}`; - } - return ''; - }, - - /** - * Verifies if the user object is present under last_deployment object. - * - * @returns {Boolean} - */ - deploymentHasUser() { - return this.model && - !this.$options.isObjectEmpty(this.model.last_deployment) && - !this.$options.isObjectEmpty(this.model.last_deployment.user); - }, - - /** - * Returns the user object nested with the last_deployment object. - * Used to render the template. - * - * @returns {Object} - */ - deploymentUser() { - if (this.model && - !this.$options.isObjectEmpty(this.model.last_deployment) && - !this.$options.isObjectEmpty(this.model.last_deployment.user)) { - return this.model.last_deployment.user; - } - return {}; - }, - - /** - * Verifies if the build name column should be rendered by verifing - * if all the information needed is present - * and if the environment is not a folder. - * - * @returns {Boolean} - */ - shouldRenderBuildName() { - return !this.model.isFolder && - !this.$options.isObjectEmpty(this.model.last_deployment) && - !this.$options.isObjectEmpty(this.model.last_deployment.deployable); - }, - - /** - * Verifies the presence of all the keys needed to render the buil_path. - * - * @return {String} - */ - buildPath() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable.build_path) { - return this.model.last_deployment.deployable.build_path; - } - - return ''; - }, - - /** - * Verifies the presence of all the keys needed to render the external_url. - * - * @return {String} - */ - externalURL() { - if (this.model && this.model.external_url) { - return this.model.external_url; - } - - return ''; - }, - - /** - * Verifies if deplyment internal ID should be rendered by verifing - * if all the information needed is present - * and if the environment is not a folder. - * - * @returns {Boolean} - */ - shouldRenderDeploymentID() { - return !this.model.isFolder && - !this.$options.isObjectEmpty(this.model.last_deployment) && - this.model.last_deployment.iid !== undefined; - }, - - environmentPath() { - if (this.model && this.model.environment_path) { - return this.model.environment_path; - } - - return ''; - }, - - /** - * Constructs folder URL based on the current location and the folder id. - * - * @return {String} - */ - folderUrl() { - return `${window.location.pathname}/folders/${this.model.folderName}`; - }, - - }, - - /** - * Helper to verify if certain given object are empty. - * Should be replaced by lodash _.isEmpty - https://lodash.com/docs/4.17.2#isEmpty - * @param {Object} object - * @returns {Bollean} - */ - isObjectEmpty(object) { - for (const key in object) { // eslint-disable-line - if (hasOwnProperty.call(object, key)) { - return false; - } - } - return true; - }, - - template: ` - <tr> - <td> - <a v-if="!model.isFolder" - class="environment-name" - :href="environmentPath"> - {{model.name}} - </a> - <a v-else class="folder-name" :href="folderUrl"> - <span class="folder-icon"> - <i class="fa fa-folder" aria-hidden="true"></i> - </span> - - <span> - {{model.folderName}} - </span> - - <span class="badge"> - {{model.size}} - </span> - </a> - </td> - - <td class="deployment-column"> - <span v-if="shouldRenderDeploymentID"> - {{deploymentInternalId}} - </span> - - <span v-if="!model.isFolder && deploymentHasUser"> - by - <a :href="deploymentUser.web_url" class="js-deploy-user-container"> - <img class="avatar has-tooltip s20" - :src="deploymentUser.avatar_url" - :alt="userImageAltDescription" - :title="deploymentUser.username" /> - </a> - </span> - </td> - - <td class="environments-build-cell"> - <a v-if="shouldRenderBuildName" - class="build-link" - :href="buildPath"> - {{buildName}} - </a> - </td> - - <td> - <div v-if="!model.isFolder && hasLastDeploymentKey" class="js-commit-component"> - <commit-component - :tag="commitTag" - :commit-ref="commitRef" - :commit-url="commitUrl" - :short-sha="commitShortSha" - :title="commitTitle" - :author="commitAuthor" - :commit-icon-svg="commitIconSvg"> - </commit-component> - </div> - <p v-if="!model.isFolder && !hasLastDeploymentKey" class="commit-title"> - No deployments yet - </p> - </td> - - <td> - <span v-if="!model.isFolder && canShowDate" - class="environment-created-date-timeago"> - {{createdDate}} - </span> - </td> - - <td class="environments-actions"> - <div v-if="!model.isFolder" class="btn-group pull-right" role="group"> - <actions-component v-if="hasManualActions && canCreateDeployment" - :play-icon-svg="playIconSvg" - :actions="manualActions"> - </actions-component> - - <external-url-component v-if="externalURL && canReadEnvironment" - :external-url="externalURL"> - </external-url-component> - - <stop-component v-if="hasStopAction && canCreateDeployment" - :stop-url="model.stop_path"> - </stop-component> - - <terminal-button-component v-if="model && model.terminal_path" - :terminal-icon-svg="terminalIconSvg" - :terminal-path="model.terminal_path"> - </terminal-button-component> - - <rollback-component v-if="canRetry && canCreateDeployment" - :is-last-deployment="isLastDeployment" - :retry-url="retryUrl"> - </rollback-component> - </div> - </td> - </tr> - `, -}); diff --git a/app/assets/javascripts/environments/components/environment_rollback.js.es6 b/app/assets/javascripts/environments/components/environment_rollback.js index daf126eb4e8..daf126eb4e8 100644 --- a/app/assets/javascripts/environments/components/environment_rollback.js.es6 +++ b/app/assets/javascripts/environments/components/environment_rollback.js diff --git a/app/assets/javascripts/environments/components/environment_stop.js.es6 b/app/assets/javascripts/environments/components/environment_stop.js index 96983a19568..96983a19568 100644 --- a/app/assets/javascripts/environments/components/environment_stop.js.es6 +++ b/app/assets/javascripts/environments/components/environment_stop.js diff --git a/app/assets/javascripts/environments/components/environment_terminal_button.js b/app/assets/javascripts/environments/components/environment_terminal_button.js new file mode 100644 index 00000000000..e86607e78f4 --- /dev/null +++ b/app/assets/javascripts/environments/components/environment_terminal_button.js @@ -0,0 +1,26 @@ +/** + * Renders a terminal button to open a web terminal. + * Used in environments table. + */ +const Vue = require('vue'); +const terminalIconSvg = require('icons/_icon_terminal.svg'); + +module.exports = Vue.component('terminal-button-component', { + props: { + terminalPath: { + type: String, + default: '', + }, + }, + + data() { + return { terminalIconSvg }; + }, + + template: ` + <a class="btn terminal-button" + :href="terminalPath"> + ${terminalIconSvg} + </a> + `, +}); diff --git a/app/assets/javascripts/environments/components/environment_terminal_button.js.es6 b/app/assets/javascripts/environments/components/environment_terminal_button.js.es6 deleted file mode 100644 index 481e0d15e7a..00000000000 --- a/app/assets/javascripts/environments/components/environment_terminal_button.js.es6 +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Renders a terminal button to open a web terminal. - * Used in environments table. - */ -const Vue = require('vue'); - -module.exports = Vue.component('terminal-button-component', { - props: { - terminalPath: { - type: String, - default: '', - }, - terminalIconSvg: { - type: String, - default: '', - }, - }, - - template: ` - <a class="btn terminal-button" - :href="terminalPath"> - <span class="js-terminal-icon-container" v-html="terminalIconSvg"></span> - </a> - `, -}); diff --git a/app/assets/javascripts/environments/components/environments_table.js b/app/assets/javascripts/environments/components/environments_table.js new file mode 100644 index 00000000000..4088d63be80 --- /dev/null +++ b/app/assets/javascripts/environments/components/environments_table.js @@ -0,0 +1,56 @@ +/** + * Render environments table. + */ +const Vue = require('vue'); +const EnvironmentItem = require('./environment_item'); + +module.exports = Vue.component('environment-table-component', { + + components: { + 'environment-item': EnvironmentItem, + }, + + props: { + environments: { + type: Array, + required: true, + default: () => ([]), + }, + + canReadEnvironment: { + type: Boolean, + required: false, + default: false, + }, + + canCreateDeployment: { + type: Boolean, + required: false, + default: false, + }, + }, + + template: ` + <table class="table ci-table"> + <thead> + <tr> + <th class="environments-name">Environment</th> + <th class="environments-deploy">Last deployment</th> + <th class="environments-build">Job</th> + <th class="environments-commit">Commit</th> + <th class="environments-date">Updated</th> + <th class="environments-actions"></th> + </tr> + </thead> + <tbody> + <template v-for="model in environments" + v-bind:model="model"> + <tr is="environment-item" + :model="model" + :can-create-deployment="canCreateDeployment" + :can-read-environment="canReadEnvironment"></tr> + </template> + </tbody> + </table> + `, +}); diff --git a/app/assets/javascripts/environments/components/environments_table.js.es6 b/app/assets/javascripts/environments/components/environments_table.js.es6 deleted file mode 100644 index 33ebca19f5d..00000000000 --- a/app/assets/javascripts/environments/components/environments_table.js.es6 +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Render environments table. - */ -const Vue = require('vue'); -const EnvironmentItem = require('./environment_item'); - -module.exports = Vue.component('environment-table-component', { - - components: { - 'environment-item': EnvironmentItem, - }, - - props: { - environments: { - type: Array, - required: true, - default: () => ([]), - }, - - canReadEnvironment: { - type: Boolean, - required: false, - default: false, - }, - - canCreateDeployment: { - type: Boolean, - required: false, - default: false, - }, - - commitIconSvg: { - type: String, - required: false, - }, - - playIconSvg: { - type: String, - required: false, - }, - - terminalIconSvg: { - type: String, - required: false, - }, - }, - - template: ` - <table class="table ci-table"> - <thead> - <tr> - <th class="environments-name">Environment</th> - <th class="environments-deploy">Last deployment</th> - <th class="environments-build">Job</th> - <th class="environments-commit">Commit</th> - <th class="environments-date">Updated</th> - <th class="environments-actions"></th> - </tr> - </thead> - <tbody> - <template v-for="model in environments" - v-bind:model="model"> - <tr is="environment-item" - :model="model" - :can-create-deployment="canCreateDeployment" - :can-read-environment="canReadEnvironment" - :play-icon-svg="playIconSvg" - :terminal-icon-svg="terminalIconSvg" - :commit-icon-svg="commitIconSvg"></tr> - </template> - </tbody> - </table> - `, -}); diff --git a/app/assets/javascripts/environments/environments_bundle.js.es6 b/app/assets/javascripts/environments/environments_bundle.js index 7bbba91bc10..7bbba91bc10 100644 --- a/app/assets/javascripts/environments/environments_bundle.js.es6 +++ b/app/assets/javascripts/environments/environments_bundle.js diff --git a/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 b/app/assets/javascripts/environments/folder/environments_folder_bundle.js index d2ca465351a..d2ca465351a 100644 --- a/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 +++ b/app/assets/javascripts/environments/folder/environments_folder_bundle.js diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.js b/app/assets/javascripts/environments/folder/environments_folder_view.js new file mode 100644 index 00000000000..2a9d0492d7a --- /dev/null +++ b/app/assets/javascripts/environments/folder/environments_folder_view.js @@ -0,0 +1,182 @@ +/* eslint-disable no-param-reassign, no-new */ +/* global Flash */ + +const Vue = window.Vue = require('vue'); +window.Vue.use(require('vue-resource')); +const EnvironmentsService = require('../services/environments_service'); +const EnvironmentTable = require('../components/environments_table'); +const EnvironmentsStore = require('../stores/environments_store'); +require('../../vue_shared/components/table_pagination'); +require('../../lib/utils/common_utils'); +require('../../vue_shared/vue_resource_interceptor'); + +module.exports = Vue.component('environment-folder-view', { + + components: { + 'environment-table': EnvironmentTable, + 'table-pagination': gl.VueGlPagination, + }, + + data() { + const environmentsData = document.querySelector('#environments-folder-list-view').dataset; + const store = new EnvironmentsStore(); + const pathname = window.location.pathname; + const endpoint = `${pathname}.json`; + const folderName = pathname.substr(pathname.lastIndexOf('/') + 1); + + return { + store, + folderName, + endpoint, + state: store.state, + visibility: 'available', + isLoading: false, + cssContainerClass: environmentsData.cssClass, + canCreateDeployment: environmentsData.canCreateDeployment, + canReadEnvironment: environmentsData.canReadEnvironment, + + // svgs + commitIconSvg: environmentsData.commitIconSvg, + playIconSvg: environmentsData.playIconSvg, + terminalIconSvg: environmentsData.terminalIconSvg, + + // Pagination Properties, + paginationInformation: {}, + pageNumber: 1, + }; + }, + + computed: { + scope() { + return gl.utils.getParameterByName('scope'); + }, + + canReadEnvironmentParsed() { + return gl.utils.convertPermissionToBoolean(this.canReadEnvironment); + }, + + canCreateDeploymentParsed() { + return gl.utils.convertPermissionToBoolean(this.canCreateDeployment); + }, + + /** + * URL to link in the stopped tab. + * + * @return {String} + */ + stoppedPath() { + return `${window.location.pathname}?scope=stopped`; + }, + + /** + * URL to link in the available tab. + * + * @return {String} + */ + availablePath() { + return window.location.pathname; + }, + }, + + /** + * Fetches all the environments and stores them. + * Toggles loading property. + */ + created() { + const scope = gl.utils.getParameterByName('scope') || this.visibility; + const pageNumber = gl.utils.getParameterByName('page') || this.pageNumber; + + const endpoint = `${this.endpoint}?scope=${scope}&page=${pageNumber}`; + + const service = new EnvironmentsService(endpoint); + + this.isLoading = true; + + return service.get() + .then(resp => ({ + headers: resp.headers, + body: resp.json(), + })) + .then((response) => { + this.store.storeAvailableCount(response.body.available_count); + this.store.storeStoppedCount(response.body.stopped_count); + this.store.storeEnvironments(response.body.environments); + this.store.setPagination(response.headers); + }) + .then(() => { + this.isLoading = false; + }) + .catch(() => { + this.isLoading = false; + new Flash('An error occurred while fetching the environments.', 'alert'); + }); + }, + + methods: { + /** + * Will change the page number and update the URL. + * + * @param {Number} pageNumber desired page to go to. + */ + changePage(pageNumber) { + const param = gl.utils.setParamInURL('page', pageNumber); + + gl.utils.visitUrl(param); + return param; + }, + }, + + template: ` + <div :class="cssContainerClass"> + <div class="top-area" v-if="!isLoading"> + + <h4 class="js-folder-name environments-folder-name"> + Environments / <b>{{folderName}}</b> + </h4> + + <ul class="nav-links"> + <li v-bind:class="{ 'active': scope === null || scope === 'available' }"> + <a :href="availablePath" class="js-available-environments-folder-tab"> + Available + <span class="badge js-available-environments-count"> + {{state.availableCounter}} + </span> + </a> + </li> + <li v-bind:class="{ 'active' : scope === 'stopped' }"> + <a :href="stoppedPath" class="js-stopped-environments-folder-tab"> + Stopped + <span class="badge js-stopped-environments-count"> + {{state.stoppedCounter}} + </span> + </a> + </li> + </ul> + </div> + + <div class="environments-container"> + <div class="environments-list-loading text-center" v-if="isLoading"> + <i class="fa fa-spinner fa-spin"></i> + </div> + + <div class="table-holder" + v-if="!isLoading && state.environments.length > 0"> + + <environment-table + :environments="state.environments" + :can-create-deployment="canCreateDeploymentParsed" + :can-read-environment="canReadEnvironmentParsed" + :play-icon-svg="playIconSvg" + :terminal-icon-svg="terminalIconSvg" + :commit-icon-svg="commitIconSvg"> + </environment-table> + + <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" + :change="changePage" + :pageInfo="state.paginationInformation"> + </table-pagination> + </div> + </div> + </div> + `, +}); diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 b/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 deleted file mode 100644 index 53d52965758..00000000000 --- a/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 +++ /dev/null @@ -1,182 +0,0 @@ -/* eslint-disable no-param-reassign, no-new */ -/* global Flash */ - -const Vue = window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -const EnvironmentsService = require('../services/environments_service'); -const EnvironmentTable = require('../components/environments_table'); -const EnvironmentsStore = require('../stores/environments_store'); -require('../../vue_shared/components/table_pagination'); -require('../../lib/utils/common_utils'); -require('../../vue_shared/vue_resource_interceptor'); - -module.exports = Vue.component('environment-folder-view', { - - components: { - 'environment-table': EnvironmentTable, - 'table-pagination': gl.VueGlPagination, - }, - - data() { - const environmentsData = document.querySelector('#environments-folder-list-view').dataset; - const store = new EnvironmentsStore(); - const pathname = window.location.pathname; - const endpoint = `${pathname}.json`; - const folderName = pathname.substr(pathname.lastIndexOf('/') + 1); - - return { - store, - folderName, - endpoint, - state: store.state, - visibility: 'available', - isLoading: false, - cssContainerClass: environmentsData.cssClass, - canCreateDeployment: environmentsData.canCreateDeployment, - canReadEnvironment: environmentsData.canReadEnvironment, - - // svgs - commitIconSvg: environmentsData.commitIconSvg, - playIconSvg: environmentsData.playIconSvg, - terminalIconSvg: environmentsData.terminalIconSvg, - - // Pagination Properties, - paginationInformation: {}, - pageNumber: 1, - }; - }, - - computed: { - scope() { - return gl.utils.getParameterByName('scope'); - }, - - canReadEnvironmentParsed() { - return gl.utils.convertPermissionToBoolean(this.canReadEnvironment); - }, - - canCreateDeploymentParsed() { - return gl.utils.convertPermissionToBoolean(this.canCreateDeployment); - }, - - /** - * URL to link in the stopped tab. - * - * @return {String} - */ - stoppedPath() { - return `${window.location.pathname}?scope=stopped`; - }, - - /** - * URL to link in the available tab. - * - * @return {String} - */ - availablePath() { - return window.location.pathname; - }, - }, - - /** - * Fetches all the environments and stores them. - * Toggles loading property. - */ - created() { - const scope = gl.utils.getParameterByName('scope') || this.visibility; - const pageNumber = gl.utils.getParameterByName('page') || this.pageNumber; - - const endpoint = `${this.endpoint}?scope=${scope}&page=${pageNumber}`; - - const service = new EnvironmentsService(endpoint); - - this.isLoading = true; - - return service.all() - .then(resp => ({ - headers: resp.headers, - body: resp.json(), - })) - .then((response) => { - this.store.storeAvailableCount(response.body.available_count); - this.store.storeStoppedCount(response.body.stopped_count); - this.store.storeEnvironments(response.body.environments); - this.store.setPagination(response.headers); - }) - .then(() => { - this.isLoading = false; - }) - .catch(() => { - this.isLoading = false; - new Flash('An error occurred while fetching the environments.', 'alert'); - }); - }, - - methods: { - /** - * Will change the page number and update the URL. - * - * @param {Number} pageNumber desired page to go to. - */ - changePage(pageNumber) { - const param = gl.utils.setParamInURL('page', pageNumber); - - gl.utils.visitUrl(param); - return param; - }, - }, - - template: ` - <div :class="cssContainerClass"> - <div class="top-area" v-if="!isLoading"> - - <h4 class="js-folder-name environments-folder-name"> - Environments / <b>{{folderName}}</b> - </h4> - - <ul class="nav-links"> - <li v-bind:class="{ 'active': scope === null || scope === 'available' }"> - <a :href="availablePath" class="js-available-environments-folder-tab"> - Available - <span class="badge js-available-environments-count"> - {{state.availableCounter}} - </span> - </a> - </li> - <li v-bind:class="{ 'active' : scope === 'stopped' }"> - <a :href="stoppedPath" class="js-stopped-environments-folder-tab"> - Stopped - <span class="badge js-stopped-environments-count"> - {{state.stoppedCounter}} - </span> - </a> - </li> - </ul> - </div> - - <div class="environments-container"> - <div class="environments-list-loading text-center" v-if="isLoading"> - <i class="fa fa-spinner fa-spin"></i> - </div> - - <div class="table-holder" - v-if="!isLoading && state.environments.length > 0"> - - <environment-table - :environments="state.environments" - :can-create-deployment="canCreateDeploymentParsed" - :can-read-environment="canReadEnvironmentParsed" - :play-icon-svg="playIconSvg" - :terminal-icon-svg="terminalIconSvg" - :commit-icon-svg="commitIconSvg"> - </environment-table> - - <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" - :change="changePage" - :pageInfo="state.paginationInformation"> - </table-pagination> - </div> - </div> - </div> - `, -}); diff --git a/app/assets/javascripts/environments/services/environments_service.js b/app/assets/javascripts/environments/services/environments_service.js new file mode 100644 index 00000000000..effc6c4c838 --- /dev/null +++ b/app/assets/javascripts/environments/services/environments_service.js @@ -0,0 +1,13 @@ +const Vue = require('vue'); + +class EnvironmentsService { + constructor(endpoint) { + this.environments = Vue.resource(endpoint); + } + + get() { + return this.environments.get(); + } +} + +module.exports = EnvironmentsService; diff --git a/app/assets/javascripts/environments/services/environments_service.js.es6 b/app/assets/javascripts/environments/services/environments_service.js.es6 deleted file mode 100644 index 9cef335868e..00000000000 --- a/app/assets/javascripts/environments/services/environments_service.js.es6 +++ /dev/null @@ -1,13 +0,0 @@ -const Vue = require('vue'); - -class EnvironmentsService { - constructor(endpoint) { - this.environments = Vue.resource(endpoint); - } - - all() { - return this.environments.get(); - } -} - -module.exports = EnvironmentsService; diff --git a/app/assets/javascripts/environments/stores/environments_store.js.es6 b/app/assets/javascripts/environments/stores/environments_store.js index 15cd9bde08e..15cd9bde08e 100644 --- a/app/assets/javascripts/environments/stores/environments_store.js.es6 +++ b/app/assets/javascripts/environments/stores/environments_store.js diff --git a/app/assets/javascripts/extensions/array.js.es6 b/app/assets/javascripts/extensions/array.js index f8256a8d26d..f8256a8d26d 100644 --- a/app/assets/javascripts/extensions/array.js.es6 +++ b/app/assets/javascripts/extensions/array.js diff --git a/app/assets/javascripts/extensions/custom_event.js.es6 b/app/assets/javascripts/extensions/custom_event.js index abedae4c1c7..abedae4c1c7 100644 --- a/app/assets/javascripts/extensions/custom_event.js.es6 +++ b/app/assets/javascripts/extensions/custom_event.js diff --git a/app/assets/javascripts/extensions/element.js.es6 b/app/assets/javascripts/extensions/element.js index 90ab79305a7..90ab79305a7 100644 --- a/app/assets/javascripts/extensions/element.js.es6 +++ b/app/assets/javascripts/extensions/element.js diff --git a/app/assets/javascripts/extensions/object.js.es6 b/app/assets/javascripts/extensions/object.js index 70a2d765abd..70a2d765abd 100644 --- a/app/assets/javascripts/extensions/object.js.es6 +++ b/app/assets/javascripts/extensions/object.js diff --git a/app/assets/javascripts/extensions/string.js b/app/assets/javascripts/extensions/string.js new file mode 100644 index 00000000000..fe23be0bbc1 --- /dev/null +++ b/app/assets/javascripts/extensions/string.js @@ -0,0 +1,2 @@ +require('string.prototype.codepointat'); +require('string.fromcodepoint'); diff --git a/app/assets/javascripts/filterable_list.js b/app/assets/javascripts/filterable_list.js new file mode 100644 index 00000000000..47a40e28461 --- /dev/null +++ b/app/assets/javascripts/filterable_list.js @@ -0,0 +1,45 @@ +/** + * Makes search request for content when user types a value in the search input. + * Updates the html content of the page with the received one. + */ +export default class FilterableList { + constructor(form, filter, holder) { + this.filterForm = form; + this.listFilterElement = filter; + this.listHolderElement = holder; + } + + initSearch() { + this.debounceFilter = _.debounce(this.filterResults.bind(this), 500); + + this.listFilterElement.removeEventListener('input', this.debounceFilter); + this.listFilterElement.addEventListener('input', this.debounceFilter); + } + + filterResults() { + const form = this.filterForm; + const filterUrl = `${form.getAttribute('action')}?${$(form).serialize()}`; + + $(this.listHolderElement).fadeTo(250, 0.5); + + return $.ajax({ + url: form.getAttribute('action'), + data: $(form).serialize(), + type: 'GET', + dataType: 'json', + context: this, + complete() { + $(this.listHolderElement).fadeTo(250, 1); + }, + success(data) { + this.listHolderElement.innerHTML = data.html; + + // Change url so if user reload a page - search results are saved + return window.history.replaceState({ + page: filterUrl, + + }, document.title, filterUrl); + }, + }); + } +} diff --git a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 b/app/assets/javascripts/filtered_search/dropdown_hint.js index 9e92d544bef..9e92d544bef 100644 --- a/app/assets/javascripts/filtered_search/dropdown_hint.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_hint.js diff --git a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_non_user.js index b3dc3e502c5..b3dc3e502c5 100644 --- a/app/assets/javascripts/filtered_search/dropdown_non_user.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_non_user.js diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 b/app/assets/javascripts/filtered_search/dropdown_user.js index 7e9c6f74aa5..7e9c6f74aa5 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_user.js diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js index de3fa116717..de3fa116717 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js index dd565da507e..dd565da507e 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index cecd3518ce3..cecd3518ce3 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js index bbafead0305..bbafead0305 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js diff --git a/app/assets/javascripts/filtered_search/filtered_search_token_keys.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_token_keys.js index e6b53cd4b55..e6b53cd4b55 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_token_keys.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_token_keys.js diff --git a/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js index 9bf1b1ced88..9bf1b1ced88 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_tokenizer.js diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js new file mode 100644 index 00000000000..1bc04a5ad96 --- /dev/null +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -0,0 +1,396 @@ +/* eslint-disable func-names, space-before-function-paren, no-template-curly-in-string, comma-dangle, object-shorthand, quotes, dot-notation, no-else-return, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-param-reassign, no-useless-escape, prefer-template, consistent-return, wrap-iife, prefer-arrow-callback, camelcase, no-unused-vars, no-useless-return, vars-on-top, max-len */ + +const emojiMap = require('emoji-map'); +const emojiAliases = require('emoji-aliases'); +const glEmoji = require('./behaviors/gl_emoji'); + +const glEmojiTag = glEmoji.glEmojiTag; + +// Creates the variables for setting up GFM auto-completion +(function() { + if (window.gl == null) { + window.gl = {}; + } + + function sanitize(str) { + return str.replace(/<(?:.|\n)*?>/gm, ''); + } + + window.gl.GfmAutoComplete = { + dataSources: {}, + defaultLoadingData: ['loading'], + cachedData: {}, + isLoadingData: {}, + atTypeMap: { + ':': 'emojis', + '@': 'members', + '#': 'issues', + '!': 'mergeRequests', + '~': 'labels', + '%': 'milestones', + '/': 'commands' + }, + // Emoji + Emoji: { + templateFunction: function(name) { + return `<li> + ${name} ${glEmojiTag(name)} + </li> + `; + } + }, + // Team Members + Members: { + template: '<li>${avatarTag} ${username} <small>${title}</small></li>' + }, + Labels: { + template: '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>' + }, + // Issues and MergeRequests + Issues: { + template: '<li><small>${id}</small> ${title}</li>' + }, + // Milestones + Milestones: { + template: '<li>${title}</li>' + }, + Loading: { + template: '<li style="pointer-events: none;"><i class="fa fa-refresh fa-spin"></i> Loading...</li>' + }, + DefaultOptions: { + sorter: function(query, items, searchKey) { + this.setting.highlightFirst = this.setting.alwaysHighlightFirst || query.length > 0; + if (gl.GfmAutoComplete.isLoading(items)) { + this.setting.highlightFirst = false; + return items; + } + return $.fn.atwho["default"].callbacks.sorter(query, items, searchKey); + }, + filter: function(query, data, searchKey) { + if (gl.GfmAutoComplete.isLoading(data)) { + gl.GfmAutoComplete.fetchData(this.$inputor, this.at); + return data; + } else { + return $.fn.atwho["default"].callbacks.filter(query, data, searchKey); + } + }, + beforeInsert: function(value) { + if (value && !this.setting.skipSpecialCharacterTest) { + var withoutAt = value.substring(1); + if (withoutAt && /[^\w\d]/.test(withoutAt)) value = value.charAt() + '"' + withoutAt + '"'; + } + return value; + }, + matcher: function (flag, subtext) { + // The below is taken from At.js source + // Tweaked to commands to start without a space only if char before is a non-word character + // https://github.com/ichord/At.js + var _a, _y, regexp, match, atSymbolsWithBar, atSymbolsWithoutBar; + atSymbolsWithBar = Object.keys(this.app.controllers).join('|'); + atSymbolsWithoutBar = Object.keys(this.app.controllers).join(''); + subtext = subtext.split(/\s+/g).pop(); + flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + + _a = decodeURI("%C3%80"); + _y = decodeURI("%C3%BF"); + + regexp = new RegExp("^(?:\\B|[^a-zA-Z0-9_" + atSymbolsWithoutBar + "]|\\s)" + flag + "(?!" + atSymbolsWithBar + ")((?:[A-Za-z" + _a + "-" + _y + "0-9_\'\.\+\-]|[^\\x00-\\x7a])*)$", 'gi'); + + match = regexp.exec(subtext); + + if (match) { + return match[1]; + } else { + return null; + } + } + }, + setup: function(input) { + // Add GFM auto-completion to all input fields, that accept GFM input. + this.input = input || $('.js-gfm-input'); + this.setupLifecycle(); + }, + setupLifecycle() { + this.input.each((i, input) => { + const $input = $(input); + $input.off('focus.setupAtWho').on('focus.setupAtWho', this.setupAtWho.bind(this, $input)); + // This triggers at.js again + // Needed for slash commands with suffixes (ex: /label ~) + $input.on('inserted-commands.atwho', $input.trigger.bind($input, 'keyup')); + }); + }, + setupAtWho: function($input) { + // Emoji + $input.atwho({ + at: ':', + displayTpl: function(value) { + return value && value.name ? this.Emoji.templateFunction(value.name) : this.Loading.template; + }.bind(this), + insertTpl: ':${name}:', + skipSpecialCharacterTest: true, + data: this.defaultLoadingData, + callbacks: { + sorter: this.DefaultOptions.sorter, + beforeInsert: this.DefaultOptions.beforeInsert, + filter: this.DefaultOptions.filter + } + }); + // Team Members + $input.atwho({ + at: '@', + displayTpl: function(value) { + return value.username != null ? this.Members.template : this.Loading.template; + }.bind(this), + insertTpl: '${atwho-at}${username}', + searchKey: 'search', + alwaysHighlightFirst: true, + skipSpecialCharacterTest: true, + data: this.defaultLoadingData, + callbacks: { + sorter: this.DefaultOptions.sorter, + filter: this.DefaultOptions.filter, + beforeInsert: this.DefaultOptions.beforeInsert, + matcher: this.DefaultOptions.matcher, + beforeSave: function(members) { + return $.map(members, function(m) { + let title = ''; + if (m.username == null) { + return m; + } + title = m.name; + if (m.count) { + title += " (" + m.count + ")"; + } + + const autoCompleteAvatar = m.avatar_url || m.username.charAt(0).toUpperCase(); + const imgAvatar = `<img src="${m.avatar_url}" alt="${m.username}" class="avatar avatar-inline center s26"/>`; + const txtAvatar = `<div class="avatar center avatar-inline s26">${autoCompleteAvatar}</div>`; + + return { + username: m.username, + avatarTag: autoCompleteAvatar.length === 1 ? txtAvatar : imgAvatar, + title: sanitize(title), + search: sanitize(m.username + " " + m.name) + }; + }); + } + } + }); + $input.atwho({ + at: '#', + alias: 'issues', + searchKey: 'search', + displayTpl: function(value) { + return value.title != null ? this.Issues.template : this.Loading.template; + }.bind(this), + data: this.defaultLoadingData, + insertTpl: '${atwho-at}${id}', + callbacks: { + sorter: this.DefaultOptions.sorter, + filter: this.DefaultOptions.filter, + beforeInsert: this.DefaultOptions.beforeInsert, + matcher: this.DefaultOptions.matcher, + beforeSave: function(issues) { + return $.map(issues, function(i) { + if (i.title == null) { + return i; + } + return { + id: i.iid, + title: sanitize(i.title), + search: i.iid + " " + i.title + }; + }); + } + } + }); + $input.atwho({ + at: '%', + alias: 'milestones', + searchKey: 'search', + insertTpl: '${atwho-at}${title}', + displayTpl: function(value) { + return value.title != null ? this.Milestones.template : this.Loading.template; + }.bind(this), + data: this.defaultLoadingData, + callbacks: { + matcher: this.DefaultOptions.matcher, + sorter: this.DefaultOptions.sorter, + beforeInsert: this.DefaultOptions.beforeInsert, + filter: this.DefaultOptions.filter, + beforeSave: function(milestones) { + return $.map(milestones, function(m) { + if (m.title == null) { + return m; + } + return { + id: m.iid, + title: sanitize(m.title), + search: "" + m.title + }; + }); + } + } + }); + $input.atwho({ + at: '!', + alias: 'mergerequests', + searchKey: 'search', + displayTpl: function(value) { + return value.title != null ? this.Issues.template : this.Loading.template; + }.bind(this), + data: this.defaultLoadingData, + insertTpl: '${atwho-at}${id}', + callbacks: { + sorter: this.DefaultOptions.sorter, + filter: this.DefaultOptions.filter, + beforeInsert: this.DefaultOptions.beforeInsert, + matcher: this.DefaultOptions.matcher, + beforeSave: function(merges) { + return $.map(merges, function(m) { + if (m.title == null) { + return m; + } + return { + id: m.iid, + title: sanitize(m.title), + search: m.iid + " " + m.title + }; + }); + } + } + }); + $input.atwho({ + at: '~', + alias: 'labels', + searchKey: 'search', + data: this.defaultLoadingData, + displayTpl: function(value) { + return this.isLoading(value) ? this.Loading.template : this.Labels.template; + }.bind(this), + insertTpl: '${atwho-at}${title}', + callbacks: { + matcher: this.DefaultOptions.matcher, + beforeInsert: this.DefaultOptions.beforeInsert, + filter: this.DefaultOptions.filter, + sorter: this.DefaultOptions.sorter, + beforeSave: function(merges) { + if (gl.GfmAutoComplete.isLoading(merges)) return merges; + var sanitizeLabelTitle; + sanitizeLabelTitle = function(title) { + if (/[\w\?&]+\s+[\w\?&]+/g.test(title)) { + return "\"" + (sanitize(title)) + "\""; + } else { + return sanitize(title); + } + }; + return $.map(merges, function(m) { + return { + title: sanitize(m.title), + color: m.color, + search: "" + m.title + }; + }); + } + } + }); + // We don't instantiate the slash commands autocomplete for note and issue/MR edit forms + $input.filter('[data-supports-slash-commands="true"]').atwho({ + at: '/', + alias: 'commands', + searchKey: 'search', + skipSpecialCharacterTest: true, + data: this.defaultLoadingData, + displayTpl: function(value) { + if (this.isLoading(value)) return this.Loading.template; + var tpl = '<li>/${name}'; + if (value.aliases.length > 0) { + tpl += ' <small>(or /<%- aliases.join(", /") %>)</small>'; + } + if (value.params.length > 0) { + tpl += ' <small><%- params.join(" ") %></small>'; + } + if (value.description !== '') { + tpl += '<small class="description"><i><%- description %></i></small>'; + } + tpl += '</li>'; + return _.template(tpl)(value); + }.bind(this), + insertTpl: function(value) { + var tpl = "/${name} "; + var reference_prefix = null; + if (value.params.length > 0) { + reference_prefix = value.params[0][0]; + if (/^[@%~]/.test(reference_prefix)) { + tpl += '<%- reference_prefix %>'; + } + } + return _.template(tpl)({ reference_prefix: reference_prefix }); + }, + suffix: '', + callbacks: { + sorter: this.DefaultOptions.sorter, + filter: this.DefaultOptions.filter, + beforeInsert: this.DefaultOptions.beforeInsert, + beforeSave: function(commands) { + if (gl.GfmAutoComplete.isLoading(commands)) return commands; + return $.map(commands, function(c) { + var search = c.name; + if (c.aliases.length > 0) { + search = search + " " + c.aliases.join(" "); + } + return { + name: c.name, + aliases: c.aliases, + params: c.params, + description: c.description, + search: search + }; + }); + }, + matcher: function(flag, subtext, should_startWithSpace, acceptSpaceBar) { + var regexp = /(?:^|\n)\/([A-Za-z_]*)$/gi; + var match = regexp.exec(subtext); + if (match) { + return match[1]; + } else { + return null; + } + } + } + }); + return; + }, + fetchData: function($input, at) { + if (this.isLoadingData[at]) return; + this.isLoadingData[at] = true; + if (this.cachedData[at]) { + this.loadData($input, at, this.cachedData[at]); + } else if (this.atTypeMap[at] === 'emojis') { + this.loadData($input, at, Object.keys(emojiMap).concat(Object.keys(emojiAliases))); + } else { + $.getJSON(this.dataSources[this.atTypeMap[at]], (data) => { + this.loadData($input, at, data); + }).fail(() => { this.isLoadingData[at] = false; }); + } + }, + loadData: function($input, at, data) { + this.isLoadingData[at] = false; + this.cachedData[at] = data; + $input.atwho('load', at, data); + // This trigger at.js again + // otherwise we would be stuck with loading until the user types + return $input.trigger('keyup'); + }, + isLoading(data) { + var dataToInspect = data; + if (data && data.length > 0) { + dataToInspect = data[0]; + } + + var loadingState = this.defaultLoadingData[0]; + return dataToInspect && + (dataToInspect === loadingState || dataToInspect.name === loadingState); + } + }; +}).call(window); diff --git a/app/assets/javascripts/gfm_auto_complete.js.es6 b/app/assets/javascripts/gfm_auto_complete.js.es6 deleted file mode 100644 index 60d6658dc16..00000000000 --- a/app/assets/javascripts/gfm_auto_complete.js.es6 +++ /dev/null @@ -1,383 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren, no-template-curly-in-string, comma-dangle, object-shorthand, quotes, dot-notation, no-else-return, one-var, no-var, no-underscore-dangle, one-var-declaration-per-line, no-param-reassign, no-useless-escape, prefer-template, consistent-return, wrap-iife, prefer-arrow-callback, camelcase, no-unused-vars, no-useless-return, vars-on-top, max-len */ - -// Creates the variables for setting up GFM auto-completion -(function() { - if (window.gl == null) { - window.gl = {}; - } - - function sanitize(str) { - return str.replace(/<(?:.|\n)*?>/gm, ''); - } - - window.gl.GfmAutoComplete = { - dataSources: {}, - defaultLoadingData: ['loading'], - cachedData: {}, - isLoadingData: {}, - atTypeMap: { - ':': 'emojis', - '@': 'members', - '#': 'issues', - '!': 'mergeRequests', - '~': 'labels', - '%': 'milestones', - '/': 'commands' - }, - // Emoji - Emoji: { - template: '<li>${name} <img alt="${name}" height="20" src="${path}" width="20" /></li>' - }, - // Team Members - Members: { - template: '<li>${avatarTag} ${username} <small>${title}</small></li>' - }, - Labels: { - template: '<li><span class="dropdown-label-box" style="background: ${color}"></span> ${title}</li>' - }, - // Issues and MergeRequests - Issues: { - template: '<li><small>${id}</small> ${title}</li>' - }, - // Milestones - Milestones: { - template: '<li>${title}</li>' - }, - Loading: { - template: '<li style="pointer-events: none;"><i class="fa fa-refresh fa-spin"></i> Loading...</li>' - }, - DefaultOptions: { - sorter: function(query, items, searchKey) { - this.setting.highlightFirst = this.setting.alwaysHighlightFirst || query.length > 0; - if (gl.GfmAutoComplete.isLoading(items)) { - this.setting.highlightFirst = false; - return items; - } - return $.fn.atwho["default"].callbacks.sorter(query, items, searchKey); - }, - filter: function(query, data, searchKey) { - if (gl.GfmAutoComplete.isLoading(data)) { - gl.GfmAutoComplete.fetchData(this.$inputor, this.at); - return data; - } else { - return $.fn.atwho["default"].callbacks.filter(query, data, searchKey); - } - }, - beforeInsert: function(value) { - if (value && !this.setting.skipSpecialCharacterTest) { - var withoutAt = value.substring(1); - if (withoutAt && /[^\w\d]/.test(withoutAt)) value = value.charAt() + '"' + withoutAt + '"'; - } - return value; - }, - matcher: function (flag, subtext) { - // The below is taken from At.js source - // Tweaked to commands to start without a space only if char before is a non-word character - // https://github.com/ichord/At.js - var _a, _y, regexp, match, atSymbolsWithBar, atSymbolsWithoutBar; - atSymbolsWithBar = Object.keys(this.app.controllers).join('|'); - atSymbolsWithoutBar = Object.keys(this.app.controllers).join(''); - subtext = subtext.split(/\s+/g).pop(); - flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - - _a = decodeURI("%C3%80"); - _y = decodeURI("%C3%BF"); - - regexp = new RegExp("^(?:\\B|[^a-zA-Z0-9_" + atSymbolsWithoutBar + "]|\\s)" + flag + "(?!" + atSymbolsWithBar + ")((?:[A-Za-z" + _a + "-" + _y + "0-9_\'\.\+\-]|[^\\x00-\\x7a])*)$", 'gi'); - - match = regexp.exec(subtext); - - if (match) { - return match[1]; - } else { - return null; - } - } - }, - setup: function(input) { - // Add GFM auto-completion to all input fields, that accept GFM input. - this.input = input || $('.js-gfm-input'); - this.setupLifecycle(); - }, - setupLifecycle() { - this.input.each((i, input) => { - const $input = $(input); - $input.off('focus.setupAtWho').on('focus.setupAtWho', this.setupAtWho.bind(this, $input)); - // This triggers at.js again - // Needed for slash commands with suffixes (ex: /label ~) - $input.on('inserted-commands.atwho', $input.trigger.bind($input, 'keyup')); - }); - }, - setupAtWho: function($input) { - // Emoji - $input.atwho({ - at: ':', - displayTpl: function(value) { - return value.path != null ? this.Emoji.template : this.Loading.template; - }.bind(this), - insertTpl: ':${name}:', - skipSpecialCharacterTest: true, - data: this.defaultLoadingData, - callbacks: { - sorter: this.DefaultOptions.sorter, - beforeInsert: this.DefaultOptions.beforeInsert, - filter: this.DefaultOptions.filter - } - }); - // Team Members - $input.atwho({ - at: '@', - displayTpl: function(value) { - return value.username != null ? this.Members.template : this.Loading.template; - }.bind(this), - insertTpl: '${atwho-at}${username}', - searchKey: 'search', - alwaysHighlightFirst: true, - skipSpecialCharacterTest: true, - data: this.defaultLoadingData, - callbacks: { - sorter: this.DefaultOptions.sorter, - filter: this.DefaultOptions.filter, - beforeInsert: this.DefaultOptions.beforeInsert, - matcher: this.DefaultOptions.matcher, - beforeSave: function(members) { - return $.map(members, function(m) { - let title = ''; - if (m.username == null) { - return m; - } - title = m.name; - if (m.count) { - title += " (" + m.count + ")"; - } - - const autoCompleteAvatar = m.avatar_url || m.username.charAt(0).toUpperCase(); - const imgAvatar = `<img src="${m.avatar_url}" alt="${m.username}" class="avatar avatar-inline center s26"/>`; - const txtAvatar = `<div class="avatar center avatar-inline s26">${autoCompleteAvatar}</div>`; - - return { - username: m.username, - avatarTag: autoCompleteAvatar.length === 1 ? txtAvatar : imgAvatar, - title: sanitize(title), - search: sanitize(m.username + " " + m.name) - }; - }); - } - } - }); - $input.atwho({ - at: '#', - alias: 'issues', - searchKey: 'search', - displayTpl: function(value) { - return value.title != null ? this.Issues.template : this.Loading.template; - }.bind(this), - data: this.defaultLoadingData, - insertTpl: '${atwho-at}${id}', - callbacks: { - sorter: this.DefaultOptions.sorter, - filter: this.DefaultOptions.filter, - beforeInsert: this.DefaultOptions.beforeInsert, - matcher: this.DefaultOptions.matcher, - beforeSave: function(issues) { - return $.map(issues, function(i) { - if (i.title == null) { - return i; - } - return { - id: i.iid, - title: sanitize(i.title), - search: i.iid + " " + i.title - }; - }); - } - } - }); - $input.atwho({ - at: '%', - alias: 'milestones', - searchKey: 'search', - insertTpl: '${atwho-at}${title}', - displayTpl: function(value) { - return value.title != null ? this.Milestones.template : this.Loading.template; - }.bind(this), - data: this.defaultLoadingData, - callbacks: { - matcher: this.DefaultOptions.matcher, - sorter: this.DefaultOptions.sorter, - beforeInsert: this.DefaultOptions.beforeInsert, - filter: this.DefaultOptions.filter, - beforeSave: function(milestones) { - return $.map(milestones, function(m) { - if (m.title == null) { - return m; - } - return { - id: m.iid, - title: sanitize(m.title), - search: "" + m.title - }; - }); - } - } - }); - $input.atwho({ - at: '!', - alias: 'mergerequests', - searchKey: 'search', - displayTpl: function(value) { - return value.title != null ? this.Issues.template : this.Loading.template; - }.bind(this), - data: this.defaultLoadingData, - insertTpl: '${atwho-at}${id}', - callbacks: { - sorter: this.DefaultOptions.sorter, - filter: this.DefaultOptions.filter, - beforeInsert: this.DefaultOptions.beforeInsert, - matcher: this.DefaultOptions.matcher, - beforeSave: function(merges) { - return $.map(merges, function(m) { - if (m.title == null) { - return m; - } - return { - id: m.iid, - title: sanitize(m.title), - search: m.iid + " " + m.title - }; - }); - } - } - }); - $input.atwho({ - at: '~', - alias: 'labels', - searchKey: 'search', - data: this.defaultLoadingData, - displayTpl: function(value) { - return this.isLoading(value) ? this.Loading.template : this.Labels.template; - }.bind(this), - insertTpl: '${atwho-at}${title}', - callbacks: { - matcher: this.DefaultOptions.matcher, - beforeInsert: this.DefaultOptions.beforeInsert, - filter: this.DefaultOptions.filter, - sorter: this.DefaultOptions.sorter, - beforeSave: function(merges) { - if (gl.GfmAutoComplete.isLoading(merges)) return merges; - var sanitizeLabelTitle; - sanitizeLabelTitle = function(title) { - if (/[\w\?&]+\s+[\w\?&]+/g.test(title)) { - return "\"" + (sanitize(title)) + "\""; - } else { - return sanitize(title); - } - }; - return $.map(merges, function(m) { - return { - title: sanitize(m.title), - color: m.color, - search: "" + m.title - }; - }); - } - } - }); - // We don't instantiate the slash commands autocomplete for note and issue/MR edit forms - $input.filter('[data-supports-slash-commands="true"]').atwho({ - at: '/', - alias: 'commands', - searchKey: 'search', - skipSpecialCharacterTest: true, - data: this.defaultLoadingData, - displayTpl: function(value) { - if (this.isLoading(value)) return this.Loading.template; - var tpl = '<li>/${name}'; - if (value.aliases.length > 0) { - tpl += ' <small>(or /<%- aliases.join(", /") %>)</small>'; - } - if (value.params.length > 0) { - tpl += ' <small><%- params.join(" ") %></small>'; - } - if (value.description !== '') { - tpl += '<small class="description"><i><%- description %></i></small>'; - } - tpl += '</li>'; - return _.template(tpl)(value); - }.bind(this), - insertTpl: function(value) { - var tpl = "/${name} "; - var reference_prefix = null; - if (value.params.length > 0) { - reference_prefix = value.params[0][0]; - if (/^[@%~]/.test(reference_prefix)) { - tpl += '<%- reference_prefix %>'; - } - } - return _.template(tpl)({ reference_prefix: reference_prefix }); - }, - suffix: '', - callbacks: { - sorter: this.DefaultOptions.sorter, - filter: this.DefaultOptions.filter, - beforeInsert: this.DefaultOptions.beforeInsert, - beforeSave: function(commands) { - if (gl.GfmAutoComplete.isLoading(commands)) return commands; - return $.map(commands, function(c) { - var search = c.name; - if (c.aliases.length > 0) { - search = search + " " + c.aliases.join(" "); - } - return { - name: c.name, - aliases: c.aliases, - params: c.params, - description: c.description, - search: search - }; - }); - }, - matcher: function(flag, subtext, should_startWithSpace, acceptSpaceBar) { - var regexp = /(?:^|\n)\/([A-Za-z_]*)$/gi; - var match = regexp.exec(subtext); - if (match) { - return match[1]; - } else { - return null; - } - } - } - }); - return; - }, - fetchData: function($input, at) { - if (this.isLoadingData[at]) return; - this.isLoadingData[at] = true; - if (this.cachedData[at]) { - this.loadData($input, at, this.cachedData[at]); - } else { - $.getJSON(this.dataSources[this.atTypeMap[at]], (data) => { - this.loadData($input, at, data); - }).fail(() => { this.isLoadingData[at] = false; }); - } - }, - loadData: function($input, at, data) { - this.isLoadingData[at] = false; - this.cachedData[at] = data; - $input.atwho('load', at, data); - // This trigger at.js again - // otherwise we would be stuck with loading until the user types - return $input.trigger('keyup'); - }, - isLoading(data) { - var dataToInspect = data; - if (data && data.length > 0) { - dataToInspect = data[0]; - } - - var loadingState = this.defaultLoadingData[0]; - return dataToInspect && - (dataToInspect === loadingState || dataToInspect.name === loadingState); - } - }; -}).call(window); diff --git a/app/assets/javascripts/gl_field_error.js.es6 b/app/assets/javascripts/gl_field_error.js index f7cbecc0385..f7cbecc0385 100644 --- a/app/assets/javascripts/gl_field_error.js.es6 +++ b/app/assets/javascripts/gl_field_error.js diff --git a/app/assets/javascripts/gl_field_errors.js.es6 b/app/assets/javascripts/gl_field_errors.js index e9add115429..e9add115429 100644 --- a/app/assets/javascripts/gl_field_errors.js.es6 +++ b/app/assets/javascripts/gl_field_errors.js diff --git a/app/assets/javascripts/gl_form.js.es6 b/app/assets/javascripts/gl_form.js index 0b446ff364a..0b446ff364a 100644 --- a/app/assets/javascripts/gl_form.js.es6 +++ b/app/assets/javascripts/gl_form.js diff --git a/app/assets/javascripts/graphs/graphs_bundle.js b/app/assets/javascripts/graphs/graphs_bundle.js index ea5afbd9d29..a433c7ba8f0 100644 --- a/app/assets/javascripts/graphs/graphs_bundle.js +++ b/app/assets/javascripts/graphs/graphs_bundle.js @@ -1,4 +1,6 @@ +import Chart from 'vendor/Chart'; import ContributorsStatGraph from './stat_graph_contributors'; // export to global scope +window.Chart = Chart; window.ContributorsStatGraph = ContributorsStatGraph; diff --git a/app/assets/javascripts/group_label_subscription.js.es6 b/app/assets/javascripts/group_label_subscription.js index 15e695e81cf..15e695e81cf 100644 --- a/app/assets/javascripts/group_label_subscription.js.es6 +++ b/app/assets/javascripts/group_label_subscription.js diff --git a/app/assets/javascripts/groups_list.js b/app/assets/javascripts/groups_list.js index 0ef81e49444..56a8cbf6d03 100644 --- a/app/assets/javascripts/groups_list.js +++ b/app/assets/javascripts/groups_list.js @@ -1,47 +1,18 @@ +import FilterableList from './filterable_list'; + /** - * Based on project list search. * Makes search request for groups when user types a value in the search input. * Updates the html content of the page with the received one. */ export default class GroupsList { constructor() { - this.groupsListFilterElement = document.querySelector('.js-groups-list-filter'); - this.groupsListHolderElement = document.querySelector('.js-groups-list-holder'); - - this.initSearch(); - } - - initSearch() { - this.debounceFilter = _.debounce(this.filterResults.bind(this), 500); - - this.groupsListFilterElement.removeEventListener('input', this.debounceFilter); - this.groupsListFilterElement.addEventListener('input', this.debounceFilter); - } - - filterResults() { const form = document.querySelector('form#group-filter-form'); - const groupFilterUrl = `${form.getAttribute('action')}?${$(form).serialize()}`; - - $(this.groupsListHolderElement).fadeTo(250, 0.5); - - return $.ajax({ - url: form.getAttribute('action'), - data: $(form).serialize(), - type: 'GET', - dataType: 'json', - context: this, - complete() { - $(this.groupsListHolderElement).fadeTo(250, 1); - }, - success(data) { - this.groupsListHolderElement.innerHTML = data.html; - - // Change url so if user reload a page - search results are saved - return window.history.replaceState({ - page: groupFilterUrl, + const filter = document.querySelector('.js-groups-list-filter'); + const holder = document.querySelector('.js-groups-list-holder'); - }, document.title, groupFilterUrl); - }, - }); + if (form && filter && holder) { + const list = new FilterableList(form, filter, holder); + list.initSearch(); + } } } diff --git a/app/assets/javascripts/issuable.js.es6 b/app/assets/javascripts/issuable.js index 3bfce32768a..3bfce32768a 100644 --- a/app/assets/javascripts/issuable.js.es6 +++ b/app/assets/javascripts/issuable.js diff --git a/app/assets/javascripts/issuable/issuable_bundle.js.es6 b/app/assets/javascripts/issuable/issuable_bundle.js index e927cc0077c..e927cc0077c 100644 --- a/app/assets/javascripts/issuable/issuable_bundle.js.es6 +++ b/app/assets/javascripts/issuable/issuable_bundle.js diff --git a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js new file mode 100644 index 00000000000..357b3487ca9 --- /dev/null +++ b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js @@ -0,0 +1,42 @@ +/* global Vue */ +import stopwatchSvg from 'icons/_icon_stopwatch.svg'; + +require('../../../lib/utils/pretty_time'); + +(() => { + Vue.component('time-tracking-collapsed-state', { + name: 'time-tracking-collapsed-state', + props: [ + 'showComparisonState', + 'showSpentOnlyState', + 'showEstimateOnlyState', + 'showNoTimeTrackingState', + 'timeSpentHumanReadable', + 'timeEstimateHumanReadable', + ], + methods: { + abbreviateTime(timeStr) { + return gl.utils.prettyTime.abbreviateTime(timeStr); + }, + }, + template: ` + <div class='sidebar-collapsed-icon'> + ${stopwatchSvg} + <div class='time-tracking-collapsed-summary'> + <div class='compare' v-if='showComparisonState'> + <span>{{ abbreviateTime(timeSpentHumanReadable) }} / {{ abbreviateTime(timeEstimateHumanReadable) }}</span> + </div> + <div class='estimate-only' v-if='showEstimateOnlyState'> + <span class='bold'>-- / {{ abbreviateTime(timeEstimateHumanReadable) }}</span> + </div> + <div class='spend-only' v-if='showSpentOnlyState'> + <span class='bold'>{{ abbreviateTime(timeSpentHumanReadable) }} / --</span> + </div> + <div class='no-tracking' v-if='showNoTimeTrackingState'> + <span class='no-value'>None</span> + </div> + </div> + </div> + `, + }); +})(); diff --git a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es6 deleted file mode 100644 index bf27fbac5d7..00000000000 --- a/app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es6 +++ /dev/null @@ -1,41 +0,0 @@ -/* global Vue */ -require('../../../lib/utils/pretty_time'); - -(() => { - Vue.component('time-tracking-collapsed-state', { - name: 'time-tracking-collapsed-state', - props: [ - 'showComparisonState', - 'showSpentOnlyState', - 'showEstimateOnlyState', - 'showNoTimeTrackingState', - 'timeSpentHumanReadable', - 'timeEstimateHumanReadable', - 'stopwatchSvg', - ], - methods: { - abbreviateTime(timeStr) { - return gl.utils.prettyTime.abbreviateTime(timeStr); - }, - }, - template: ` - <div class='sidebar-collapsed-icon'> - <div v-html='stopwatchSvg'></div> - <div class='time-tracking-collapsed-summary'> - <div class='compare' v-if='showComparisonState'> - <span>{{ abbreviateTime(timeSpentHumanReadable) }} / {{ abbreviateTime(timeEstimateHumanReadable) }}</span> - </div> - <div class='estimate-only' v-if='showEstimateOnlyState'> - <span class='bold'>-- / {{ abbreviateTime(timeEstimateHumanReadable) }}</span> - </div> - <div class='spend-only' v-if='showSpentOnlyState'> - <span class='bold'>{{ abbreviateTime(timeSpentHumanReadable) }} / --</span> - </div> - <div class='no-tracking' v-if='showNoTimeTrackingState'> - <span class='no-value'>None</span> - </div> - </div> - </div> - `, - }); -})(); diff --git a/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js index 750468c679b..750468c679b 100644 --- a/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js.es6 +++ b/app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js diff --git a/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js index 309e9f2f9ef..309e9f2f9ef 100644 --- a/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js.es6 +++ b/app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js diff --git a/app/assets/javascripts/issuable/time_tracking/components/help_state.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/help_state.js index d7ced6d7151..d7ced6d7151 100644 --- a/app/assets/javascripts/issuable/time_tracking/components/help_state.js.es6 +++ b/app/assets/javascripts/issuable/time_tracking/components/help_state.js diff --git a/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js index 1d2ca643b5b..1d2ca643b5b 100644 --- a/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js.es6 +++ b/app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js diff --git a/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js index ed283fec3c3..ed283fec3c3 100644 --- a/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js.es6 +++ b/app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js diff --git a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js new file mode 100644 index 00000000000..1fae2d62b14 --- /dev/null +++ b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js @@ -0,0 +1,117 @@ +/* global Vue */ + +require('./help_state'); +require('./collapsed_state'); +require('./spent_only_pane'); +require('./no_tracking_pane'); +require('./estimate_only_pane'); +require('./comparison_pane'); + +(() => { + Vue.component('issuable-time-tracker', { + name: 'issuable-time-tracker', + props: [ + 'time_estimate', + 'time_spent', + 'human_time_estimate', + 'human_time_spent', + 'docsUrl', + ], + data() { + return { + showHelp: false, + }; + }, + computed: { + timeSpent() { + return this.time_spent; + }, + timeEstimate() { + return this.time_estimate; + }, + timeEstimateHumanReadable() { + return this.human_time_estimate; + }, + timeSpentHumanReadable() { + return this.human_time_spent; + }, + hasTimeSpent() { + return !!this.timeSpent; + }, + hasTimeEstimate() { + return !!this.timeEstimate; + }, + showComparisonState() { + return this.hasTimeEstimate && this.hasTimeSpent; + }, + showEstimateOnlyState() { + return this.hasTimeEstimate && !this.hasTimeSpent; + }, + showSpentOnlyState() { + return this.hasTimeSpent && !this.hasTimeEstimate; + }, + showNoTimeTrackingState() { + return !this.hasTimeEstimate && !this.hasTimeSpent; + }, + showHelpState() { + return !!this.showHelp; + }, + }, + methods: { + toggleHelpState(show) { + this.showHelp = show; + }, + }, + template: ` + <div class='time_tracker time-tracking-component-wrap' v-cloak> + <time-tracking-collapsed-state + :show-comparison-state='showComparisonState' + :show-help-state='showHelpState' + :show-spent-only-state='showSpentOnlyState' + :show-estimate-only-state='showEstimateOnlyState' + :time-spent-human-readable='timeSpentHumanReadable' + :time-estimate-human-readable='timeEstimateHumanReadable'> + </time-tracking-collapsed-state> + <div class='title hide-collapsed'> + Time tracking + <div class='help-button pull-right' + v-if='!showHelpState' + @click='toggleHelpState(true)'> + <i class='fa fa-question-circle' aria-hidden='true'></i> + </div> + <div class='close-help-button pull-right' + v-if='showHelpState' + @click='toggleHelpState(false)'> + <i class='fa fa-close' aria-hidden='true'></i> + </div> + </div> + <div class='time-tracking-content hide-collapsed'> + <time-tracking-estimate-only-pane + v-if='showEstimateOnlyState' + :time-estimate-human-readable='timeEstimateHumanReadable'> + </time-tracking-estimate-only-pane> + <time-tracking-spent-only-pane + v-if='showSpentOnlyState' + :time-spent-human-readable='timeSpentHumanReadable'> + </time-tracking-spent-only-pane> + <time-tracking-no-tracking-pane + v-if='showNoTimeTrackingState'> + </time-tracking-no-tracking-pane> + <time-tracking-comparison-pane + v-if='showComparisonState' + :time-estimate='timeEstimate' + :time-spent='timeSpent' + :time-spent-human-readable='timeSpentHumanReadable' + :time-estimate-human-readable='timeEstimateHumanReadable'> + </time-tracking-comparison-pane> + <transition name='help-state-toggle'> + <time-tracking-help-state + v-if='showHelpState' + :docs-url='docsUrl'> + </time-tracking-help-state> + </transition> + </div> + </div> + `, + }); +})(); diff --git a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6 b/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6 deleted file mode 100644 index b271ea83330..00000000000 --- a/app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6 +++ /dev/null @@ -1,119 +0,0 @@ -/* global Vue */ - -require('./help_state'); -require('./collapsed_state'); -require('./spent_only_pane'); -require('./no_tracking_pane'); -require('./estimate_only_pane'); -require('./comparison_pane'); - -(() => { - Vue.component('issuable-time-tracker', { - name: 'issuable-time-tracker', - props: [ - 'time_estimate', - 'time_spent', - 'human_time_estimate', - 'human_time_spent', - 'stopwatchSvg', - 'docsUrl', - ], - data() { - return { - showHelp: false, - }; - }, - computed: { - timeSpent() { - return this.time_spent; - }, - timeEstimate() { - return this.time_estimate; - }, - timeEstimateHumanReadable() { - return this.human_time_estimate; - }, - timeSpentHumanReadable() { - return this.human_time_spent; - }, - hasTimeSpent() { - return !!this.timeSpent; - }, - hasTimeEstimate() { - return !!this.timeEstimate; - }, - showComparisonState() { - return this.hasTimeEstimate && this.hasTimeSpent; - }, - showEstimateOnlyState() { - return this.hasTimeEstimate && !this.hasTimeSpent; - }, - showSpentOnlyState() { - return this.hasTimeSpent && !this.hasTimeEstimate; - }, - showNoTimeTrackingState() { - return !this.hasTimeEstimate && !this.hasTimeSpent; - }, - showHelpState() { - return !!this.showHelp; - }, - }, - methods: { - toggleHelpState(show) { - this.showHelp = show; - }, - }, - template: ` - <div class='time_tracker time-tracking-component-wrap' v-cloak> - <time-tracking-collapsed-state - :show-comparison-state='showComparisonState' - :show-help-state='showHelpState' - :show-spent-only-state='showSpentOnlyState' - :show-estimate-only-state='showEstimateOnlyState' - :time-spent-human-readable='timeSpentHumanReadable' - :time-estimate-human-readable='timeEstimateHumanReadable' - :stopwatch-svg='stopwatchSvg'> - </time-tracking-collapsed-state> - <div class='title hide-collapsed'> - Time tracking - <div class='help-button pull-right' - v-if='!showHelpState' - @click='toggleHelpState(true)'> - <i class='fa fa-question-circle' aria-hidden='true'></i> - </div> - <div class='close-help-button pull-right' - v-if='showHelpState' - @click='toggleHelpState(false)'> - <i class='fa fa-close' aria-hidden='true'></i> - </div> - </div> - <div class='time-tracking-content hide-collapsed'> - <time-tracking-estimate-only-pane - v-if='showEstimateOnlyState' - :time-estimate-human-readable='timeEstimateHumanReadable'> - </time-tracking-estimate-only-pane> - <time-tracking-spent-only-pane - v-if='showSpentOnlyState' - :time-spent-human-readable='timeSpentHumanReadable'> - </time-tracking-spent-only-pane> - <time-tracking-no-tracking-pane - v-if='showNoTimeTrackingState'> - </time-tracking-no-tracking-pane> - <time-tracking-comparison-pane - v-if='showComparisonState' - :time-estimate='timeEstimate' - :time-spent='timeSpent' - :time-spent-human-readable='timeSpentHumanReadable' - :time-estimate-human-readable='timeEstimateHumanReadable'> - </time-tracking-comparison-pane> - <transition name='help-state-toggle'> - <time-tracking-help-state - v-if='showHelpState' - :docs-url='docsUrl'> - </time-tracking-help-state> - </transition> - </div> - </div> - `, - }); -})(); diff --git a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js new file mode 100644 index 00000000000..0134b7cb6f3 --- /dev/null +++ b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js @@ -0,0 +1,65 @@ +/* global Vue */ + +window.Vue = require('vue'); +window.Vue.use(require('vue-resource')); +require('./components/time_tracker'); +require('../../smart_interval'); +require('../../subbable_resource'); + +(() => { + /* This Vue instance represents what will become the parent instance for the + * sidebar. It will be responsible for managing `issuable` state and propagating + * changes to sidebar components. We will want to create a separate service to + * interface with the server at that point. + */ + + class IssuableTimeTracking { + constructor(issuableJSON) { + const parsedIssuable = JSON.parse(issuableJSON); + return this.initComponent(parsedIssuable); + } + + initComponent(parsedIssuable) { + this.parentInstance = new Vue({ + el: '#issuable-time-tracker', + data: { + issuable: parsedIssuable, + }, + methods: { + fetchIssuable() { + return gl.IssuableResource.get.call(gl.IssuableResource, { + type: 'GET', + url: gl.IssuableResource.endpoint, + }); + }, + updateState(data) { + this.issuable = data; + }, + subscribeToUpdates() { + gl.IssuableResource.subscribe(data => this.updateState(data)); + }, + listenForSlashCommands() { + $(document).on('ajax:success', '.gfm-form', (e, data) => { + const subscribedCommands = ['spend_time', 'time_estimate']; + const changedCommands = data.commands_changes + ? Object.keys(data.commands_changes) + : []; + if (changedCommands && _.intersection(subscribedCommands, changedCommands).length) { + this.fetchIssuable(); + } + }); + }, + }, + created() { + this.fetchIssuable(); + }, + mounted() { + this.subscribeToUpdates(); + this.listenForSlashCommands(); + }, + }); + } + } + + gl.IssuableTimeTracking = IssuableTimeTracking; +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es6 b/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es6 deleted file mode 100644 index 958a0cc6d50..00000000000 --- a/app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es6 +++ /dev/null @@ -1,63 +0,0 @@ -/* global Vue */ - -require('./components/time_tracker'); -require('../../smart_interval'); -require('../../subbable_resource'); - -(() => { - /* This Vue instance represents what will become the parent instance for the - * sidebar. It will be responsible for managing `issuable` state and propagating - * changes to sidebar components. We will want to create a separate service to - * interface with the server at that point. - */ - - class IssuableTimeTracking { - constructor(issuableJSON) { - const parsedIssuable = JSON.parse(issuableJSON); - return this.initComponent(parsedIssuable); - } - - initComponent(parsedIssuable) { - this.parentInstance = new Vue({ - el: '#issuable-time-tracker', - data: { - issuable: parsedIssuable, - }, - methods: { - fetchIssuable() { - return gl.IssuableResource.get.call(gl.IssuableResource, { - type: 'GET', - url: gl.IssuableResource.endpoint, - }); - }, - updateState(data) { - this.issuable = data; - }, - subscribeToUpdates() { - gl.IssuableResource.subscribe(data => this.updateState(data)); - }, - listenForSlashCommands() { - $(document).on('ajax:success', '.gfm-form', (e, data) => { - const subscribedCommands = ['spend_time', 'time_estimate']; - const changedCommands = data.commands_changes - ? Object.keys(data.commands_changes) - : []; - if (changedCommands && _.intersection(subscribedCommands, changedCommands).length) { - this.fetchIssuable(); - } - }); - }, - }, - created() { - this.fetchIssuable(); - }, - mounted() { - this.subscribeToUpdates(); - this.listenForSlashCommands(); - }, - }); - } - } - - gl.IssuableTimeTracking = IssuableTimeTracking; -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/issues_bulk_assignment.js.es6 b/app/assets/javascripts/issues_bulk_assignment.js index e0ebd36a65c..e0ebd36a65c 100644 --- a/app/assets/javascripts/issues_bulk_assignment.js.es6 +++ b/app/assets/javascripts/issues_bulk_assignment.js diff --git a/app/assets/javascripts/label_manager.js.es6 b/app/assets/javascripts/label_manager.js index 38b2eb9ff14..38b2eb9ff14 100644 --- a/app/assets/javascripts/label_manager.js.es6 +++ b/app/assets/javascripts/label_manager.js diff --git a/app/assets/javascripts/lib/chart.js b/app/assets/javascripts/lib/chart.js deleted file mode 100644 index 9b011d89e93..00000000000 --- a/app/assets/javascripts/lib/chart.js +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren */ - -window.Chart = require('vendor/Chart'); diff --git a/app/assets/javascripts/lib/cropper.js b/app/assets/javascripts/lib/cropper.js deleted file mode 100644 index 7862c6797c3..00000000000 --- a/app/assets/javascripts/lib/cropper.js +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren */ - -/*= require cropper */ - -(function() { - -}).call(window); diff --git a/app/assets/javascripts/lib/d3.js b/app/assets/javascripts/lib/d3.js deleted file mode 100644 index a9dd32edbed..00000000000 --- a/app/assets/javascripts/lib/d3.js +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren */ - -window.d3 = require('d3'); diff --git a/app/assets/javascripts/lib/raphael.js b/app/assets/javascripts/lib/raphael.js deleted file mode 100644 index ebe1e2ae98d..00000000000 --- a/app/assets/javascripts/lib/raphael.js +++ /dev/null @@ -1,9 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren */ - -/*= require raphael */ -/*= require g.raphael */ -/*= require g.bar */ - -(function() { - -}).call(window); diff --git a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js.es6 b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js index 2955bda1a36..2955bda1a36 100644 --- a/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js.es6 +++ b/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js new file mode 100644 index 00000000000..a1423b6fda5 --- /dev/null +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -0,0 +1,342 @@ +/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-unused-expressions, no-param-reassign, no-else-return, quotes, object-shorthand, comma-dangle, camelcase, one-var, vars-on-top, one-var-declaration-per-line, no-return-assign, consistent-return, max-len, prefer-template */ +(function() { + (function(w) { + var base; + w.gl || (w.gl = {}); + (base = w.gl).utils || (base.utils = {}); + w.gl.utils.isInGroupsPage = function() { + return gl.utils.getPagePath() === 'groups'; + }; + w.gl.utils.isInProjectPage = function() { + return gl.utils.getPagePath() === 'projects'; + }; + w.gl.utils.getProjectSlug = function() { + if (this.isInProjectPage()) { + return $('body').data('project'); + } else { + return null; + } + }; + w.gl.utils.getGroupSlug = function() { + if (this.isInGroupsPage()) { + return $('body').data('group'); + } else { + return null; + } + }; + + w.gl.utils.ajaxGet = function(url) { + return $.ajax({ + type: "GET", + url: url, + dataType: "script" + }); + }; + + w.gl.utils.extractLast = function(term) { + return this.split(term).pop(); + }; + + w.gl.utils.rstrip = function rstrip(val) { + if (val) { + return val.replace(/\s+$/, ''); + } else { + return val; + } + }; + + w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) { + event_name = event_name || 'input'; + var closest_submit, field, that; + that = this; + field = $(field_selector); + closest_submit = field.closest('form').find(button_selector); + if (this.rstrip(field.val()) === "") { + closest_submit.disable(); + } + return field.on(event_name, function() { + if (that.rstrip($(this).val()) === "") { + return closest_submit.disable(); + } else { + return closest_submit.enable(); + } + }); + }; + + // automatically adjust scroll position for hash urls taking the height of the navbar into account + // https://github.com/twitter/bootstrap/issues/1768 + w.gl.utils.handleLocationHash = function() { + var hash = w.gl.utils.getLocationHash(); + if (!hash) return; + + // This is required to handle non-unicode characters in hash + hash = decodeURIComponent(hash); + + // scroll to user-generated markdown anchor if we cannot find a match + if (document.getElementById(hash) === null) { + var target = document.getElementById('user-content-' + hash); + if (target && target.scrollIntoView) { + target.scrollIntoView(true); + } + } else { + // only adjust for fixedTabs when not targeting user-generated content + var fixedTabs = document.querySelector('.js-tabs-affix'); + if (fixedTabs) { + window.scrollBy(0, -fixedTabs.offsetHeight); + } + } + }; + + // Check if element scrolled into viewport from above or below + // Courtesy http://stackoverflow.com/a/7557433/414749 + w.gl.utils.isInViewport = function(el) { + var rect = el.getBoundingClientRect(); + + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= window.innerHeight && + rect.right <= window.innerWidth + ); + }; + + gl.utils.getPagePath = function(index) { + index = index || 0; + return $('body').data('page').split(':')[index]; + }; + + gl.utils.parseUrl = function (url) { + var parser = document.createElement('a'); + parser.href = url; + return parser; + }; + + gl.utils.parseUrlPathname = function (url) { + var parsedUrl = gl.utils.parseUrl(url); + // parsedUrl.pathname will return an absolute path for Firefox and a relative path for IE11 + // We have to make sure we always have an absolute path. + return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : '/' + parsedUrl.pathname; + }; + + gl.utils.getUrlParamsArray = function () { + // We can trust that each param has one & since values containing & will be encoded + // Remove the first character of search as it is always ? + return window.location.search.slice(1).split('&'); + }; + + gl.utils.isMetaKey = function(e) { + return e.metaKey || e.ctrlKey || e.altKey || e.shiftKey; + }; + + gl.utils.isMetaClick = function(e) { + // Identify following special clicks + // 1) Cmd + Click on Mac (e.metaKey) + // 2) Ctrl + Click on PC (e.ctrlKey) + // 3) Middle-click or Mouse Wheel Click (e.which is 2) + return e.metaKey || e.ctrlKey || e.which === 2; + }; + + gl.utils.scrollToElement = function($el) { + var top = $el.offset().top; + gl.mrTabsHeight = gl.mrTabsHeight || $('.merge-request-tabs').height(); + + return $('body, html').animate({ + scrollTop: top - (gl.mrTabsHeight) + }, 200); + }; + + /** + this will take in the `name` of the param you want to parse in the url + if the name does not exist this function will return `null` + otherwise it will return the value of the param key provided + */ + w.gl.utils.getParameterByName = (name) => { + const url = window.location.href; + name = name.replace(/[[\]]/g, '\\$&'); + const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`); + const results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return decodeURIComponent(results[2].replace(/\+/g, ' ')); + }; + + w.gl.utils.getSelectedFragment = () => { + const selection = window.getSelection(); + if (selection.rangeCount === 0) return null; + const documentFragment = selection.getRangeAt(0).cloneContents(); + if (documentFragment.textContent.length === 0) return null; + + return documentFragment; + }; + + w.gl.utils.insertText = (target, text) => { + // Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas + + const selectionStart = target.selectionStart; + const selectionEnd = target.selectionEnd; + const value = target.value; + + const textBefore = value.substring(0, selectionStart); + const textAfter = value.substring(selectionEnd, value.length); + const newText = textBefore + text + textAfter; + + target.value = newText; + target.selectionStart = target.selectionEnd = selectionStart + text.length; + + // Trigger autosave + $(target).trigger('input'); + + // Trigger autosize + var event = document.createEvent('Event'); + event.initEvent('autosize:update', true, false); + target.dispatchEvent(event); + }; + + w.gl.utils.nodeMatchesSelector = (node, selector) => { + const matches = Element.prototype.matches || + Element.prototype.matchesSelector || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector; + + if (matches) { + return matches.call(node, selector); + } + + // IE11 doesn't support `node.matches(selector)` + + let parentNode = node.parentNode; + if (!parentNode) { + parentNode = document.createElement('div'); + node = node.cloneNode(true); + parentNode.appendChild(node); + } + + const matchingNodes = parentNode.querySelectorAll(selector); + return Array.prototype.indexOf.call(matchingNodes, node) !== -1; + }; + + /** + this will take in the headers from an API response and normalize them + this way we don't run into production issues when nginx gives us lowercased header keys + */ + w.gl.utils.normalizeHeaders = (headers) => { + const upperCaseHeaders = {}; + + Object.keys(headers).forEach((e) => { + upperCaseHeaders[e.toUpperCase()] = headers[e]; + }); + + return upperCaseHeaders; + }; + + /** + * Parses pagination object string values into numbers. + * + * @param {Object} paginationInformation + * @returns {Object} + */ + w.gl.utils.parseIntPagination = paginationInformation => ({ + perPage: parseInt(paginationInformation['X-PER-PAGE'], 10), + page: parseInt(paginationInformation['X-PAGE'], 10), + total: parseInt(paginationInformation['X-TOTAL'], 10), + totalPages: parseInt(paginationInformation['X-TOTAL-PAGES'], 10), + nextPage: parseInt(paginationInformation['X-NEXT-PAGE'], 10), + previousPage: parseInt(paginationInformation['X-PREV-PAGE'], 10), + }); + + /** + * Updates the search parameter of a URL given the parameter and values provided. + * + * If no search params are present we'll add it. + * If param for page is already present, we'll update it + * If there are params but not for the given one, we'll add it at the end. + * Returns the new search parameters. + * + * @param {String} param + * @param {Number|String|Undefined|Null} value + * @return {String} + */ + w.gl.utils.setParamInURL = (param, value) => { + let search; + const locationSearch = window.location.search; + + if (locationSearch.length === 0) { + search = `?${param}=${value}`; + } + + if (locationSearch.indexOf(param) !== -1) { + const regex = new RegExp(param + '=\\d'); + search = locationSearch.replace(regex, `${param}=${value}`); + } + + if (locationSearch.length && locationSearch.indexOf(param) === -1) { + search = `${locationSearch}&${param}=${value}`; + } + + return search; + }; + + /** + * Converts permission provided as strings to booleans. + * + * @param {String} string + * @returns {Boolean} + */ + w.gl.utils.convertPermissionToBoolean = permission => permission === 'true'; + + /** + * Back Off exponential algorithm + * backOff :: (Function<next, stop>, Number) -> Promise<Any, Error> + * + * @param {Function<next, stop>} fn function to be called + * @param {Number} timeout + * @return {Promise<Any, Error>} + * @example + * ``` + * backOff(function (next, stop) { + * // Let's perform this function repeatedly for 60s or for the timeout provided. + * + * ourFunction() + * .then(function (result) { + * // continue if result is not what we need + * next(); + * + * // when result is what we need let's stop with the repetions and jump out of the cycle + * stop(result); + * }) + * .catch(function (error) { + * // if there is an error, we need to stop this with an error. + * stop(error); + * }) + * }, 60000) + * .then(function (result) {}) + * .catch(function (error) { + * // deal with errors passed to stop() + * }) + * ``` + */ + w.gl.utils.backOff = (fn, timeout = 60000) => { + const maxInterval = 32000; + let nextInterval = 2000; + + const startTime = Date.now(); + + return new Promise((resolve, reject) => { + const stop = arg => ((arg instanceof Error) ? reject(arg) : resolve(arg)); + + const next = () => { + if (Date.now() - startTime < timeout) { + setTimeout(fn.bind(null, next, stop), nextInterval); + nextInterval = Math.min(nextInterval + nextInterval, maxInterval); + } else { + reject(new Error('BACKOFF_TIMEOUT')); + } + }; + + fn(next, stop); + }); + }; + })(window); +}).call(window); diff --git a/app/assets/javascripts/lib/utils/common_utils.js.es6 b/app/assets/javascripts/lib/utils/common_utils.js.es6 deleted file mode 100644 index 0242350f718..00000000000 --- a/app/assets/javascripts/lib/utils/common_utils.js.es6 +++ /dev/null @@ -1,353 +0,0 @@ -/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, no-unused-expressions, no-param-reassign, no-else-return, quotes, object-shorthand, comma-dangle, camelcase, one-var, vars-on-top, one-var-declaration-per-line, no-return-assign, consistent-return, max-len, prefer-template */ -(function() { - (function(w) { - var base; - w.gl || (w.gl = {}); - (base = w.gl).utils || (base.utils = {}); - w.gl.utils.isInGroupsPage = function() { - return gl.utils.getPagePath() === 'groups'; - }; - w.gl.utils.isInProjectPage = function() { - return gl.utils.getPagePath() === 'projects'; - }; - w.gl.utils.getProjectSlug = function() { - if (this.isInProjectPage()) { - return $('body').data('project'); - } else { - return null; - } - }; - w.gl.utils.getGroupSlug = function() { - if (this.isInGroupsPage()) { - return $('body').data('group'); - } else { - return null; - } - }; - - w.gl.utils.ajaxGet = function(url) { - return $.ajax({ - type: "GET", - url: url, - dataType: "script" - }); - }; - - w.gl.utils.extractLast = function(term) { - return this.split(term).pop(); - }; - - w.gl.utils.rstrip = function rstrip(val) { - if (val) { - return val.replace(/\s+$/, ''); - } else { - return val; - } - }; - - w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) { - event_name = event_name || 'input'; - var closest_submit, field, that; - that = this; - field = $(field_selector); - closest_submit = field.closest('form').find(button_selector); - if (this.rstrip(field.val()) === "") { - closest_submit.disable(); - } - return field.on(event_name, function() { - if (that.rstrip($(this).val()) === "") { - return closest_submit.disable(); - } else { - return closest_submit.enable(); - } - }); - }; - - // automatically adjust scroll position for hash urls taking the height of the navbar into account - // https://github.com/twitter/bootstrap/issues/1768 - w.gl.utils.handleLocationHash = function() { - var hash = w.gl.utils.getLocationHash(); - if (!hash) return; - - // This is required to handle non-unicode characters in hash - hash = decodeURIComponent(hash); - - // scroll to user-generated markdown anchor if we cannot find a match - if (document.getElementById(hash) === null) { - var target = document.getElementById('user-content-' + hash); - if (target && target.scrollIntoView) { - target.scrollIntoView(true); - } - } else { - // only adjust for fixedTabs when not targeting user-generated content - var fixedTabs = document.querySelector('.js-tabs-affix'); - if (fixedTabs) { - window.scrollBy(0, -fixedTabs.offsetHeight); - } - } - }; - - // Check if element scrolled into viewport from above or below - // Courtesy http://stackoverflow.com/a/7557433/414749 - w.gl.utils.isInViewport = function(el) { - var rect = el.getBoundingClientRect(); - - return ( - rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= window.innerHeight && - rect.right <= window.innerWidth - ); - }; - - gl.utils.getPagePath = function(index) { - index = index || 0; - return $('body').data('page').split(':')[index]; - }; - - gl.utils.parseUrl = function (url) { - var parser = document.createElement('a'); - parser.href = url; - return parser; - }; - - gl.utils.parseUrlPathname = function (url) { - var parsedUrl = gl.utils.parseUrl(url); - // parsedUrl.pathname will return an absolute path for Firefox and a relative path for IE11 - // We have to make sure we always have an absolute path. - return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : '/' + parsedUrl.pathname; - }; - - gl.utils.getUrlParamsArray = function () { - // We can trust that each param has one & since values containing & will be encoded - // Remove the first character of search as it is always ? - return window.location.search.slice(1).split('&'); - }; - - gl.utils.isMetaKey = function(e) { - return e.metaKey || e.ctrlKey || e.altKey || e.shiftKey; - }; - - gl.utils.isMetaClick = function(e) { - // Identify following special clicks - // 1) Cmd + Click on Mac (e.metaKey) - // 2) Ctrl + Click on PC (e.ctrlKey) - // 3) Middle-click or Mouse Wheel Click (e.which is 2) - return e.metaKey || e.ctrlKey || e.which === 2; - }; - - gl.utils.scrollToElement = function($el) { - var top = $el.offset().top; - gl.mrTabsHeight = gl.mrTabsHeight || $('.merge-request-tabs').height(); - - return $('body, html').animate({ - scrollTop: top - (gl.mrTabsHeight) - }, 200); - }; - - /** - this will take in the `name` of the param you want to parse in the url - if the name does not exist this function will return `null` - otherwise it will return the value of the param key provided - */ - w.gl.utils.getParameterByName = (name) => { - const url = window.location.href; - name = name.replace(/[[\]]/g, '\\$&'); - const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`); - const results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; - return decodeURIComponent(results[2].replace(/\+/g, ' ')); - }; - - w.gl.utils.getSelectedFragment = () => { - const selection = window.getSelection(); - if (selection.rangeCount === 0) return null; - const documentFragment = selection.getRangeAt(0).cloneContents(); - if (documentFragment.textContent.length === 0) return null; - - return documentFragment; - }; - - w.gl.utils.insertText = (target, text) => { - // Firefox doesn't support `document.execCommand('insertText', false, text)` on textareas - - const selectionStart = target.selectionStart; - const selectionEnd = target.selectionEnd; - const value = target.value; - - const textBefore = value.substring(0, selectionStart); - const textAfter = value.substring(selectionEnd, value.length); - const newText = textBefore + text + textAfter; - - target.value = newText; - target.selectionStart = target.selectionEnd = selectionStart + text.length; - - // Trigger autosave - $(target).trigger('input'); - - // Trigger autosize - var event = document.createEvent('Event'); - event.initEvent('autosize:update', true, false); - target.dispatchEvent(event); - }; - - w.gl.utils.nodeMatchesSelector = (node, selector) => { - const matches = Element.prototype.matches || - Element.prototype.matchesSelector || - Element.prototype.mozMatchesSelector || - Element.prototype.msMatchesSelector || - Element.prototype.oMatchesSelector || - Element.prototype.webkitMatchesSelector; - - if (matches) { - return matches.call(node, selector); - } - - // IE11 doesn't support `node.matches(selector)` - - let parentNode = node.parentNode; - if (!parentNode) { - parentNode = document.createElement('div'); - node = node.cloneNode(true); - parentNode.appendChild(node); - } - - const matchingNodes = parentNode.querySelectorAll(selector); - return Array.prototype.indexOf.call(matchingNodes, node) !== -1; - }; - - /** - this will take in the headers from an API response and normalize them - this way we don't run into production issues when nginx gives us lowercased header keys - */ - w.gl.utils.normalizeHeaders = (headers) => { - const upperCaseHeaders = {}; - - Object.keys(headers).forEach((e) => { - upperCaseHeaders[e.toUpperCase()] = headers[e]; - }); - - return upperCaseHeaders; - }; - - /** - * Parses pagination object string values into numbers. - * - * @param {Object} paginationInformation - * @returns {Object} - */ - w.gl.utils.parseIntPagination = paginationInformation => ({ - perPage: parseInt(paginationInformation['X-PER-PAGE'], 10), - page: parseInt(paginationInformation['X-PAGE'], 10), - total: parseInt(paginationInformation['X-TOTAL'], 10), - totalPages: parseInt(paginationInformation['X-TOTAL-PAGES'], 10), - nextPage: parseInt(paginationInformation['X-NEXT-PAGE'], 10), - previousPage: parseInt(paginationInformation['X-PREV-PAGE'], 10), - }); - - /** - * Transforms a DOMStringMap into a plain object. - * - * @param {DOMStringMap} DOMStringMapObject - * @returns {Object} - */ - w.gl.utils.DOMStringMapToObject = DOMStringMapObject => Object.keys(DOMStringMapObject).reduce((acc, element) => { - acc[element] = DOMStringMapObject[element]; - return acc; - }, {}); - - /** - * Updates the search parameter of a URL given the parameter and values provided. - * - * If no search params are present we'll add it. - * If param for page is already present, we'll update it - * If there are params but not for the given one, we'll add it at the end. - * Returns the new search parameters. - * - * @param {String} param - * @param {Number|String|Undefined|Null} value - * @return {String} - */ - w.gl.utils.setParamInURL = (param, value) => { - let search; - const locationSearch = window.location.search; - - if (locationSearch.length === 0) { - search = `?${param}=${value}`; - } - - if (locationSearch.indexOf(param) !== -1) { - const regex = new RegExp(param + '=\\d'); - search = locationSearch.replace(regex, `${param}=${value}`); - } - - if (locationSearch.length && locationSearch.indexOf(param) === -1) { - search = `${locationSearch}&${param}=${value}`; - } - - return search; - }; - - /** - * Converts permission provided as strings to booleans. - * - * @param {String} string - * @returns {Boolean} - */ - w.gl.utils.convertPermissionToBoolean = permission => permission === 'true'; - - /** - * Back Off exponential algorithm - * backOff :: (Function<next, stop>, Number) -> Promise<Any, Error> - * - * @param {Function<next, stop>} fn function to be called - * @param {Number} timeout - * @return {Promise<Any, Error>} - * @example - * ``` - * backOff(function (next, stop) { - * // Let's perform this function repeatedly for 60s or for the timeout provided. - * - * ourFunction() - * .then(function (result) { - * // continue if result is not what we need - * next(); - * - * // when result is what we need let's stop with the repetions and jump out of the cycle - * stop(result); - * }) - * .catch(function (error) { - * // if there is an error, we need to stop this with an error. - * stop(error); - * }) - * }, 60000) - * .then(function (result) {}) - * .catch(function (error) { - * // deal with errors passed to stop() - * }) - * ``` - */ - w.gl.utils.backOff = (fn, timeout = 60000) => { - const maxInterval = 32000; - let nextInterval = 2000; - - const startTime = Date.now(); - - return new Promise((resolve, reject) => { - const stop = arg => ((arg instanceof Error) ? reject(arg) : resolve(arg)); - - const next = () => { - if (Date.now() - startTime < timeout) { - setTimeout(fn.bind(null, next, stop), nextInterval); - nextInterval = Math.min(nextInterval + nextInterval, maxInterval); - } else { - reject(new Error('BACKOFF_TIMEOUT')); - } - }; - - fn(next, stop); - }); - }; - })(window); -}).call(window); diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js.es6 b/app/assets/javascripts/lib/utils/datetime_utility.js index 82dcbdc26c8..82dcbdc26c8 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js.es6 +++ b/app/assets/javascripts/lib/utils/datetime_utility.js diff --git a/app/assets/javascripts/lib/utils/pretty_time.js.es6 b/app/assets/javascripts/lib/utils/pretty_time.js index ae397212e55..ae397212e55 100644 --- a/app/assets/javascripts/lib/utils/pretty_time.js.es6 +++ b/app/assets/javascripts/lib/utils/pretty_time.js diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js index 579d322e3fb..2e5f8a09fc1 100644 --- a/app/assets/javascripts/lib/utils/text_utility.js +++ b/app/assets/javascripts/lib/utils/text_utility.js @@ -65,9 +65,10 @@ require('vendor/latinise'); } }; gl.text.insertText = function(textArea, text, tag, blockTag, selected, wrap) { - var insertText, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine; + var insertText, inserted, selectedSplit, startChar, removedLastNewLine, removedFirstNewLine, currentLineEmpty, lastNewLine; removedLastNewLine = false; removedFirstNewLine = false; + currentLineEmpty = false; // Remove the first newline if (selected.indexOf('\n') === 0) { @@ -82,7 +83,17 @@ require('vendor/latinise'); } selectedSplit = selected.split('\n'); - startChar = !wrap && textArea.selectionStart > 0 ? '\n' : ''; + + if (!wrap) { + lastNewLine = textArea.value.substr(0, textArea.selectionStart).lastIndexOf('\n'); + + // Check whether the current line is empty or consists only of spaces(=handle as empty) + if (/^\s*$/.test(textArea.value.substring(lastNewLine, textArea.selectionStart))) { + currentLineEmpty = true; + } + } + + startChar = !wrap && !currentLineEmpty && textArea.selectionStart > 0 ? '\n' : ''; if (selectedSplit.length > 1 && (!wrap || (blockTag != null))) { if (blockTag != null) { @@ -142,9 +153,8 @@ require('vendor/latinise'); } }; gl.text.updateText = function(textArea, tag, blockTag, wrap) { - var $textArea, oldVal, selected, text; + var $textArea, selected, text; $textArea = $(textArea); - oldVal = $textArea.val(); textArea = $textArea.get(0); text = $textArea.val(); selected = this.selectedText(text, textArea); diff --git a/app/assets/javascripts/lib/utils/url_utility.js.es6 b/app/assets/javascripts/lib/utils/url_utility.js index 1bc81d2e4a4..1bc81d2e4a4 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js.es6 +++ b/app/assets/javascripts/lib/utils/url_utility.js diff --git a/app/assets/javascripts/lib/vue_resource.js.es6 b/app/assets/javascripts/lib/vue_resource.js.es6 deleted file mode 100644 index 49babdea2e1..00000000000 --- a/app/assets/javascripts/lib/vue_resource.js.es6 +++ /dev/null @@ -1,2 +0,0 @@ -window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js new file mode 100644 index 00000000000..ae4dd64424c --- /dev/null +++ b/app/assets/javascripts/main.js @@ -0,0 +1,394 @@ +/* eslint-disable func-names, space-before-function-paren, no-var, quotes, consistent-return, prefer-arrow-callback, comma-dangle, object-shorthand, no-new, max-len, no-multi-spaces, import/newline-after-import */ +/* global bp */ +/* global Cookies */ +/* global Flash */ +/* global ConfirmDangerModal */ +/* global Aside */ + +import jQuery from 'jquery'; +import _ from 'underscore'; +import Cookies from 'js-cookie'; +import Pikaday from 'pikaday'; +import Dropzone from 'dropzone'; +import Sortable from 'vendor/Sortable'; + +// libraries with import side-effects +require('mousetrap'); +require('mousetrap/plugins/pause/mousetrap-pause'); +require('vendor/fuzzaldrin-plus'); +require('es6-promise').polyfill(); + +// extensions +require('./extensions/string'); +require('./extensions/array'); +require('./extensions/custom_event'); +require('./extensions/element'); +require('./extensions/jquery'); +require('./extensions/object'); +require('es6-promise').polyfill(); + +// expose common libraries as globals (TODO: remove these) +window.jQuery = jQuery; +window.$ = jQuery; +window._ = _; +window.Cookies = Cookies; +window.Pikaday = Pikaday; +window.Dropzone = Dropzone; +window.Sortable = Sortable; + +// shortcuts +require('./shortcuts'); +require('./shortcuts_navigation'); +require('./shortcuts_dashboard_navigation'); +require('./shortcuts_issuable'); +require('./shortcuts_network'); + +// behaviors +require('./behaviors/autosize'); +require('./behaviors/details_behavior'); +require('./behaviors/quick_submit'); +require('./behaviors/requires_input'); +require('./behaviors/toggler_behavior'); +require('./behaviors/bind_in_out'); + +// blob +require('./blob/blob_ci_yaml'); +require('./blob/blob_dockerfile_selector'); +require('./blob/blob_dockerfile_selectors'); +require('./blob/blob_file_dropzone'); +require('./blob/blob_gitignore_selector'); +require('./blob/blob_gitignore_selectors'); +require('./blob/blob_license_selector'); +require('./blob/blob_license_selectors'); +require('./blob/template_selector'); + +// templates +require('./templates/issuable_template_selector'); +require('./templates/issuable_template_selectors'); + +// commit +require('./commit/file.js'); +require('./commit/image_file.js'); + +// lib/utils +require('./lib/utils/animate'); +require('./lib/utils/bootstrap_linked_tabs'); +require('./lib/utils/common_utils'); +require('./lib/utils/datetime_utility'); +require('./lib/utils/notify'); +require('./lib/utils/pretty_time'); +require('./lib/utils/text_utility'); +require('./lib/utils/type_utility'); +require('./lib/utils/url_utility'); + +// u2f +require('./u2f/authenticate'); +require('./u2f/error'); +require('./u2f/register'); +require('./u2f/util'); + +// droplab +require('./droplab/droplab'); +require('./droplab/droplab_ajax'); +require('./droplab/droplab_ajax_filter'); +require('./droplab/droplab_filter'); + +// everything else +require('./abuse_reports'); +require('./activities'); +require('./admin'); +require('./ajax_loading_spinner'); +require('./api'); +require('./aside'); +require('./autosave'); +const AwardsHandler = require('./awards_handler'); +require('./breakpoints'); +require('./broadcast_message'); +require('./build'); +require('./build_artifacts'); +require('./build_variables'); +require('./ci_lint_editor'); +require('./commit'); +require('./commits'); +require('./compare'); +require('./compare_autocomplete'); +require('./confirm_danger_modal'); +require('./copy_as_gfm'); +require('./copy_to_clipboard'); +require('./create_label'); +require('./diff'); +require('./dispatcher'); +require('./dropzone_input'); +require('./due_date_select'); +require('./files_comment_button'); +require('./flash'); +require('./gfm_auto_complete'); +require('./gl_dropdown'); +require('./gl_field_error'); +require('./gl_field_errors'); +require('./gl_form'); +require('./group_avatar'); +require('./group_label_subscription'); +require('./groups_select'); +require('./header'); +require('./importer_status'); +require('./issuable'); +require('./issuable_context'); +require('./issuable_form'); +require('./issue'); +require('./issue_status_select'); +require('./issues_bulk_assignment'); +require('./label_manager'); +require('./labels'); +require('./labels_select'); +require('./layout_nav'); +require('./line_highlighter'); +require('./logo'); +require('./member_expiration_date'); +require('./members'); +require('./merge_request'); +require('./merge_request_tabs'); +require('./merge_request_widget'); +require('./merged_buttons'); +require('./milestone'); +require('./milestone_select'); +require('./mini_pipeline_graph_dropdown'); +require('./namespace_select'); +require('./new_branch_form'); +require('./new_commit_form'); +require('./notes'); +require('./notifications_dropdown'); +require('./notifications_form'); +require('./pager'); +require('./pipelines'); +require('./preview_markdown'); +require('./project'); +require('./project_avatar'); +require('./project_find_file'); +require('./project_fork'); +require('./project_import'); +require('./project_label_subscription'); +require('./project_new'); +require('./project_select'); +require('./project_show'); +require('./project_variables'); +require('./projects_list'); +require('./render_gfm'); +require('./render_math'); +require('./right_sidebar'); +require('./search'); +require('./search_autocomplete'); +require('./shortcuts'); +require('./shortcuts_blob'); +require('./shortcuts_dashboard_navigation'); +require('./shortcuts_find_file'); +require('./shortcuts_issuable'); +require('./shortcuts_navigation'); +require('./shortcuts_network'); +require('./signin_tabs_memoizer'); +require('./single_file_diff'); +require('./smart_interval'); +require('./snippets_list'); +require('./star'); +require('./subbable_resource'); +require('./subscription'); +require('./subscription_select'); +require('./syntax_highlight'); +require('./task_list'); +require('./todos'); +require('./tree'); +require('./user'); +require('./user_tabs'); +require('./username_validator'); +require('./users_select'); +require('./version_check_image'); +require('./visibility_select'); +require('./wikis'); +require('./zen_mode'); + +(function () { + document.addEventListener('beforeunload', function () { + // Unbind scroll events + $(document).off('scroll'); + // Close any open tooltips + $('.has-tooltip, [data-toggle="tooltip"]').tooltip('destroy'); + }); + + window.addEventListener('hashchange', gl.utils.handleLocationHash); + window.addEventListener('load', function onLoad() { + window.removeEventListener('load', onLoad, false); + gl.utils.handleLocationHash(); + }, false); + + $(function () { + var $body = $('body'); + var $document = $(document); + var $window = $(window); + var $sidebarGutterToggle = $('.js-sidebar-toggle'); + var $flash = $('.flash-container'); + var bootstrapBreakpoint = bp.getBreakpointSize(); + var fitSidebarForSize; + + // Set the default path for all cookies to GitLab's root directory + Cookies.defaults.path = gon.relative_url_root || '/'; + + // `hashchange` is not triggered when link target is already in window.location + $body.on('click', 'a[href^="#"]', function() { + var href = this.getAttribute('href'); + if (href.substr(1) === gl.utils.getLocationHash()) { + setTimeout(gl.utils.handleLocationHash, 1); + } + }); + + // prevent default action for disabled buttons + $('.btn').click(function(e) { + if ($(this).hasClass('disabled')) { + e.preventDefault(); + e.stopImmediatePropagation(); + return false; + } + }); + + $('.js-select-on-focus').on('focusin', function () { + return $(this).select().one('mouseup', function (e) { + return e.preventDefault(); + }); + // Click a .js-select-on-focus field, select the contents + // Prevent a mouseup event from deselecting the input + }); + $('.remove-row').bind('ajax:success', function () { + $(this).tooltip('destroy') + .closest('li') + .fadeOut(); + }); + $('.js-remove-tr').bind('ajax:before', function () { + return $(this).hide(); + }); + $('.js-remove-tr').bind('ajax:success', function () { + return $(this).closest('tr').fadeOut(); + }); + $('select.select2').select2({ + width: 'resolve', + // Initialize select2 selects + dropdownAutoWidth: true + }); + $('.js-select2').bind('select2-close', function () { + return setTimeout((function () { + $('.select2-container-active').removeClass('select2-container-active'); + return $(':focus').blur(); + }), 1); + // Close select2 on escape + }); + // Initialize tooltips + $.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover'; + $body.tooltip({ + selector: '.has-tooltip, [data-toggle="tooltip"]', + placement: function (tip, el) { + return $(el).data('placement') || 'bottom'; + } + }); + $('.trigger-submit').on('change', function () { + return $(this).parents('form').submit(); + // Form submitter + }); + gl.utils.localTimeAgo($('abbr.timeago, .js-timeago'), true); + // Flash + if ($flash.length > 0) { + $flash.click(function () { + return $(this).fadeOut(); + }); + $flash.show(); + } + // Disable form buttons while a form is submitting + $body.on('ajax:complete, ajax:beforeSend, submit', 'form', function (e) { + var buttons; + buttons = $('[type="submit"]', this); + switch (e.type) { + case 'ajax:beforeSend': + case 'submit': + return buttons.disable(); + default: + return buttons.enable(); + } + }); + $(document).ajaxError(function (e, xhrObj) { + var ref = xhrObj.status; + if (xhrObj.status === 401) { + return new Flash('You need to be logged in.', 'alert'); + } else if (ref === 404 || ref === 500) { + return new Flash('Something went wrong on our end.', 'alert'); + } + }); + $('.account-box').hover(function () { + // Show/Hide the profile menu when hovering the account box + return $(this).toggleClass('hover'); + }); + $document.on('click', '.diff-content .js-show-suppressed-diff', function () { + var $container; + $container = $(this).parent(); + $container.next('table').show(); + return $container.remove(); + // Commit show suppressed diff + }); + $('.navbar-toggle').on('click', function () { + $('.header-content .title').toggle(); + $('.header-content .header-logo').toggle(); + $('.header-content .navbar-collapse').toggle(); + return $('.navbar-toggle').toggleClass('active'); + }); + // Show/hide comments on diff + $body.on('click', '.js-toggle-diff-comments', function (e) { + var $this = $(this); + var notesHolders = $this.closest('.diff-file').find('.notes_holder'); + $this.toggleClass('active'); + if ($this.hasClass('active')) { + notesHolders.show().find('.hide').show(); + } else { + notesHolders.hide(); + } + $this.trigger('blur'); + return e.preventDefault(); + }); + $document.off('click', '.js-confirm-danger'); + $document.on('click', '.js-confirm-danger', function (e) { + var btn = $(e.target); + var form = btn.closest('form'); + var text = btn.data('confirm-danger-message'); + e.preventDefault(); + return new ConfirmDangerModal(form, text); + }); + $('input[type="search"]').each(function () { + var $this = $(this); + $this.attr('value', $this.val()); + }); + $document.off('keyup', 'input[type="search"]').on('keyup', 'input[type="search"]', function () { + var $this; + $this = $(this); + return $this.attr('value', $this.val()); + }); + $document.off('breakpoint:change').on('breakpoint:change', function (e, breakpoint) { + var $gutterIcon; + if (breakpoint === 'sm' || breakpoint === 'xs') { + $gutterIcon = $sidebarGutterToggle.find('i'); + if ($gutterIcon.hasClass('fa-angle-double-right')) { + return $sidebarGutterToggle.trigger('click'); + } + } + }); + fitSidebarForSize = function () { + var oldBootstrapBreakpoint; + oldBootstrapBreakpoint = bootstrapBreakpoint; + bootstrapBreakpoint = bp.getBreakpointSize(); + if (bootstrapBreakpoint !== oldBootstrapBreakpoint) { + return $document.trigger('breakpoint:change', [bootstrapBreakpoint]); + } + }; + $window.off('resize.app').on('resize.app', function () { + return fitSidebarForSize(); + }); + gl.awardsHandler = new AwardsHandler(); + new Aside(); + + gl.utils.initTimeagoTimeout(); + }); +}).call(window); diff --git a/app/assets/javascripts/member_expiration_date.js.es6 b/app/assets/javascripts/member_expiration_date.js index 129d2dc5f0a..129d2dc5f0a 100644 --- a/app/assets/javascripts/member_expiration_date.js.es6 +++ b/app/assets/javascripts/member_expiration_date.js diff --git a/app/assets/javascripts/members.js.es6 b/app/assets/javascripts/members.js index e3f367a11eb..e3f367a11eb 100644 --- a/app/assets/javascripts/members.js.es6 +++ b/app/assets/javascripts/members.js diff --git a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js.es6 b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js index c7e78fed8fe..c7e78fed8fe 100644 --- a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js.es6 +++ b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js diff --git a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js.es6 b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js index 240c8f98932..240c8f98932 100644 --- a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js.es6 +++ b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js diff --git a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js.es6 b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js index 97753c50b60..97753c50b60 100644 --- a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js.es6 +++ b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_service.js.es6 b/app/assets/javascripts/merge_conflicts/merge_conflict_service.js index c012b77e0bf..c012b77e0bf 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflict_service.js.es6 +++ b/app/assets/javascripts/merge_conflicts/merge_conflict_service.js diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js.es6 b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js index 74587df22c5..74587df22c5 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflict_store.js.es6 +++ b/app/assets/javascripts/merge_conflicts/merge_conflict_store.js diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js.es6 b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js index 653e52fb6bf..653e52fb6bf 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js.es6 +++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js diff --git a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js.es6 b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js index 53e000d7e9e..53e000d7e9e 100644 --- a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js.es6 +++ b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js diff --git a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js.es6 b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js index 0f475f62ee6..0f475f62ee6 100644 --- a/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js.es6 +++ b/app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js diff --git a/app/assets/javascripts/merge_request_tabs.js.es6 b/app/assets/javascripts/merge_request_tabs.js index 190336dbd20..190336dbd20 100644 --- a/app/assets/javascripts/merge_request_tabs.js.es6 +++ b/app/assets/javascripts/merge_request_tabs.js diff --git a/app/assets/javascripts/merge_request_widget.js b/app/assets/javascripts/merge_request_widget.js new file mode 100644 index 00000000000..5f1bd474a0c --- /dev/null +++ b/app/assets/javascripts/merge_request_widget.js @@ -0,0 +1,295 @@ +/* eslint-disable max-len, no-var, func-names, space-before-function-paren, vars-on-top, comma-dangle, no-return-assign, consistent-return, no-param-reassign, one-var, one-var-declaration-per-line, quotes, prefer-template, no-else-return, prefer-arrow-callback, no-unused-vars, no-underscore-dangle, no-shadow, no-mixed-operators, camelcase, default-case, wrap-iife */ +/* global notify */ +/* global notifyPermissions */ +/* global merge_request_widget */ + +require('./smart_interval'); + +((global) => { + var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i += 1) { if (i in this && this[i] === item) return i; } return -1; }; + + const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>"> + <div class="ci_widget ci-success"> + <%= ci_success_icon %> + <span> + Deployed to + <a href="<%- url %>" target="_blank" class="environment"> + <%- name %> + </a> + <span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>"> + <%- deployed_at %> + </span> + <a class="js-environment-link" href="<%- external_url %>" target="_blank"> + <i class="fa fa-external-link"></i> + View on <%- external_url_formatted %> + </a> + </span> + <span class="stop-env-container js-stop-env-link"> + <a href="<%- stop_url %>" class="close-evn-link" data-method="post" rel="nofollow" data-confirm="Are you sure you want to stop this environment?"> + <i class="fa fa-stop-circle-o"/> + Stop environment + </a> + </span> + </div> + </div>`; + + global.MergeRequestWidget = (function() { + function MergeRequestWidget(opts) { + // Initialize MergeRequestWidget behavior + // + // check_enable - Boolean, whether to check automerge status + // merge_check_url - String, URL to use to check automerge status + // ci_status_url - String, URL to use to check CI status + // + this.opts = opts; + this.$widgetBody = $('.mr-widget-body'); + $('#modal_merge_info').modal({ + show: false + }); + this.clearEventListeners(); + this.addEventListeners(); + this.getCIStatus(false); + this.retrieveSuccessIcon(); + + this.initMiniPipelineGraph(); + + this.ciStatusInterval = new global.SmartInterval({ + callback: this.getCIStatus.bind(this, true), + startingInterval: 10000, + maxInterval: 30000, + hiddenInterval: 120000, + incrementByFactorOf: 5000, + }); + this.ciEnvironmentStatusInterval = new global.SmartInterval({ + callback: this.getCIEnvironmentsStatus.bind(this), + startingInterval: 30000, + maxInterval: 120000, + hiddenInterval: 240000, + incrementByFactorOf: 15000, + immediateExecution: true, + }); + + notifyPermissions(); + } + + MergeRequestWidget.prototype.clearEventListeners = function() { + return $(document).off('DOMContentLoaded'); + }; + + MergeRequestWidget.prototype.addEventListeners = function() { + var allowedPages; + allowedPages = ['show', 'commits', 'pipelines', 'changes']; + $(document).on('DOMContentLoaded', (function(_this) { + return function() { + var page; + page = $('body').data('page').split(':').last(); + if (allowedPages.indexOf(page) === -1) { + return _this.clearEventListeners(); + } + }; + })(this)); + }; + + MergeRequestWidget.prototype.retrieveSuccessIcon = function() { + const $ciSuccessIcon = $('.js-success-icon'); + this.$ciSuccessIcon = $ciSuccessIcon.html(); + $ciSuccessIcon.remove(); + }; + + MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) { + if (deleteSourceBranch == null) { + deleteSourceBranch = false; + } + return $.ajax({ + type: 'GET', + url: $('.merge-request').data('url'), + success: (function(_this) { + return function(data) { + var callback, urlSuffix; + if (data.state === "merged") { + urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : ''; + return window.location.href = window.location.pathname + urlSuffix; + } else if (data.merge_error) { + return $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>"); + } else { + callback = function() { + return merge_request_widget.mergeInProgress(deleteSourceBranch); + }; + return setTimeout(callback, 2000); + } + }; + })(this), + dataType: 'json' + }); + }; + + MergeRequestWidget.prototype.cancelPolling = function () { + this.ciStatusInterval.cancel(); + this.ciEnvironmentStatusInterval.cancel(); + }; + + MergeRequestWidget.prototype.getMergeStatus = function() { + return $.get(this.opts.merge_check_url, (data) => { + var $html = $(data); + this.updateMergeButton(this.status, this.hasCi, $html); + $('.mr-widget-body').replaceWith($html.find('.mr-widget-body')); + $('.mr-widget-footer').replaceWith($html.find('.mr-widget-footer')); + }); + }; + + MergeRequestWidget.prototype.ciLabelForStatus = function(status) { + switch (status) { + case 'success': + return 'passed'; + case 'success_with_warnings': + return 'passed with warnings'; + default: + return status; + } + }; + + MergeRequestWidget.prototype.getCIStatus = function(showNotification) { + var _this; + _this = this; + $('.ci-widget-fetching').show(); + return $.getJSON(this.opts.ci_status_url, (function(_this) { + return function(data) { + var message, status, title; + _this.status = data.status; + _this.hasCi = data.has_ci; + _this.updateMergeButton(_this.status, _this.hasCi); + if (data.environments && data.environments.length) _this.renderEnvironments(data.environments); + if (data.status !== _this.opts.ci_status || + data.sha !== _this.opts.ci_sha || + data.pipeline !== _this.opts.ci_pipeline) { + _this.opts.ci_status = data.status; + _this.showCIStatus(data.status); + if (data.coverage) { + _this.showCICoverage(data.coverage); + } + if (data.pipeline) { + _this.opts.ci_pipeline = data.pipeline; + _this.updatePipelineUrls(data.pipeline); + } + if (data.sha) { + _this.opts.ci_sha = data.sha; + _this.updateCommitUrls(data.sha); + } + if (showNotification) { + status = _this.ciLabelForStatus(data.status); + if (status === "preparing") { + title = _this.opts.ci_title.preparing; + status = status.charAt(0).toUpperCase() + status.slice(1); + message = _this.opts.ci_message.preparing.replace('{{status}}', status); + } else { + title = _this.opts.ci_title.normal; + message = _this.opts.ci_message.normal.replace('{{status}}', status); + } + title = title.replace('{{status}}', status); + message = message.replace('{{sha}}', data.sha); + message = message.replace('{{title}}', data.title); + notify(title, message, _this.opts.gitlab_icon, function() { + this.close(); + }); + } + } + }; + })(this)); + }; + + MergeRequestWidget.prototype.getCIEnvironmentsStatus = function() { + $.getJSON(this.opts.ci_environments_status_url, (environments) => { + if (environments && environments.length) this.renderEnvironments(environments); + }); + }; + + MergeRequestWidget.prototype.renderEnvironments = function(environments) { + for (let i = 0; i < environments.length; i += 1) { + const environment = environments[i]; + if ($(`.mr-state-widget #${environment.id}`).length) return; + const $template = $(DEPLOYMENT_TEMPLATE); + if (!environment.external_url || !environment.external_url_formatted) $('.js-environment-link', $template).remove(); + + if (!environment.stop_url) { + $('.js-stop-env-link', $template).remove(); + } + + if (environment.deployed_at && environment.deployed_at_formatted) { + environment.deployed_at = gl.utils.getTimeago().format(environment.deployed_at, 'gl_en') + '.'; + } else { + $('.js-environment-timeago', $template).remove(); + environment.name += '.'; + } + environment.ci_success_icon = this.$ciSuccessIcon; + const templateString = _.unescape($template[0].outerHTML); + const template = _.template(templateString)(environment); + this.$widgetBody.before(template); + } + }; + + MergeRequestWidget.prototype.showCIStatus = function(state) { + var allowed_states; + if (state == null) { + return; + } + $('.ci_widget').hide(); + $('.ci_widget.ci-' + state).show(); + + this.initMiniPipelineGraph(); + }; + + MergeRequestWidget.prototype.showCICoverage = function(coverage) { + var text = `Coverage ${coverage}%`; + return $('.ci_widget:visible .ci-coverage').text(text); + }; + + MergeRequestWidget.prototype.updateMergeButton = function(state, hasCi, $html) { + const allowed_states = ["failed", "canceled", "running", "pending", "success", "success_with_warnings", "skipped", "not_found"]; + let stateClass = 'btn-danger'; + if (!hasCi) { + stateClass = 'btn-create'; + } else if (indexOf.call(allowed_states, state) !== -1) { + switch (state) { + case "failed": + case "canceled": + case "not_found": + stateClass = 'btn-danger'; + break; + case "running": + stateClass = 'btn-info'; + break; + case "success": + case "success_with_warnings": + stateClass = 'btn-create'; + } + } else { + $('.ci_widget.ci-error').show(); + stateClass = 'btn-danger'; + } + + this.setMergeButtonClass(stateClass, $html); + }; + + MergeRequestWidget.prototype.setMergeButtonClass = function(css_class, $html = $('.mr-state-widget')) { + return $html.find('.js-merge-button').removeClass('btn-danger btn-info btn-create').addClass(css_class); + }; + + MergeRequestWidget.prototype.updatePipelineUrls = function(id) { + const pipelineUrl = this.opts.pipeline_path; + $('.pipeline').text(`#${id}`).attr('href', [pipelineUrl, id].join('/')); + }; + + MergeRequestWidget.prototype.updateCommitUrls = function(id) { + const commitsUrl = this.opts.commits_path; + $('.js-commit-link').text(`#${id}`).attr('href', [commitsUrl, id].join('/')); + }; + + MergeRequestWidget.prototype.initMiniPipelineGraph = function() { + new gl.MiniPipelineGraph({ + container: '.js-pipeline-inline-mr-widget-graph:visible', + }).bindEvents(); + }; + + return MergeRequestWidget; + })(); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/merge_request_widget.js.es6 b/app/assets/javascripts/merge_request_widget.js.es6 deleted file mode 100644 index 00c6c050612..00000000000 --- a/app/assets/javascripts/merge_request_widget.js.es6 +++ /dev/null @@ -1,285 +0,0 @@ -/* eslint-disable max-len, no-var, func-names, space-before-function-paren, vars-on-top, comma-dangle, no-return-assign, consistent-return, no-param-reassign, one-var, one-var-declaration-per-line, quotes, prefer-template, no-else-return, prefer-arrow-callback, no-unused-vars, no-underscore-dangle, no-shadow, no-mixed-operators, camelcase, default-case, wrap-iife */ -/* global notify */ -/* global notifyPermissions */ -/* global merge_request_widget */ - -require('./smart_interval'); - -((global) => { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i += 1) { if (i in this && this[i] === item) return i; } return -1; }; - - const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>"> - <div class="ci_widget ci-success"> - <%= ci_success_icon %> - <span> - Deployed to - <a href="<%- url %>" target="_blank" class="environment"> - <%- name %> - </a> - <span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>"> - <%- deployed_at %> - </span> - <a class="js-environment-link" href="<%- external_url %>" target="_blank"> - <i class="fa fa-external-link"></i> - View on <%- external_url_formatted %> - </a> - </span> - <span class="stop-env-container js-stop-env-link"> - <a href="<%- stop_url %>" class="close-evn-link" data-method="post" rel="nofollow" data-confirm="Are you sure you want to stop this environment?"> - <i class="fa fa-stop-circle-o"/> - Stop environment - </a> - </span> - </div> - </div>`; - - global.MergeRequestWidget = (function() { - function MergeRequestWidget(opts) { - // Initialize MergeRequestWidget behavior - // - // check_enable - Boolean, whether to check automerge status - // merge_check_url - String, URL to use to check automerge status - // ci_status_url - String, URL to use to check CI status - // - this.opts = opts; - this.$widgetBody = $('.mr-widget-body'); - $('#modal_merge_info').modal({ - show: false - }); - this.clearEventListeners(); - this.addEventListeners(); - this.getCIStatus(false); - this.retrieveSuccessIcon(); - - this.initMiniPipelineGraph(); - - this.ciStatusInterval = new global.SmartInterval({ - callback: this.getCIStatus.bind(this, true), - startingInterval: 10000, - maxInterval: 30000, - hiddenInterval: 120000, - incrementByFactorOf: 5000, - }); - this.ciEnvironmentStatusInterval = new global.SmartInterval({ - callback: this.getCIEnvironmentsStatus.bind(this), - startingInterval: 30000, - maxInterval: 120000, - hiddenInterval: 240000, - incrementByFactorOf: 15000, - immediateExecution: true, - }); - - notifyPermissions(); - } - - MergeRequestWidget.prototype.clearEventListeners = function() { - return $(document).off('DOMContentLoaded'); - }; - - MergeRequestWidget.prototype.addEventListeners = function() { - var allowedPages; - allowedPages = ['show', 'commits', 'pipelines', 'changes']; - $(document).on('DOMContentLoaded', (function(_this) { - return function() { - var page; - page = $('body').data('page').split(':').last(); - if (allowedPages.indexOf(page) === -1) { - return _this.clearEventListeners(); - } - }; - })(this)); - }; - - MergeRequestWidget.prototype.retrieveSuccessIcon = function() { - const $ciSuccessIcon = $('.js-success-icon'); - this.$ciSuccessIcon = $ciSuccessIcon.html(); - $ciSuccessIcon.remove(); - }; - - MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) { - if (deleteSourceBranch == null) { - deleteSourceBranch = false; - } - return $.ajax({ - type: 'GET', - url: $('.merge-request').data('url'), - success: (function(_this) { - return function(data) { - var callback, urlSuffix; - if (data.state === "merged") { - urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : ''; - return window.location.href = window.location.pathname + urlSuffix; - } else if (data.merge_error) { - return $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>"); - } else { - callback = function() { - return merge_request_widget.mergeInProgress(deleteSourceBranch); - }; - return setTimeout(callback, 2000); - } - }; - })(this), - dataType: 'json' - }); - }; - - MergeRequestWidget.prototype.cancelPolling = function () { - this.ciStatusInterval.cancel(); - this.ciEnvironmentStatusInterval.cancel(); - }; - - MergeRequestWidget.prototype.getMergeStatus = function() { - return $.get(this.opts.merge_check_url, function(data) { - var $html = $(data); - $('.mr-widget-body').replaceWith($html.find('.mr-widget-body')); - $('.mr-widget-footer').replaceWith($html.find('.mr-widget-footer')); - }); - }; - - MergeRequestWidget.prototype.ciLabelForStatus = function(status) { - switch (status) { - case 'success': - return 'passed'; - case 'success_with_warnings': - return 'passed with warnings'; - default: - return status; - } - }; - - MergeRequestWidget.prototype.getCIStatus = function(showNotification) { - var _this; - _this = this; - $('.ci-widget-fetching').show(); - return $.getJSON(this.opts.ci_status_url, (function(_this) { - return function(data) { - var message, status, title; - if (!data.status) { - return; - } - if (data.environments && data.environments.length) _this.renderEnvironments(data.environments); - if (data.status !== _this.opts.ci_status || - data.sha !== _this.opts.ci_sha || - data.pipeline !== _this.opts.ci_pipeline) { - _this.opts.ci_status = data.status; - _this.showCIStatus(data.status); - if (data.coverage) { - _this.showCICoverage(data.coverage); - } - if (data.pipeline) { - _this.opts.ci_pipeline = data.pipeline; - _this.updatePipelineUrls(data.pipeline); - } - if (data.sha) { - _this.opts.ci_sha = data.sha; - _this.updateCommitUrls(data.sha); - } - if (showNotification) { - status = _this.ciLabelForStatus(data.status); - if (status === "preparing") { - title = _this.opts.ci_title.preparing; - status = status.charAt(0).toUpperCase() + status.slice(1); - message = _this.opts.ci_message.preparing.replace('{{status}}', status); - } else { - title = _this.opts.ci_title.normal; - message = _this.opts.ci_message.normal.replace('{{status}}', status); - } - title = title.replace('{{status}}', status); - message = message.replace('{{sha}}', data.sha); - message = message.replace('{{title}}', data.title); - notify(title, message, _this.opts.gitlab_icon, function() { - this.close(); - }); - } - } - }; - })(this)); - }; - - MergeRequestWidget.prototype.getCIEnvironmentsStatus = function() { - $.getJSON(this.opts.ci_environments_status_url, (environments) => { - if (environments && environments.length) this.renderEnvironments(environments); - }); - }; - - MergeRequestWidget.prototype.renderEnvironments = function(environments) { - for (let i = 0; i < environments.length; i += 1) { - const environment = environments[i]; - if ($(`.mr-state-widget #${environment.id}`).length) return; - const $template = $(DEPLOYMENT_TEMPLATE); - if (!environment.external_url || !environment.external_url_formatted) $('.js-environment-link', $template).remove(); - - if (!environment.stop_url) { - $('.js-stop-env-link', $template).remove(); - } - - if (environment.deployed_at && environment.deployed_at_formatted) { - environment.deployed_at = gl.utils.getTimeago().format(environment.deployed_at, 'gl_en') + '.'; - } else { - $('.js-environment-timeago', $template).remove(); - environment.name += '.'; - } - environment.ci_success_icon = this.$ciSuccessIcon; - const templateString = _.unescape($template[0].outerHTML); - const template = _.template(templateString)(environment); - this.$widgetBody.before(template); - } - }; - - MergeRequestWidget.prototype.showCIStatus = function(state) { - var allowed_states; - if (state == null) { - return; - } - $('.ci_widget').hide(); - allowed_states = ["failed", "canceled", "running", "pending", "success", "success_with_warnings", "skipped", "not_found"]; - if (indexOf.call(allowed_states, state) !== -1) { - $('.ci_widget.ci-' + state).show(); - switch (state) { - case "failed": - case "canceled": - case "not_found": - this.setMergeButtonClass('btn-danger'); - break; - case "running": - this.setMergeButtonClass('btn-info'); - break; - case "success": - case "success_with_warnings": - this.setMergeButtonClass('btn-create'); - } - } else { - $('.ci_widget.ci-error').show(); - this.setMergeButtonClass('btn-danger'); - } - }; - - MergeRequestWidget.prototype.showCICoverage = function(coverage) { - var text; - text = 'Coverage ' + coverage + '%'; - return $('.ci_widget:visible .ci-coverage').text(text); - }; - - MergeRequestWidget.prototype.setMergeButtonClass = function(css_class) { - return $('.js-merge-button,.accept-action .dropdown-toggle').removeClass('btn-danger btn-info btn-create').addClass(css_class); - }; - - MergeRequestWidget.prototype.updatePipelineUrls = function(id) { - const pipelineUrl = this.opts.pipeline_path; - $('.pipeline').text(`#${id}`).attr('href', [pipelineUrl, id].join('/')); - }; - - MergeRequestWidget.prototype.updateCommitUrls = function(id) { - const commitsUrl = this.opts.commits_path; - $('.js-commit-link').text(`#${id}`).attr('href', [commitsUrl, id].join('/')); - }; - - MergeRequestWidget.prototype.initMiniPipelineGraph = function() { - new gl.MiniPipelineGraph({ - container: '.js-pipeline-inline-mr-widget-graph:visible', - }).bindEvents(); - }; - - return MergeRequestWidget; - })(); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/merge_request_widget/ci_bundle.js b/app/assets/javascripts/merge_request_widget/ci_bundle.js new file mode 100644 index 00000000000..21d7c3e168e --- /dev/null +++ b/app/assets/javascripts/merge_request_widget/ci_bundle.js @@ -0,0 +1,53 @@ +/* global merge_request_widget */ + +(() => { + $(() => { + /* TODO: This needs a better home, or should be refactored. It was previously contained + * in a script tag in app/views/projects/merge_requests/widget/open/_accept.html.haml, + * but Vue chokes on script tags and prevents their execution. So it was moved here + * temporarily. + * */ + + $(document) + .off('ajax:send', '.accept-mr-form') + .on('ajax:send', '.accept-mr-form', () => { + $('.accept-mr-form :input').disable(); + }); + + $(document) + .off('click', '.accept-merge-request') + .on('click', '.accept-merge-request', () => { + $('.js-merge-button, .js-merge-when-pipeline-succeeds-button').html('<i class="fa fa-spinner fa-spin"></i> Merge in progress'); + }); + + $(document) + .off('click', '.merge-when-pipeline-succeeds') + .on('click', '.merge-when-pipeline-succeeds', () => { + $('#merge_when_pipeline_succeeds').val('1'); + }); + + $(document) + .off('click', '.js-merge-dropdown a') + .on('click', '.js-merge-dropdown a', (e) => { + e.preventDefault(); + $(e.target).closest('form').submit(); + }); + if ($('.rebase-in-progress').length) { + merge_request_widget.rebaseInProgress(); + } else if ($('.rebase-mr-form').length) { + $(document) + .off('ajax:send', '.rebase-mr-form') + .on('ajax:send', '.rebase-mr-form', () => { + $('.rebase-mr-form :input').disable(); + }); + + $(document) + .off('click', '.js-rebase-button') + .on('click', '.js-rebase-button', () => { + $('.js-rebase-button').html("<i class='fa fa-spinner fa-spin'></i> Rebase in progress"); + }); + } else { + setTimeout(() => merge_request_widget.getMergeStatus(), 200); + } + }); +})(); diff --git a/app/assets/javascripts/merge_request_widget/ci_bundle.js.es6 b/app/assets/javascripts/merge_request_widget/ci_bundle.js.es6 deleted file mode 100644 index 547dfa9e677..00000000000 --- a/app/assets/javascripts/merge_request_widget/ci_bundle.js.es6 +++ /dev/null @@ -1,53 +0,0 @@ -/* global merge_request_widget */ - -(() => { - $(() => { - /* TODO: This needs a better home, or should be refactored. It was previously contained - * in a script tag in app/views/projects/merge_requests/widget/open/_accept.html.haml, - * but Vue chokes on script tags and prevents their execution. So it was moved here - * temporarily. - * */ - - $(document) - .off('ajax:send', '.accept-mr-form') - .on('ajax:send', '.accept-mr-form', () => { - $('.accept-mr-form :input').disable(); - }); - - $(document) - .off('click', '.accept_merge_request') - .on('click', '.accept_merge_request', () => { - $('.js-merge-button').html('<i class="fa fa-spinner fa-spin"></i> Merge in progress'); - }); - - $(document) - .off('click', '.merge_when_pipeline_succeeds') - .on('click', '.merge_when_pipeline_succeeds', () => { - $('#merge_when_pipeline_succeeds').val('1'); - }); - - $(document) - .off('click', '.js-merge-dropdown a') - .on('click', '.js-merge-dropdown a', (e) => { - e.preventDefault(); - $(e.target).closest('form').submit(); - }); - if ($('.rebase-in-progress').length) { - merge_request_widget.rebaseInProgress(); - } else if ($('.rebase-mr-form').length) { - $(document) - .off('ajax:send', '.rebase-mr-form') - .on('ajax:send', '.rebase-mr-form', () => { - $('.rebase-mr-form :input').disable(); - }); - - $(document) - .off('click', '.js-rebase-button') - .on('click', '.js-rebase-button', () => { - $('.js-rebase-button').html("<i class='fa fa-spinner fa-spin'></i> Rebase in progress"); - }); - } else { - setTimeout(() => merge_request_widget.getMergeStatus(), 200); - } - }); -})(); diff --git a/app/assets/javascripts/mini_pipeline_graph_dropdown.js.es6 b/app/assets/javascripts/mini_pipeline_graph_dropdown.js index 2145e531331..2145e531331 100644 --- a/app/assets/javascripts/mini_pipeline_graph_dropdown.js.es6 +++ b/app/assets/javascripts/mini_pipeline_graph_dropdown.js diff --git a/app/assets/javascripts/network/branch_graph.js b/app/assets/javascripts/network/branch_graph.js index 43dc9838977..5aad3908eb6 100644 --- a/app/assets/javascripts/network/branch_graph.js +++ b/app/assets/javascripts/network/branch_graph.js @@ -1,424 +1,347 @@ -/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, quotes, comma-dangle, one-var, one-var-declaration-per-line, no-mixed-operators, new-cap, no-loop-func, no-floating-decimal, consistent-return, no-unused-vars, prefer-template, prefer-arrow-callback, camelcase, max-len */ -/* global Raphael */ +/* eslint-disable func-names, space-before-function-paren, no-var, wrap-iife, quotes, comma-dangle, one-var, one-var-declaration-per-line, no-mixed-operators, no-loop-func, no-floating-decimal, consistent-return, no-unused-vars, prefer-template, prefer-arrow-callback, camelcase, max-len */ -(function() { - var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; +import Raphael from './raphael'; - this.BranchGraph = (function() { - function BranchGraph(element1, options1) { - this.element = element1; - this.options = options1; - this.scrollTop = bind(this.scrollTop, this); - this.scrollBottom = bind(this.scrollBottom, this); - this.scrollRight = bind(this.scrollRight, this); - this.scrollLeft = bind(this.scrollLeft, this); - this.scrollUp = bind(this.scrollUp, this); - this.scrollDown = bind(this.scrollDown, this); - this.preparedCommits = {}; - this.mtime = 0; - this.mspace = 0; - this.parents = {}; - this.colors = ["#000"]; - this.offsetX = 150; - this.offsetY = 20; - this.unitTime = 30; - this.unitSpace = 10; - this.prev_start = -1; - this.load(); - } - - BranchGraph.prototype.load = function() { - return $.ajax({ - url: this.options.url, - method: "get", - dataType: "json", - success: $.proxy(function(data) { - $(".loading", this.element).hide(); - this.prepareData(data.days, data.commits); - return this.buildGraph(); - }, this) - }); - }; +export default (function() { + function BranchGraph(element1, options1) { + this.element = element1; + this.options = options1; + this.scrollTop = this.scrollTop.bind(this); + this.scrollBottom = this.scrollBottom.bind(this); + this.scrollRight = this.scrollRight.bind(this); + this.scrollLeft = this.scrollLeft.bind(this); + this.scrollUp = this.scrollUp.bind(this); + this.scrollDown = this.scrollDown.bind(this); + this.preparedCommits = {}; + this.mtime = 0; + this.mspace = 0; + this.parents = {}; + this.colors = ["#000"]; + this.offsetX = 150; + this.offsetY = 20; + this.unitTime = 30; + this.unitSpace = 10; + this.prev_start = -1; + this.load(); + } - BranchGraph.prototype.prepareData = function(days, commits) { - var c, ch, cw, j, len, ref; - this.days = days; - this.commits = commits; - this.collectParents(); - this.graphHeight = $(this.element).height(); - this.graphWidth = $(this.element).width(); - ch = Math.max(this.graphHeight, this.offsetY + this.unitTime * this.mtime + 150); - cw = Math.max(this.graphWidth, this.offsetX + this.unitSpace * this.mspace + 300); - this.r = Raphael(this.element.get(0), cw, ch); - this.top = this.r.set(); - this.barHeight = Math.max(this.graphHeight, this.unitTime * this.days.length + 320); - ref = this.commits; - for (j = 0, len = ref.length; j < len; j += 1) { - c = ref[j]; - if (c.id in this.parents) { - c.isParent = true; - } - this.preparedCommits[c.id] = c; - this.markCommit(c); - } - return this.collectColors(); - }; - - BranchGraph.prototype.collectParents = function() { - var c, j, len, p, ref, results; - ref = this.commits; - results = []; - for (j = 0, len = ref.length; j < len; j += 1) { - c = ref[j]; - this.mtime = Math.max(this.mtime, c.time); - this.mspace = Math.max(this.mspace, c.space); - results.push((function() { - var l, len1, ref1, results1; - ref1 = c.parents; - results1 = []; - for (l = 0, len1 = ref1.length; l < len1; l += 1) { - p = ref1[l]; - this.parents[p[0]] = true; - results1.push(this.mspace = Math.max(this.mspace, p[1])); - } - return results1; - }).call(this)); - } - return results; - }; + BranchGraph.prototype.load = function() { + return $.ajax({ + url: this.options.url, + method: "get", + dataType: "json", + success: $.proxy(function(data) { + $(".loading", this.element).hide(); + this.prepareData(data.days, data.commits); + return this.buildGraph(); + }, this) + }); + }; - BranchGraph.prototype.collectColors = function() { - var k, results; - k = 0; - results = []; - while (k < this.mspace) { - this.colors.push(Raphael.getColor(.8)); - // Skipping a few colors in the spectrum to get more contrast between colors - Raphael.getColor(); - Raphael.getColor(); - results.push(k += 1); + BranchGraph.prototype.prepareData = function(days, commits) { + var c, ch, cw, j, len, ref; + this.days = days; + this.commits = commits; + this.collectParents(); + this.graphHeight = $(this.element).height(); + this.graphWidth = $(this.element).width(); + ch = Math.max(this.graphHeight, this.offsetY + this.unitTime * this.mtime + 150); + cw = Math.max(this.graphWidth, this.offsetX + this.unitSpace * this.mspace + 300); + this.r = Raphael(this.element.get(0), cw, ch); + this.top = this.r.set(); + this.barHeight = Math.max(this.graphHeight, this.unitTime * this.days.length + 320); + ref = this.commits; + for (j = 0, len = ref.length; j < len; j += 1) { + c = ref[j]; + if (c.id in this.parents) { + c.isParent = true; } - return results; - }; + this.preparedCommits[c.id] = c; + this.markCommit(c); + } + return this.collectColors(); + }; - BranchGraph.prototype.buildGraph = function() { - var cuday, cumonth, day, j, len, mm, r, ref; - r = this.r; - cuday = 0; - cumonth = ""; - r.rect(0, 0, 40, this.barHeight).attr({ - fill: "#222" - }); - r.rect(40, 0, 30, this.barHeight).attr({ - fill: "#444" - }); - ref = this.days; - for (mm = j = 0, len = ref.length; j < len; mm = (j += 1)) { - day = ref[mm]; - if (cuday !== day[0] || cumonth !== day[1]) { - // Dates - r.text(55, this.offsetY + this.unitTime * mm, day[0]).attr({ - font: "12px Monaco, monospace", - fill: "#BBB" - }); - cuday = day[0]; - } - if (cumonth !== day[1]) { - // Months - r.text(20, this.offsetY + this.unitTime * mm, day[1]).attr({ - font: "12px Monaco, monospace", - fill: "#EEE" - }); - cumonth = day[1]; + BranchGraph.prototype.collectParents = function() { + var c, j, len, p, ref, results; + ref = this.commits; + results = []; + for (j = 0, len = ref.length; j < len; j += 1) { + c = ref[j]; + this.mtime = Math.max(this.mtime, c.time); + this.mspace = Math.max(this.mspace, c.space); + results.push((function() { + var l, len1, ref1, results1; + ref1 = c.parents; + results1 = []; + for (l = 0, len1 = ref1.length; l < len1; l += 1) { + p = ref1[l]; + this.parents[p[0]] = true; + results1.push(this.mspace = Math.max(this.mspace, p[1])); } - } - this.renderPartialGraph(); - return this.bindEvents(); - }; + return results1; + }).call(this)); + } + return results; + }; - BranchGraph.prototype.renderPartialGraph = function() { - var commit, end, i, isGraphEdge, start, x, y; - start = Math.floor((this.element.scrollTop() - this.offsetY) / this.unitTime) - 10; - if (start < 0) { - isGraphEdge = true; - start = 0; + BranchGraph.prototype.collectColors = function() { + var k, results; + k = 0; + results = []; + while (k < this.mspace) { + this.colors.push(Raphael.getColor(.8)); + // Skipping a few colors in the spectrum to get more contrast between colors + Raphael.getColor(); + Raphael.getColor(); + results.push(k += 1); + } + return results; + }; + + BranchGraph.prototype.buildGraph = function() { + var cuday, cumonth, day, j, len, mm, r, ref; + r = this.r; + cuday = 0; + cumonth = ""; + r.rect(0, 0, 40, this.barHeight).attr({ + fill: "#222" + }); + r.rect(40, 0, 30, this.barHeight).attr({ + fill: "#444" + }); + ref = this.days; + for (mm = j = 0, len = ref.length; j < len; mm = (j += 1)) { + day = ref[mm]; + if (cuday !== day[0] || cumonth !== day[1]) { + // Dates + r.text(55, this.offsetY + this.unitTime * mm, day[0]).attr({ + font: "12px Monaco, monospace", + fill: "#BBB" + }); + cuday = day[0]; } - end = start + 40; - if (this.commits.length < end) { - isGraphEdge = true; - end = this.commits.length; + if (cumonth !== day[1]) { + // Months + r.text(20, this.offsetY + this.unitTime * mm, day[1]).attr({ + font: "12px Monaco, monospace", + fill: "#EEE" + }); + cumonth = day[1]; } - if (this.prev_start === -1 || Math.abs(this.prev_start - start) > 10 || isGraphEdge) { - i = start; - this.prev_start = start; - while (i < end) { - commit = this.commits[i]; - i += 1; - if (commit.hasDrawn !== true) { - x = this.offsetX + this.unitSpace * (this.mspace - commit.space); - y = this.offsetY + this.unitTime * commit.time; - this.drawDot(x, y, commit); - this.drawLines(x, y, commit); - this.appendLabel(x, y, commit); - this.appendAnchor(x, y, commit); - commit.hasDrawn = true; - } + } + this.renderPartialGraph(); + return this.bindEvents(); + }; + + BranchGraph.prototype.renderPartialGraph = function() { + var commit, end, i, isGraphEdge, start, x, y; + start = Math.floor((this.element.scrollTop() - this.offsetY) / this.unitTime) - 10; + if (start < 0) { + isGraphEdge = true; + start = 0; + } + end = start + 40; + if (this.commits.length < end) { + isGraphEdge = true; + end = this.commits.length; + } + if (this.prev_start === -1 || Math.abs(this.prev_start - start) > 10 || isGraphEdge) { + i = start; + this.prev_start = start; + while (i < end) { + commit = this.commits[i]; + i += 1; + if (commit.hasDrawn !== true) { + x = this.offsetX + this.unitSpace * (this.mspace - commit.space); + y = this.offsetY + this.unitTime * commit.time; + this.drawDot(x, y, commit); + this.drawLines(x, y, commit); + this.appendLabel(x, y, commit); + this.appendAnchor(x, y, commit); + commit.hasDrawn = true; } - return this.top.toFront(); } - }; - - BranchGraph.prototype.bindEvents = function() { - var element; - element = this.element; - return $(element).scroll((function(_this) { - return function(event) { - return _this.renderPartialGraph(); - }; - })(this)); - }; - - BranchGraph.prototype.scrollDown = function() { - this.element.scrollTop(this.element.scrollTop() + 50); - return this.renderPartialGraph(); - }; - - BranchGraph.prototype.scrollUp = function() { - this.element.scrollTop(this.element.scrollTop() - 50); - return this.renderPartialGraph(); - }; - - BranchGraph.prototype.scrollLeft = function() { - this.element.scrollLeft(this.element.scrollLeft() - 50); - return this.renderPartialGraph(); - }; - - BranchGraph.prototype.scrollRight = function() { - this.element.scrollLeft(this.element.scrollLeft() + 50); - return this.renderPartialGraph(); - }; - - BranchGraph.prototype.scrollBottom = function() { - return this.element.scrollTop(this.element.find('svg').height()); - }; + return this.top.toFront(); + } + }; - BranchGraph.prototype.scrollTop = function() { - return this.element.scrollTop(0); - }; + BranchGraph.prototype.bindEvents = function() { + var element; + element = this.element; + return $(element).scroll((function(_this) { + return function(event) { + return _this.renderPartialGraph(); + }; + })(this)); + }; - BranchGraph.prototype.appendLabel = function(x, y, commit) { - var label, r, rect, shortrefs, text, textbox, triangle; - if (!commit.refs) { - return; - } - r = this.r; - shortrefs = commit.refs; - // Truncate if longer than 15 chars - if (shortrefs.length > 17) { - shortrefs = shortrefs.substr(0, 15) + "…"; - } - text = r.text(x + 4, y, shortrefs).attr({ - "text-anchor": "start", - font: "10px Monaco, monospace", - fill: "#FFF", - title: commit.refs - }); - textbox = text.getBBox(); - // Create rectangle based on the size of the textbox - rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr({ - fill: "#000", - "fill-opacity": .5, - stroke: "none" - }); - triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr({ - fill: "#000", - "fill-opacity": .5, - stroke: "none" - }); - label = r.set(rect, text); - label.transform(["t", -rect.getBBox().width - 15, 0]); - // Set text to front - return text.toFront(); - }; + BranchGraph.prototype.scrollDown = function() { + this.element.scrollTop(this.element.scrollTop() + 50); + return this.renderPartialGraph(); + }; - BranchGraph.prototype.appendAnchor = function(x, y, commit) { - var anchor, options, r, top; - r = this.r; - top = this.top; - options = this.options; - anchor = r.circle(x, y, 10).attr({ - fill: "#000", - opacity: 0, - cursor: "pointer" - }).click(function() { - return window.open(options.commit_url.replace("%s", commit.id), "_blank"); - }).hover(function() { - this.tooltip = r.commitTooltip(x + 5, y, commit); - return top.push(this.tooltip.insertBefore(this)); - }, function() { - return this.tooltip && this.tooltip.remove() && delete this.tooltip; - }); - return top.push(anchor); - }; + BranchGraph.prototype.scrollUp = function() { + this.element.scrollTop(this.element.scrollTop() - 50); + return this.renderPartialGraph(); + }; - BranchGraph.prototype.drawDot = function(x, y, commit) { - var avatar_box_x, avatar_box_y, r; - r = this.r; - r.circle(x, y, 3).attr({ - fill: this.colors[commit.space], - stroke: "none" - }); - avatar_box_x = this.offsetX + this.unitSpace * this.mspace + 10; - avatar_box_y = y - 10; - r.rect(avatar_box_x, avatar_box_y, 20, 20).attr({ - stroke: this.colors[commit.space], - "stroke-width": 2 - }); - r.image(commit.author.icon, avatar_box_x, avatar_box_y, 20, 20); - return r.text(this.offsetX + this.unitSpace * this.mspace + 35, y, commit.message.split("\n")[0]).attr({ - "text-anchor": "start", - font: "14px Monaco, monospace" - }); - }; + BranchGraph.prototype.scrollLeft = function() { + this.element.scrollLeft(this.element.scrollLeft() - 50); + return this.renderPartialGraph(); + }; - BranchGraph.prototype.drawLines = function(x, y, commit) { - var arrow, color, i, j, len, offset, parent, parentCommit, parentX1, parentX2, parentY, r, ref, results, route; - r = this.r; - ref = commit.parents; - results = []; - for (i = j = 0, len = ref.length; j < len; i = (j += 1)) { - parent = ref[i]; - parentCommit = this.preparedCommits[parent[0]]; - parentY = this.offsetY + this.unitTime * parentCommit.time; - parentX1 = this.offsetX + this.unitSpace * (this.mspace - parentCommit.space); - parentX2 = this.offsetX + this.unitSpace * (this.mspace - parent[1]); - // Set line color - if (parentCommit.space <= commit.space) { - color = this.colors[commit.space]; - } else { - color = this.colors[parentCommit.space]; - } - // Build line shape - if (parent[1] === commit.space) { - offset = [0, 5]; - arrow = "l-2,5,4,0,-2,-5,0,5"; - } else if (parent[1] < commit.space) { - offset = [3, 3]; - arrow = "l5,0,-2,4,-3,-4,4,2"; - } else { - offset = [-3, 3]; - arrow = "l-5,0,2,4,3,-4,-4,2"; - } - // Start point - route = ["M", x + offset[0], y + offset[1]]; - // Add arrow if not first parent - if (i > 0) { - route.push(arrow); - } - // Circumvent if overlap - if (commit.space !== parentCommit.space || commit.space !== parent[1]) { - route.push("L", parentX2, y + 10, "L", parentX2, parentY - 5); - } - // End point - route.push("L", parentX1, parentY); - results.push(r.path(route).attr({ - stroke: color, - "stroke-width": 2 - })); - } - return results; - }; + BranchGraph.prototype.scrollRight = function() { + this.element.scrollLeft(this.element.scrollLeft() + 50); + return this.renderPartialGraph(); + }; - BranchGraph.prototype.markCommit = function(commit) { - var r, x, y; - if (commit.id === this.options.commit_id) { - r = this.r; - x = this.offsetX + this.unitSpace * (this.mspace - commit.space); - y = this.offsetY + this.unitTime * commit.time; - r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr({ - fill: "#000", - "fill-opacity": .5, - stroke: "none" - }); - // Displayed in the center - return this.element.scrollTop(y - this.graphHeight / 2); - } - }; + BranchGraph.prototype.scrollBottom = function() { + return this.element.scrollTop(this.element.find('svg').height()); + }; - return BranchGraph; - })(); + BranchGraph.prototype.scrollTop = function() { + return this.element.scrollTop(0); + }; - Raphael.prototype.commitTooltip = function(x, y, commit) { - var boxHeight, boxWidth, icon, idText, messageText, nameText, rect, textSet, tooltip; - boxWidth = 300; - boxHeight = 200; - icon = this.image(gon.relative_url_root + commit.author.icon, x, y, 20, 20); - nameText = this.text(x + 25, y + 10, commit.author.name); - idText = this.text(x, y + 35, commit.id); - messageText = this.text(x, y + 50, commit.message.replace(/\r?\n/g, " \n ")); - textSet = this.set(icon, nameText, idText, messageText).attr({ + BranchGraph.prototype.appendLabel = function(x, y, commit) { + var label, r, rect, shortrefs, text, textbox, triangle; + if (!commit.refs) { + return; + } + r = this.r; + shortrefs = commit.refs; + // Truncate if longer than 15 chars + if (shortrefs.length > 17) { + shortrefs = shortrefs.substr(0, 15) + "…"; + } + text = r.text(x + 4, y, shortrefs).attr({ "text-anchor": "start", - font: "12px Monaco, monospace" - }); - nameText.attr({ - font: "14px Arial", - "font-weight": "bold" + font: "10px Monaco, monospace", + fill: "#FFF", + title: commit.refs }); - idText.attr({ - fill: "#AAA" + textbox = text.getBBox(); + // Create rectangle based on the size of the textbox + rect = r.rect(x, y - 7, textbox.width + 5, textbox.height + 5, 4).attr({ + fill: "#000", + "fill-opacity": .5, + stroke: "none" }); - messageText.node.style["white-space"] = "pre"; - this.textWrap(messageText, boxWidth - 50); - rect = this.rect(x - 10, y - 10, boxWidth, 100, 4).attr({ - fill: "#FFF", - stroke: "#000", - "stroke-linecap": "round", - "stroke-width": 2 + triangle = r.path(["M", x - 5, y, "L", x - 15, y - 4, "L", x - 15, y + 4, "Z"]).attr({ + fill: "#000", + "fill-opacity": .5, + stroke: "none" }); - tooltip = this.set(rect, textSet); - rect.attr({ - height: tooltip.getBBox().height + 10, - width: tooltip.getBBox().width + 10 + label = r.set(rect, text); + label.transform(["t", -rect.getBBox().width - 15, 0]); + // Set text to front + return text.toFront(); + }; + + BranchGraph.prototype.appendAnchor = function(x, y, commit) { + var anchor, options, r, top; + r = this.r; + top = this.top; + options = this.options; + anchor = r.circle(x, y, 10).attr({ + fill: "#000", + opacity: 0, + cursor: "pointer" + }).click(function() { + return window.open(options.commit_url.replace("%s", commit.id), "_blank"); + }).hover(function() { + this.tooltip = r.commitTooltip(x + 5, y, commit); + return top.push(this.tooltip.insertBefore(this)); + }, function() { + return this.tooltip && this.tooltip.remove() && delete this.tooltip; }); - tooltip.transform(["t", 20, 20]); - return tooltip; + return top.push(anchor); }; - Raphael.prototype.textWrap = function(t, width) { - var abc, b, content, h, j, len, letterWidth, s, word, words, x; - content = t.attr("text"); - abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - t.attr({ - text: abc + BranchGraph.prototype.drawDot = function(x, y, commit) { + var avatar_box_x, avatar_box_y, r; + r = this.r; + r.circle(x, y, 3).attr({ + fill: this.colors[commit.space], + stroke: "none" }); - letterWidth = t.getBBox().width / abc.length; - t.attr({ - text: content + avatar_box_x = this.offsetX + this.unitSpace * this.mspace + 10; + avatar_box_y = y - 10; + r.rect(avatar_box_x, avatar_box_y, 20, 20).attr({ + stroke: this.colors[commit.space], + "stroke-width": 2 }); - words = content.split(" "); - x = 0; - s = []; - for (j = 0, len = words.length; j < len; j += 1) { - word = words[j]; - if (x + (word.length * letterWidth) > width) { - s.push("\n"); - x = 0; + r.image(commit.author.icon, avatar_box_x, avatar_box_y, 20, 20); + return r.text(this.offsetX + this.unitSpace * this.mspace + 35, y, commit.message.split("\n")[0]).attr({ + "text-anchor": "start", + font: "14px Monaco, monospace" + }); + }; + + BranchGraph.prototype.drawLines = function(x, y, commit) { + var arrow, color, i, j, len, offset, parent, parentCommit, parentX1, parentX2, parentY, r, ref, results, route; + r = this.r; + ref = commit.parents; + results = []; + for (i = j = 0, len = ref.length; j < len; i = (j += 1)) { + parent = ref[i]; + parentCommit = this.preparedCommits[parent[0]]; + parentY = this.offsetY + this.unitTime * parentCommit.time; + parentX1 = this.offsetX + this.unitSpace * (this.mspace - parentCommit.space); + parentX2 = this.offsetX + this.unitSpace * (this.mspace - parent[1]); + // Set line color + if (parentCommit.space <= commit.space) { + color = this.colors[commit.space]; + } else { + color = this.colors[parentCommit.space]; } - if (word === "\n") { - s.push("\n"); - x = 0; + // Build line shape + if (parent[1] === commit.space) { + offset = [0, 5]; + arrow = "l-2,5,4,0,-2,-5,0,5"; + } else if (parent[1] < commit.space) { + offset = [3, 3]; + arrow = "l5,0,-2,4,-3,-4,4,2"; } else { - s.push(word + " "); - x += word.length * letterWidth; + offset = [-3, 3]; + arrow = "l-5,0,2,4,3,-4,-4,2"; + } + // Start point + route = ["M", x + offset[0], y + offset[1]]; + // Add arrow if not first parent + if (i > 0) { + route.push(arrow); + } + // Circumvent if overlap + if (commit.space !== parentCommit.space || commit.space !== parent[1]) { + route.push("L", parentX2, y + 10, "L", parentX2, parentY - 5); } + // End point + route.push("L", parentX1, parentY); + results.push(r.path(route).attr({ + stroke: color, + "stroke-width": 2 + })); + } + return results; + }; + + BranchGraph.prototype.markCommit = function(commit) { + var r, x, y; + if (commit.id === this.options.commit_id) { + r = this.r; + x = this.offsetX + this.unitSpace * (this.mspace - commit.space); + y = this.offsetY + this.unitTime * commit.time; + r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr({ + fill: "#000", + "fill-opacity": .5, + stroke: "none" + }); + // Displayed in the center + return this.element.scrollTop(y - this.graphHeight / 2); } - t.attr({ - text: s.join("").trim() - }); - b = t.getBBox(); - h = Math.abs(b.y2) + 1; - return t.attr({ - y: h - }); }; -}).call(window); + + return BranchGraph; +})(); diff --git a/app/assets/javascripts/network/network.js b/app/assets/javascripts/network/network.js index 8e7027b44e7..a3fd22aff2a 100644 --- a/app/assets/javascripts/network/network.js +++ b/app/assets/javascripts/network/network.js @@ -1,20 +1,19 @@ /* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, quotes, quote-props, prefer-template, comma-dangle, max-len */ -/* global BranchGraph */ -(function() { - this.Network = (function() { - function Network(opts) { - var vph; - $("#filter_ref").click(function() { - return $(this).closest('form').submit(); - }); - this.branch_graph = new BranchGraph($(".network-graph"), opts); - vph = $(window).height() - 250; - $('.network-graph').css({ - 'height': vph + 'px' - }); - } +import BranchGraph from './branch_graph'; - return Network; - })(); -}).call(window); +export default (function() { + function Network(opts) { + var vph; + $("#filter_ref").click(function() { + return $(this).closest('form').submit(); + }); + this.branch_graph = new BranchGraph($(".network-graph"), opts); + vph = $(window).height() - 250; + $('.network-graph').css({ + 'height': vph + 'px' + }); + } + + return Network; +})(); diff --git a/app/assets/javascripts/network/network_bundle.js b/app/assets/javascripts/network/network_bundle.js index e5947586583..8aae2ad201c 100644 --- a/app/assets/javascripts/network/network_bundle.js +++ b/app/assets/javascripts/network/network_bundle.js @@ -1,21 +1,17 @@ /* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, quotes, no-var, vars-on-top, camelcase, comma-dangle, consistent-return, max-len */ -/* global Network */ /* global ShortcutsNetwork */ -require('./branch_graph'); -require('./network'); +import Network from './network'; -(function() { - $(function() { - if (!$(".network-graph").length) return; +$(function() { + if (!$(".network-graph").length) return; - var network_graph; - network_graph = new Network({ - url: $(".network-graph").attr('data-url'), - commit_url: $(".network-graph").attr('data-commit-url'), - ref: $(".network-graph").attr('data-ref'), - commit_id: $(".network-graph").attr('data-commit-id') - }); - return new ShortcutsNetwork(network_graph.branch_graph); + var network_graph; + network_graph = new Network({ + url: $(".network-graph").attr('data-url'), + commit_url: $(".network-graph").attr('data-commit-url'), + ref: $(".network-graph").attr('data-ref'), + commit_id: $(".network-graph").attr('data-commit-id') }); -}).call(window); + return new ShortcutsNetwork(network_graph.branch_graph); +}); diff --git a/app/assets/javascripts/network/raphael.js b/app/assets/javascripts/network/raphael.js new file mode 100644 index 00000000000..09dcf716148 --- /dev/null +++ b/app/assets/javascripts/network/raphael.js @@ -0,0 +1,74 @@ +import Raphael from 'raphael/raphael'; + +Raphael.prototype.commitTooltip = function commitTooltip(x, y, commit) { + const boxWidth = 300; + const icon = this.image(gon.relative_url_root + commit.author.icon, x, y, 20, 20); + const nameText = this.text(x + 25, y + 10, commit.author.name); + const idText = this.text(x, y + 35, commit.id); + const messageText = this.text(x, y + 50, commit.message.replace(/\r?\n/g, ' \n ')); + const textSet = this.set(icon, nameText, idText, messageText).attr({ + 'text-anchor': 'start', + font: '12px Monaco, monospace', + }); + nameText.attr({ + font: '14px Arial', + 'font-weight': 'bold', + }); + idText.attr({ + fill: '#AAA', + }); + messageText.node.style['white-space'] = 'pre'; + this.textWrap(messageText, boxWidth - 50); + const rect = this.rect(x - 10, y - 10, boxWidth, 100, 4).attr({ + fill: '#FFF', + stroke: '#000', + 'stroke-linecap': 'round', + 'stroke-width': 2, + }); + const tooltip = this.set(rect, textSet); + rect.attr({ + height: tooltip.getBBox().height + 10, + width: tooltip.getBBox().width + 10, + }); + tooltip.transform(['t', 20, 20]); + return tooltip; +}; + +Raphael.prototype.textWrap = function testWrap(t, width) { + const content = t.attr('text'); + const abc = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + t.attr({ + text: abc, + }); + const letterWidth = t.getBBox().width / abc.length; + t.attr({ + text: content, + }); + const words = content.split(' '); + let x = 0; + const s = []; + for (let j = 0, len = words.length; j < len; j += 1) { + const word = words[j]; + if (x + (word.length * letterWidth) > width) { + s.push('\n'); + x = 0; + } + if (word === '\n') { + s.push('\n'); + x = 0; + } else { + s.push(`${word} `); + x += word.length * letterWidth; + } + } + t.attr({ + text: s.join('').trim(), + }); + const b = t.getBBox(); + const h = Math.abs(b.y2) + 1; + return t.attr({ + y: h, + }); +}; + +export default Raphael; diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 47fa0f2eb96..df7a7d2a459 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -198,7 +198,7 @@ require('./task_list'); this.refreshing = true; return $.ajax({ url: this.notes_url, - data: "last_fetched_at=" + this.last_fetched_at, + headers: { "X-Last-Fetched-At": this.last_fetched_at }, dataType: "json", success: (function(_this) { return function(data) { diff --git a/app/assets/javascripts/pager.js.es6 b/app/assets/javascripts/pager.js index e35cf6d295e..e35cf6d295e 100644 --- a/app/assets/javascripts/pager.js.es6 +++ b/app/assets/javascripts/pager.js diff --git a/app/assets/javascripts/pipelines.js.es6 b/app/assets/javascripts/pipelines.js index 9203abefbbc..9203abefbbc 100644 --- a/app/assets/javascripts/pipelines.js.es6 +++ b/app/assets/javascripts/pipelines.js diff --git a/app/assets/javascripts/profile/gl_crop.js b/app/assets/javascripts/profile/gl_crop.js new file mode 100644 index 00000000000..cf1566eeb87 --- /dev/null +++ b/app/assets/javascripts/profile/gl_crop.js @@ -0,0 +1,173 @@ +/* eslint-disable no-useless-escape, max-len, quotes, no-var, no-underscore-dangle, func-names, space-before-function-paren, no-unused-vars, no-return-assign, object-shorthand, one-var, one-var-declaration-per-line, comma-dangle, consistent-return, class-methods-use-this, new-parens */ + +import 'vendor/cropper'; + +((global) => { + // Matches everything but the file name + const FILENAMEREGEX = /^.*[\\\/]/; + + class GitLabCrop { + constructor(input, { filename, previewImage, modalCrop, pickImageEl, uploadImageBtn, modalCropImg, + exportWidth = 200, exportHeight = 200, cropBoxWidth = 200, cropBoxHeight = 200 } = {}) { + this.onUploadImageBtnClick = this.onUploadImageBtnClick.bind(this); + this.onModalHide = this.onModalHide.bind(this); + this.onModalShow = this.onModalShow.bind(this); + this.onPickImageClick = this.onPickImageClick.bind(this); + this.fileInput = $(input); + this.modalCropImg = _.isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg; + this.fileInput.attr('name', `${this.fileInput.attr('name')}-trigger`).attr('id', `${this.fileInput.attr('id')}-trigger`); + this.exportWidth = exportWidth; + this.exportHeight = exportHeight; + this.cropBoxWidth = cropBoxWidth; + this.cropBoxHeight = cropBoxHeight; + this.form = this.fileInput.parents('form'); + this.filename = filename; + this.previewImage = previewImage; + this.modalCrop = modalCrop; + this.pickImageEl = pickImageEl; + this.uploadImageBtn = uploadImageBtn; + this.modalCropImg = modalCropImg; + this.filename = this.getElement(filename); + this.previewImage = this.getElement(previewImage); + this.pickImageEl = this.getElement(pickImageEl); + this.modalCrop = _.isString(modalCrop) ? $(modalCrop) : modalCrop; + this.uploadImageBtn = _.isString(uploadImageBtn) ? $(uploadImageBtn) : uploadImageBtn; + this.modalCropImg = _.isString(modalCropImg) ? $(modalCropImg) : modalCropImg; + this.cropActionsBtn = this.modalCrop.find('[data-method]'); + this.bindEvents(); + } + + getElement(selector) { + return $(selector, this.form); + } + + bindEvents() { + var _this; + _this = this; + this.fileInput.on('change', function(e) { + return _this.onFileInputChange(e, this); + }); + this.pickImageEl.on('click', this.onPickImageClick); + this.modalCrop.on('shown.bs.modal', this.onModalShow); + this.modalCrop.on('hidden.bs.modal', this.onModalHide); + this.uploadImageBtn.on('click', this.onUploadImageBtnClick); + this.cropActionsBtn.on('click', function(e) { + var btn; + btn = this; + return _this.onActionBtnClick(btn); + }); + return this.croppedImageBlob = null; + } + + onPickImageClick() { + return this.fileInput.trigger('click'); + } + + onModalShow() { + var _this; + _this = this; + return this.modalCropImg.cropper({ + viewMode: 1, + center: false, + aspectRatio: 1, + modal: true, + scalable: false, + rotatable: false, + zoomable: true, + dragMode: 'move', + guides: false, + zoomOnTouch: false, + zoomOnWheel: false, + cropBoxMovable: false, + cropBoxResizable: false, + toggleDragModeOnDblclick: false, + built: function() { + var $image, container, cropBoxHeight, cropBoxWidth; + $image = $(this); + container = $image.cropper('getContainerData'); + cropBoxWidth = _this.cropBoxWidth; + cropBoxHeight = _this.cropBoxHeight; + return $image.cropper('setCropBoxData', { + width: cropBoxWidth, + height: cropBoxHeight, + left: (container.width - cropBoxWidth) / 2, + top: (container.height - cropBoxHeight) / 2 + }); + } + }); + } + + onModalHide() { + return this.modalCropImg.attr('src', '').cropper('destroy'); + } + + onUploadImageBtnClick(e) { + e.preventDefault(); + this.setBlob(); + this.setPreview(); + this.modalCrop.modal('hide'); + return this.fileInput.val(''); + } + + onActionBtnClick(btn) { + var data, result; + data = $(btn).data(); + if (this.modalCropImg.data('cropper') && data.method) { + return result = this.modalCropImg.cropper(data.method, data.option); + } + } + + onFileInputChange(e, input) { + return this.readFile(input); + } + + readFile(input) { + var _this, reader; + _this = this; + reader = new FileReader; + reader.onload = () => { + _this.modalCropImg.attr('src', reader.result); + return _this.modalCrop.modal('show'); + }; + return reader.readAsDataURL(input.files[0]); + } + + dataURLtoBlob(dataURL) { + var array, binary, i, k, len, v; + binary = atob(dataURL.split(',')[1]); + array = []; + for (k = i = 0, len = binary.length; i < len; k = (i += 1)) { + v = binary[k]; + array.push(binary.charCodeAt(k)); + } + return new Blob([new Uint8Array(array)], { + type: 'image/png' + }); + } + + setPreview() { + var filename; + this.previewImage.attr('src', this.dataURL); + filename = this.fileInput.val().replace(FILENAMEREGEX, ''); + return this.filename.text(filename); + } + + setBlob() { + this.dataURL = this.modalCropImg.cropper('getCroppedCanvas', { + width: 200, + height: 200 + }).toDataURL('image/png'); + return this.croppedImageBlob = this.dataURLtoBlob(this.dataURL); + } + + getBlob() { + return this.croppedImageBlob; + } + } + + $.fn.glCrop = function(opts) { + return this.each(function() { + return $(this).data('glcrop', new GitLabCrop(this, opts)); + }); + }; +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/profile/gl_crop.js.es6 b/app/assets/javascripts/profile/gl_crop.js.es6 deleted file mode 100644 index 192b1192d07..00000000000 --- a/app/assets/javascripts/profile/gl_crop.js.es6 +++ /dev/null @@ -1,171 +0,0 @@ -/* eslint-disable no-useless-escape, max-len, quotes, no-var, no-underscore-dangle, func-names, space-before-function-paren, no-unused-vars, no-return-assign, object-shorthand, one-var, one-var-declaration-per-line, comma-dangle, consistent-return, class-methods-use-this, new-parens */ - -((global) => { - // Matches everything but the file name - const FILENAMEREGEX = /^.*[\\\/]/; - - class GitLabCrop { - constructor(input, { filename, previewImage, modalCrop, pickImageEl, uploadImageBtn, modalCropImg, - exportWidth = 200, exportHeight = 200, cropBoxWidth = 200, cropBoxHeight = 200 } = {}) { - this.onUploadImageBtnClick = this.onUploadImageBtnClick.bind(this); - this.onModalHide = this.onModalHide.bind(this); - this.onModalShow = this.onModalShow.bind(this); - this.onPickImageClick = this.onPickImageClick.bind(this); - this.fileInput = $(input); - this.modalCropImg = _.isString(this.modalCropImg) ? $(this.modalCropImg) : this.modalCropImg; - this.fileInput.attr('name', `${this.fileInput.attr('name')}-trigger`).attr('id', `${this.fileInput.attr('id')}-trigger`); - this.exportWidth = exportWidth; - this.exportHeight = exportHeight; - this.cropBoxWidth = cropBoxWidth; - this.cropBoxHeight = cropBoxHeight; - this.form = this.fileInput.parents('form'); - this.filename = filename; - this.previewImage = previewImage; - this.modalCrop = modalCrop; - this.pickImageEl = pickImageEl; - this.uploadImageBtn = uploadImageBtn; - this.modalCropImg = modalCropImg; - this.filename = this.getElement(filename); - this.previewImage = this.getElement(previewImage); - this.pickImageEl = this.getElement(pickImageEl); - this.modalCrop = _.isString(modalCrop) ? $(modalCrop) : modalCrop; - this.uploadImageBtn = _.isString(uploadImageBtn) ? $(uploadImageBtn) : uploadImageBtn; - this.modalCropImg = _.isString(modalCropImg) ? $(modalCropImg) : modalCropImg; - this.cropActionsBtn = this.modalCrop.find('[data-method]'); - this.bindEvents(); - } - - getElement(selector) { - return $(selector, this.form); - } - - bindEvents() { - var _this; - _this = this; - this.fileInput.on('change', function(e) { - return _this.onFileInputChange(e, this); - }); - this.pickImageEl.on('click', this.onPickImageClick); - this.modalCrop.on('shown.bs.modal', this.onModalShow); - this.modalCrop.on('hidden.bs.modal', this.onModalHide); - this.uploadImageBtn.on('click', this.onUploadImageBtnClick); - this.cropActionsBtn.on('click', function(e) { - var btn; - btn = this; - return _this.onActionBtnClick(btn); - }); - return this.croppedImageBlob = null; - } - - onPickImageClick() { - return this.fileInput.trigger('click'); - } - - onModalShow() { - var _this; - _this = this; - return this.modalCropImg.cropper({ - viewMode: 1, - center: false, - aspectRatio: 1, - modal: true, - scalable: false, - rotatable: false, - zoomable: true, - dragMode: 'move', - guides: false, - zoomOnTouch: false, - zoomOnWheel: false, - cropBoxMovable: false, - cropBoxResizable: false, - toggleDragModeOnDblclick: false, - built: function() { - var $image, container, cropBoxHeight, cropBoxWidth; - $image = $(this); - container = $image.cropper('getContainerData'); - cropBoxWidth = _this.cropBoxWidth; - cropBoxHeight = _this.cropBoxHeight; - return $image.cropper('setCropBoxData', { - width: cropBoxWidth, - height: cropBoxHeight, - left: (container.width - cropBoxWidth) / 2, - top: (container.height - cropBoxHeight) / 2 - }); - } - }); - } - - onModalHide() { - return this.modalCropImg.attr('src', '').cropper('destroy'); - } - - onUploadImageBtnClick(e) { - e.preventDefault(); - this.setBlob(); - this.setPreview(); - this.modalCrop.modal('hide'); - return this.fileInput.val(''); - } - - onActionBtnClick(btn) { - var data, result; - data = $(btn).data(); - if (this.modalCropImg.data('cropper') && data.method) { - return result = this.modalCropImg.cropper(data.method, data.option); - } - } - - onFileInputChange(e, input) { - return this.readFile(input); - } - - readFile(input) { - var _this, reader; - _this = this; - reader = new FileReader; - reader.onload = () => { - _this.modalCropImg.attr('src', reader.result); - return _this.modalCrop.modal('show'); - }; - return reader.readAsDataURL(input.files[0]); - } - - dataURLtoBlob(dataURL) { - var array, binary, i, k, len, v; - binary = atob(dataURL.split(',')[1]); - array = []; - for (k = i = 0, len = binary.length; i < len; k = (i += 1)) { - v = binary[k]; - array.push(binary.charCodeAt(k)); - } - return new Blob([new Uint8Array(array)], { - type: 'image/png' - }); - } - - setPreview() { - var filename; - this.previewImage.attr('src', this.dataURL); - filename = this.fileInput.val().replace(FILENAMEREGEX, ''); - return this.filename.text(filename); - } - - setBlob() { - this.dataURL = this.modalCropImg.cropper('getCroppedCanvas', { - width: 200, - height: 200 - }).toDataURL('image/png'); - return this.croppedImageBlob = this.dataURLtoBlob(this.dataURL); - } - - getBlob() { - return this.croppedImageBlob; - } - } - - $.fn.glCrop = function(opts) { - return this.each(function() { - return $(this).data('glcrop', new GitLabCrop(this, opts)); - }); - }; -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/profile/profile.js.es6 b/app/assets/javascripts/profile/profile.js index 4ccea0624ee..4ccea0624ee 100644 --- a/app/assets/javascripts/profile/profile.js.es6 +++ b/app/assets/javascripts/profile/profile.js diff --git a/app/assets/javascripts/project_label_subscription.js.es6 b/app/assets/javascripts/project_label_subscription.js index 0a811627600..0a811627600 100644 --- a/app/assets/javascripts/project_label_subscription.js.es6 +++ b/app/assets/javascripts/project_label_subscription.js diff --git a/app/assets/javascripts/project_variables.js.es6 b/app/assets/javascripts/project_variables.js index 4ee2e49306d..4ee2e49306d 100644 --- a/app/assets/javascripts/project_variables.js.es6 +++ b/app/assets/javascripts/project_variables.js diff --git a/app/assets/javascripts/projects_list.js b/app/assets/javascripts/projects_list.js index acdf9b7eb5a..c67d59d2be5 100644 --- a/app/assets/javascripts/projects_list.js +++ b/app/assets/javascripts/projects_list.js @@ -1,50 +1,18 @@ -/* eslint-disable func-names, space-before-function-paren, object-shorthand, quotes, no-var, one-var, one-var-declaration-per-line, prefer-arrow-callback, consistent-return, no-unused-vars, camelcase, prefer-template, comma-dangle, max-len */ +import FilterableList from './filterable_list'; -(function() { - window.ProjectsList = { - init: function() { - $(".projects-list-filter").off('keyup'); - this.initSearch(); - return this.initPagination(); - }, - initSearch: function() { - var debounceFilter, projectsListFilter; - projectsListFilter = $('.projects-list-filter'); - debounceFilter = _.debounce(window.ProjectsList.filterResults, 500); - return projectsListFilter.on('keyup', function(e) { - if (projectsListFilter.val() !== '') { - return debounceFilter(); - } - }); - }, - filterResults: function() { - var form, project_filter_url, search; - $('.projects-list-holder').fadeTo(250, 0.5); - form = null; - form = $("form#project-filter-form"); - search = $(".projects-list-filter").val(); - project_filter_url = form.attr('action') + '?' + form.serialize(); - return $.ajax({ - type: "GET", - url: form.attr('action'), - data: form.serialize(), - complete: function() { - return $('.projects-list-holder').fadeTo(250, 1); - }, - success: function(data) { - $('.projects-list-holder').replaceWith(data.html); - return history.replaceState({ - page: project_filter_url - // Change url so if user reload a page - search results are saved - }, document.title, project_filter_url); - }, - dataType: "json" - }); - }, - initPagination: function() { - return $('.projects-list-holder .pagination').on('ajax:success', function(e, data) { - return $('.projects-list-holder').replaceWith(data.html); - }); +/** + * Makes search request for projects when user types a value in the search input. + * Updates the html content of the page with the received one. + */ +export default class ProjectsList { + constructor() { + const form = document.querySelector('form#project-filter-form'); + const filter = document.querySelector('.js-projects-list-filter'); + const holder = document.querySelector('.js-projects-list-holder'); + + if (form && filter && holder) { + const list = new FilterableList(form, filter, holder); + list.initSearch(); } - }; -}).call(window); + } +} diff --git a/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js index e7fff57ff45..e7fff57ff45 100644 --- a/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6 +++ b/app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js diff --git a/app/assets/javascripts/protected_branches/protected_branch_create.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_create.js index 57ea2f52814..57ea2f52814 100644 --- a/app/assets/javascripts/protected_branches/protected_branch_create.js.es6 +++ b/app/assets/javascripts/protected_branches/protected_branch_create.js diff --git a/app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_dropdown.js index 5cf28aa7a73..5cf28aa7a73 100644 --- a/app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6 +++ b/app/assets/javascripts/protected_branches/protected_branch_dropdown.js diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_edit.js index 6ef59e94384..6ef59e94384 100644 --- a/app/assets/javascripts/protected_branches/protected_branch_edit.js.es6 +++ b/app/assets/javascripts/protected_branches/protected_branch_edit.js diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6 b/app/assets/javascripts/protected_branches/protected_branch_edit_list.js index 336fa6c57a7..336fa6c57a7 100644 --- a/app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6 +++ b/app/assets/javascripts/protected_branches/protected_branch_edit_list.js diff --git a/app/assets/javascripts/search_autocomplete.js.es6 b/app/assets/javascripts/search_autocomplete.js index 6fd5345a0a6..6fd5345a0a6 100644 --- a/app/assets/javascripts/search_autocomplete.js.es6 +++ b/app/assets/javascripts/search_autocomplete.js diff --git a/app/assets/javascripts/shortcuts_blob.js.es6 b/app/assets/javascripts/shortcuts_blob.js index bfe90aef71e..bfe90aef71e 100644 --- a/app/assets/javascripts/shortcuts_blob.js.es6 +++ b/app/assets/javascripts/shortcuts_blob.js diff --git a/app/assets/javascripts/shortcuts_navigation.js b/app/assets/javascripts/shortcuts_navigation.js index 542cd586df0..09a58cad2b2 100644 --- a/app/assets/javascripts/shortcuts_navigation.js +++ b/app/assets/javascripts/shortcuts_navigation.js @@ -32,7 +32,7 @@ require('./shortcuts'); return ShortcutsNavigation.findAndFollowLink('.shortcuts-network'); }); Mousetrap.bind('g g', function() { - return ShortcutsNavigation.findAndFollowLink('.shortcuts-graphs'); + return ShortcutsNavigation.findAndFollowLink('.shortcuts-repository-charts'); }); Mousetrap.bind('g i', function() { return ShortcutsNavigation.findAndFollowLink('.shortcuts-issues'); diff --git a/app/assets/javascripts/signin_tabs_memoizer.js.es6 b/app/assets/javascripts/signin_tabs_memoizer.js index d811d1cd53a..d811d1cd53a 100644 --- a/app/assets/javascripts/signin_tabs_memoizer.js.es6 +++ b/app/assets/javascripts/signin_tabs_memoizer.js diff --git a/app/assets/javascripts/smart_interval.js.es6 b/app/assets/javascripts/smart_interval.js index d1bdc353be2..d1bdc353be2 100644 --- a/app/assets/javascripts/smart_interval.js.es6 +++ b/app/assets/javascripts/smart_interval.js diff --git a/app/assets/javascripts/snippets_list.js.es6 b/app/assets/javascripts/snippets_list.js index 2128007113f..2128007113f 100644 --- a/app/assets/javascripts/snippets_list.js.es6 +++ b/app/assets/javascripts/snippets_list.js diff --git a/app/assets/javascripts/subbable_resource.js.es6 b/app/assets/javascripts/subbable_resource.js index d8191605128..d8191605128 100644 --- a/app/assets/javascripts/subbable_resource.js.es6 +++ b/app/assets/javascripts/subbable_resource.js diff --git a/app/assets/javascripts/subscription.js.es6 b/app/assets/javascripts/subscription.js index 62d1604fe9e..62d1604fe9e 100644 --- a/app/assets/javascripts/subscription.js.es6 +++ b/app/assets/javascripts/subscription.js diff --git a/app/assets/javascripts/templates/issuable_template_selector.js.es6 b/app/assets/javascripts/templates/issuable_template_selector.js index e9e9aafd71a..e9e9aafd71a 100644 --- a/app/assets/javascripts/templates/issuable_template_selector.js.es6 +++ b/app/assets/javascripts/templates/issuable_template_selector.js diff --git a/app/assets/javascripts/templates/issuable_template_selectors.js.es6 b/app/assets/javascripts/templates/issuable_template_selectors.js index 97f6d37364d..97f6d37364d 100644 --- a/app/assets/javascripts/templates/issuable_template_selectors.js.es6 +++ b/app/assets/javascripts/templates/issuable_template_selectors.js diff --git a/app/assets/javascripts/terminal/terminal.js.es6 b/app/assets/javascripts/terminal/terminal.js index 6b9422b1816..6b9422b1816 100644 --- a/app/assets/javascripts/terminal/terminal.js.es6 +++ b/app/assets/javascripts/terminal/terminal.js diff --git a/app/assets/javascripts/terminal/terminal_bundle.js.es6 b/app/assets/javascripts/terminal/terminal_bundle.js index 13cf3a10a38..13cf3a10a38 100644 --- a/app/assets/javascripts/terminal/terminal_bundle.js.es6 +++ b/app/assets/javascripts/terminal/terminal_bundle.js diff --git a/app/assets/javascripts/todos.js.es6 b/app/assets/javascripts/todos.js index e9513725d9d..e9513725d9d 100644 --- a/app/assets/javascripts/todos.js.es6 +++ b/app/assets/javascripts/todos.js diff --git a/app/assets/javascripts/u2f/authenticate.js.es6 b/app/assets/javascripts/u2f/authenticate.js index 500b78fc5d8..500b78fc5d8 100644 --- a/app/assets/javascripts/u2f/authenticate.js.es6 +++ b/app/assets/javascripts/u2f/authenticate.js diff --git a/app/assets/javascripts/user.js.es6 b/app/assets/javascripts/user.js index 059e6c628b3..059e6c628b3 100644 --- a/app/assets/javascripts/user.js.es6 +++ b/app/assets/javascripts/user.js diff --git a/app/assets/javascripts/user_callout.js b/app/assets/javascripts/user_callout.js index 74b869502a4..99419e85b20 100644 --- a/app/assets/javascripts/user_callout.js +++ b/app/assets/javascripts/user_callout.js @@ -43,6 +43,8 @@ class UserCallout { this.userCalloutBody.append($template); $template.find(closeButton).on('click', e => this.dismissCallout(e)); $template.find(userCalloutBtn).on('click', e => this.dismissCallout(e)); + } else { + this.userCalloutBody.remove(); } } @@ -50,7 +52,7 @@ class UserCallout { Cookies.set(USER_CALLOUT_COOKIE, 'true'); const $currentTarget = $(e.currentTarget); if ($currentTarget.hasClass('close-user-callout')) { - this.userCalloutBody.empty(); + this.userCalloutBody.remove(); } } } diff --git a/app/assets/javascripts/user_tabs.js.es6 b/app/assets/javascripts/user_tabs.js index 465618e3d53..465618e3d53 100644 --- a/app/assets/javascripts/user_tabs.js.es6 +++ b/app/assets/javascripts/user_tabs.js diff --git a/app/assets/javascripts/username_validator.js.es6 b/app/assets/javascripts/username_validator.js index 137cefa3b8e..137cefa3b8e 100644 --- a/app/assets/javascripts/username_validator.js.es6 +++ b/app/assets/javascripts/username_validator.js diff --git a/app/assets/javascripts/users/calendar.js b/app/assets/javascripts/users/calendar.js index 5111b260e1c..754d448564f 100644 --- a/app/assets/javascripts/users/calendar.js +++ b/app/assets/javascripts/users/calendar.js @@ -1,5 +1,6 @@ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, camelcase, vars-on-top, object-shorthand, comma-dangle, eqeqeq, no-mixed-operators, no-return-assign, newline-per-chained-call, prefer-arrow-callback, consistent-return, one-var, one-var-declaration-per-line, prefer-template, quotes, no-unused-vars, no-else-return, max-len */ -/* global d3 */ + +import d3 from 'd3'; (function() { var bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; }; diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index de33a31b411..27af859f7d8 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -60,6 +60,15 @@ }); }; + $('.assign-to-me-link').on('click', (e) => { + e.preventDefault(); + $(e.currentTarget).hide(); + const $input = $(`input[name="${$dropdown.data('field-name')}"]`); + $input.val(gon.current_user_id); + selectedId = $input.val(); + $dropdown.find('.dropdown-toggle-text').text(gon.current_user_fullname).removeClass('is-default'); + }); + $block.on('click', '.js-assign-yourself', function(e) { e.preventDefault(); @@ -199,6 +208,11 @@ if ($dropdown.hasClass('js-filter-bulk-update') || $dropdown.hasClass('js-issuable-form-dropdown')) { e.preventDefault(); selectedId = user.id; + if (selectedId === gon.current_user_id) { + $('.assign-to-me-link').hide(); + } else { + $('.assign-to-me-link').show(); + } return; } if ($el.closest('.add-issues-modal').length) { @@ -234,11 +248,16 @@ id: function (user) { return user.id; }, + opened: function(e) { + const $el = $(e.currentTarget); + $el.find('.is-active').removeClass('is-active'); + $el.find(`li[data-user-id="${selectedId}"] .dropdown-menu-user-link`).addClass('is-active'); + }, renderRow: function(user) { var avatar, img, listClosingTags, listWithName, listWithUserName, selected, username; username = user.username ? "@" + user.username : ""; avatar = user.avatar_url ? user.avatar_url : false; - selected = user.id === selectedId ? "is-active" : ""; + selected = user.id === parseInt(selectedId, 10) ? "is-active" : ""; img = ""; if (user.beforeDivider != null) { "<li> <a href='#' class='" + selected + "'> " + user.name + " </a> </li>"; @@ -248,7 +267,7 @@ } } // split into three parts so we can remove the username section if nessesary - listWithName = "<li> <a href='#' class='dropdown-menu-user-link " + selected + "'> " + img + " <strong class='dropdown-menu-user-full-name'> " + user.name + " </strong>"; + listWithName = "<li data-user-id=" + user.id + "> <a href='#' class='dropdown-menu-user-link " + selected + "'> " + img + " <strong class='dropdown-menu-user-full-name'> " + user.name + " </strong>"; listWithUserName = "<span class='dropdown-menu-user-username'> " + username + " </span>"; listClosingTags = "</a> </li>"; if (username === '') { diff --git a/app/assets/javascripts/version_check_image.js.es6 b/app/assets/javascripts/version_check_image.js index d4f716acb72..d4f716acb72 100644 --- a/app/assets/javascripts/version_check_image.js.es6 +++ b/app/assets/javascripts/version_check_image.js diff --git a/app/assets/javascripts/visibility_select.js.es6 b/app/assets/javascripts/visibility_select.js index f712d7ba930..f712d7ba930 100644 --- a/app/assets/javascripts/visibility_select.js.es6 +++ b/app/assets/javascripts/visibility_select.js diff --git a/app/assets/javascripts/vue_pipelines_index/index.js b/app/assets/javascripts/vue_pipelines_index/index.js new file mode 100644 index 00000000000..a90bd1518e9 --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/index.js @@ -0,0 +1,29 @@ +/* eslint-disable no-param-reassign */ +/* global Vue, VueResource, gl */ +window.Vue = require('vue'); +window.Vue.use(require('vue-resource')); +require('../lib/utils/common_utils'); +require('../vue_shared/vue_resource_interceptor'); +require('./pipelines'); + +$(() => new Vue({ + el: document.querySelector('.vue-pipelines-index'), + + data() { + const project = document.querySelector('.pipelines'); + + return { + scope: project.dataset.url, + store: new gl.PipelineStore(), + }; + }, + components: { + 'vue-pipelines': gl.VuePipelines, + }, + template: ` + <vue-pipelines + :scope="scope" + :store="store"> + </vue-pipelines> + `, +})); diff --git a/app/assets/javascripts/vue_pipelines_index/index.js.es6 b/app/assets/javascripts/vue_pipelines_index/index.js.es6 deleted file mode 100644 index e7432afb56e..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/index.js.es6 +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* global Vue, VueResource, gl */ -window.Vue = require('vue'); -window.Vue.use(require('vue-resource')); -require('../lib/utils/common_utils'); -require('../vue_shared/vue_resource_interceptor'); -require('./pipelines'); - -$(() => new Vue({ - el: document.querySelector('.vue-pipelines-index'), - - data() { - const project = document.querySelector('.pipelines'); - const svgs = document.querySelector('.pipeline-svgs').dataset; - - // Transform svgs DOMStringMap to a plain Object. - const svgsObject = gl.utils.DOMStringMapToObject(svgs); - - return { - scope: project.dataset.url, - store: new gl.PipelineStore(), - svgs: svgsObject, - }; - }, - components: { - 'vue-pipelines': gl.VuePipelines, - }, - template: ` - <vue-pipelines - :scope='scope' - :store='store' - :svgs='svgs' - > - </vue-pipelines> - `, -})); diff --git a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js new file mode 100644 index 00000000000..891f1f17fb3 --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js @@ -0,0 +1,119 @@ +/* global Vue, Flash, gl */ +/* eslint-disable no-param-reassign, no-alert */ +const playIconSvg = require('icons/_icon_play.svg'); + +((gl) => { + gl.VuePipelineActions = Vue.extend({ + props: ['pipeline'], + computed: { + actions() { + return this.pipeline.details.manual_actions.length > 0; + }, + artifacts() { + return this.pipeline.details.artifacts.length > 0; + }, + }, + methods: { + download(name) { + return `Download ${name} artifacts`; + }, + + /** + * Shows a dialog when the user clicks in the cancel button. + * We need to prevent the default behavior and stop propagation because the + * link relies on UJS. + * + * @param {Event} event + */ + confirmAction(event) { + if (!confirm('Are you sure you want to cancel this pipeline?')) { + event.preventDefault(); + event.stopPropagation(); + } + }, + }, + + data() { + return { playIconSvg }; + }, + + template: ` + <td class="pipeline-actions"> + <div class="pull-right"> + <div class="btn-group"> + <div class="btn-group" v-if="actions"> + <button + class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions" + data-toggle="dropdown" + title="Manual job" + data-placement="top" + aria-label="Manual job"> + <span v-html="playIconSvg" aria-hidden="true"></span> + <i class="fa fa-caret-down" aria-hidden="true"></i> + </button> + <ul class="dropdown-menu dropdown-menu-align-right"> + <li v-for='action in pipeline.details.manual_actions'> + <a + rel="nofollow" + data-method="post" + :href="action.path" > + <span v-html="playIconSvg" aria-hidden="true"></span> + <span>{{action.name}}</span> + </a> + </li> + </ul> + </div> + + <div class="btn-group" v-if="artifacts"> + <button + class="dropdown-toggle btn btn-default build-artifacts has-tooltip js-pipeline-dropdown-download" + title="Artifacts" + data-placement="top" + data-toggle="dropdown" + aria-label="Artifacts"> + <i class="fa fa-download" aria-hidden="true"></i> + <i class="fa fa-caret-down" aria-hidden="true"></i> + </button> + <ul class="dropdown-menu dropdown-menu-align-right"> + <li v-for='artifact in pipeline.details.artifacts'> + <a + rel="nofollow" + :href="artifact.path"> + <i class="fa fa-download" aria-hidden="true"></i> + <span>{{download(artifact.name)}}</span> + </a> + </li> + </ul> + </div> + <div class="btn-group" v-if="pipeline.flags.retryable"> + <a + class="btn btn-default btn-retry has-tooltip" + title="Retry" + rel="nofollow" + data-method="post" + data-placement="top" + data-toggle="dropdown" + :href='pipeline.retry_path' + aria-label="Retry"> + <i class="fa fa-repeat" aria-hidden="true"></i> + </a> + </div> + <div class="btn-group" v-if="pipeline.flags.cancelable"> + <a + class="btn btn-remove has-tooltip" + title="Cancel" + rel="nofollow" + data-method="post" + data-placement="top" + data-toggle="dropdown" + :href='pipeline.cancel_path' + aria-label="Cancel"> + <i class="fa fa-remove" aria-hidden="true"></i> + </a> + </div> + </div> + </div> + </td> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 deleted file mode 100644 index b50afe7c594..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6 +++ /dev/null @@ -1,113 +0,0 @@ -/* global Vue, Flash, gl */ -/* eslint-disable no-param-reassign, no-alert */ - -((gl) => { - gl.VuePipelineActions = Vue.extend({ - props: ['pipeline', 'svgs'], - computed: { - actions() { - return this.pipeline.details.manual_actions.length > 0; - }, - artifacts() { - return this.pipeline.details.artifacts.length > 0; - }, - }, - methods: { - download(name) { - return `Download ${name} artifacts`; - }, - - /** - * Shows a dialog when the user clicks in the cancel button. - * We need to prevent the default behavior and stop propagation because the - * link relies on UJS. - * - * @param {Event} event - */ - confirmAction(event) { - if (!confirm('Are you sure you want to cancel this pipeline?')) { - event.preventDefault(); - event.stopPropagation(); - } - }, - }, - template: ` - <td class="pipeline-actions"> - <div class="pull-right"> - <div class="btn-group"> - <div class="btn-group" v-if="actions"> - <button - class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions" - data-toggle="dropdown" - title="Manual job" - data-placement="top" - aria-label="Manual job"> - <span v-html="svgs.iconPlay" aria-hidden="true"></span> - <i class="fa fa-caret-down" aria-hidden="true"></i> - </button> - <ul class="dropdown-menu dropdown-menu-align-right"> - <li v-for='action in pipeline.details.manual_actions'> - <a - rel="nofollow" - data-method="post" - :href="action.path"> - <span v-html="svgs.iconPlay" aria-hidden="true"></span> - <span>{{action.name}}</span> - </a> - </li> - </ul> - </div> - - <div class="btn-group" v-if="artifacts"> - <button - class="dropdown-toggle btn btn-default build-artifacts has-tooltip js-pipeline-dropdown-download" - title="Artifacts" - data-placement="top" - data-toggle="dropdown" - aria-label="Artifacts"> - <i class="fa fa-download" aria-hidden="true"></i> - <i class="fa fa-caret-down" aria-hidden="true"></i> - </button> - <ul class="dropdown-menu dropdown-menu-align-right"> - <li v-for='artifact in pipeline.details.artifacts'> - <a - rel="nofollow" - :href="artifact.path"> - <i class="fa fa-download" aria-hidden="true"></i> - <span>{{download(artifact.name)}}</span> - </a> - </li> - </ul> - </div> - <div class="btn-group" v-if="pipeline.flags.retryable"> - <a - class="btn btn-default btn-retry has-tooltip" - title="Retry" - rel="nofollow" - data-method="post" - data-placement="top" - data-toggle="dropdown" - :href='pipeline.retry_path' - aria-label="Retry"> - <i class="fa fa-repeat" aria-hidden="true"></i> - </a> - </div> - <div class="btn-group" v-if="pipeline.flags.cancelable"> - <a - class="btn btn-remove has-tooltip" - title="Cancel" - rel="nofollow" - data-method="post" - data-placement="top" - data-toggle="dropdown" - :href='pipeline.cancel_path' - aria-label="Cancel"> - <i class="fa fa-remove" aria-hidden="true"></i> - </a> - </div> - </div> - </div> - </td> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/pipeline_url.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipeline_url.js index ae5649f0519..ae5649f0519 100644 --- a/app/assets/javascripts/vue_pipelines_index/pipeline_url.js.es6 +++ b/app/assets/javascripts/vue_pipelines_index/pipeline_url.js diff --git a/app/assets/javascripts/vue_pipelines_index/pipelines.js b/app/assets/javascripts/vue_pipelines_index/pipelines.js new file mode 100644 index 00000000000..601ef41e917 --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/pipelines.js @@ -0,0 +1,87 @@ +/* global Vue, gl */ +/* eslint-disable no-param-reassign */ + +window.Vue = require('vue'); +require('../vue_shared/components/table_pagination'); +require('./store'); +require('../vue_shared/components/pipelines_table'); +const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_store'); + +((gl) => { + gl.VuePipelines = Vue.extend({ + + components: { + 'gl-pagination': gl.VueGlPagination, + 'pipelines-table-component': gl.pipelines.PipelinesTableComponent, + }, + + data() { + return { + pipelines: [], + timeLoopInterval: '', + intervalId: '', + apiScope: 'all', + pageInfo: {}, + pagenum: 1, + count: {}, + pageRequest: false, + }; + }, + props: ['scope', 'store'], + created() { + const pagenum = gl.utils.getParameterByName('page'); + const scope = gl.utils.getParameterByName('scope'); + if (pagenum) this.pagenum = pagenum; + if (scope) this.apiScope = scope; + + this.store.fetchDataLoop.call(this, Vue, this.pagenum, this.scope, this.apiScope); + }, + + beforeUpdate() { + if (this.pipelines.length && this.$children) { + CommitPipelinesStoreWithTimeAgo.startTimeAgoLoops.call(this, Vue); + } + }, + + methods: { + /** + * Will change the page number and update the URL. + * + * @param {Number} pageNumber desired page to go to. + */ + change(pageNumber) { + const param = gl.utils.setParamInURL('page', pageNumber); + + gl.utils.visitUrl(param); + return param; + }, + }, + template: ` + <div> + <div class="pipelines realtime-loading" v-if='pageRequest'> + <i class="fa fa-spinner fa-spin"></i> + </div> + + <div class="blank-state blank-state-no-icon" + v-if="!pageRequest && pipelines.length === 0"> + <h2 class="blank-state-title js-blank-state-title"> + No pipelines to show + </h2> + </div> + + <div class="table-holder" v-if='!pageRequest && pipelines.length'> + <pipelines-table-component :pipelines='pipelines'/> + </div> + + <gl-pagination + v-if='!pageRequest && pipelines.length && pageInfo.total > pageInfo.perPage' + :pagenum='pagenum' + :change='change' + :count='count.all' + :pageInfo='pageInfo' + > + </gl-pagination> + </div> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 b/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 deleted file mode 100644 index 9275cdf78f7..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/pipelines.js.es6 +++ /dev/null @@ -1,90 +0,0 @@ -/* global Vue, gl */ -/* eslint-disable no-param-reassign */ - -window.Vue = require('vue'); -require('../vue_shared/components/table_pagination'); -require('./store'); -require('../vue_shared/components/pipelines_table'); -const CommitPipelinesStoreWithTimeAgo = require('../commit/pipelines/pipelines_store'); - -((gl) => { - gl.VuePipelines = Vue.extend({ - - components: { - 'gl-pagination': gl.VueGlPagination, - 'pipelines-table-component': gl.pipelines.PipelinesTableComponent, - }, - - data() { - return { - pipelines: [], - timeLoopInterval: '', - intervalId: '', - apiScope: 'all', - pageInfo: {}, - pagenum: 1, - count: {}, - pageRequest: false, - }; - }, - props: ['scope', 'store', 'svgs'], - created() { - const pagenum = gl.utils.getParameterByName('page'); - const scope = gl.utils.getParameterByName('scope'); - if (pagenum) this.pagenum = pagenum; - if (scope) this.apiScope = scope; - - this.store.fetchDataLoop.call(this, Vue, this.pagenum, this.scope, this.apiScope); - }, - - beforeUpdate() { - if (this.pipelines.length && this.$children) { - CommitPipelinesStoreWithTimeAgo.startTimeAgoLoops.call(this, Vue); - } - }, - - methods: { - /** - * Will change the page number and update the URL. - * - * @param {Number} pageNumber desired page to go to. - */ - change(pageNumber) { - const param = gl.utils.setParamInURL('page', pageNumber); - - gl.utils.visitUrl(param); - return param; - }, - }, - template: ` - <div> - <div class="pipelines realtime-loading" v-if='pageRequest'> - <i class="fa fa-spinner fa-spin"></i> - </div> - - <div class="blank-state blank-state-no-icon" - v-if="!pageRequest && pipelines.length === 0"> - <h2 class="blank-state-title js-blank-state-title"> - No pipelines to show - </h2> - </div> - - <div class="table-holder" v-if='!pageRequest && pipelines.length'> - <pipelines-table-component - :pipelines='pipelines' - :svgs='svgs'> - </pipelines-table-component> - </div> - - <gl-pagination - v-if='!pageRequest && pipelines.length && pageInfo.total > pageInfo.perPage' - :pagenum='pagenum' - :change='change' - :count='count.all' - :pageInfo='pageInfo' - > - </gl-pagination> - </div> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/stage.js b/app/assets/javascripts/vue_pipelines_index/stage.js new file mode 100644 index 00000000000..f67ebd6a265 --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/stage.js @@ -0,0 +1,119 @@ +/* global Vue, Flash, gl */ +/* eslint-disable no-param-reassign */ +import canceledSvg from 'icons/_icon_status_canceled_borderless.svg'; +import createdSvg from 'icons/_icon_status_created_borderless.svg'; +import failedSvg from 'icons/_icon_status_failed_borderless.svg'; +import manualSvg from 'icons/_icon_status_manual_borderless.svg'; +import pendingSvg from 'icons/_icon_status_pending_borderless.svg'; +import runningSvg from 'icons/_icon_status_running_borderless.svg'; +import skippedSvg from 'icons/_icon_status_skipped_borderless.svg'; +import successSvg from 'icons/_icon_status_success_borderless.svg'; +import warningSvg from 'icons/_icon_status_warning_borderless.svg'; + +((gl) => { + gl.VueStage = Vue.extend({ + data() { + const svgsDictionary = { + icon_status_canceled: canceledSvg, + icon_status_created: createdSvg, + icon_status_failed: failedSvg, + icon_status_manual: manualSvg, + icon_status_pending: pendingSvg, + icon_status_running: runningSvg, + icon_status_skipped: skippedSvg, + icon_status_success: successSvg, + icon_status_warning: warningSvg, + }; + + return { + builds: '', + spinner: '<span class="fa fa-spinner fa-spin"></span>', + svg: svgsDictionary[this.stage.status.icon], + }; + }, + + props: { + stage: { + type: Object, + required: true, + }, + }, + + updated() { + if (this.builds) { + this.stopDropdownClickPropagation(); + } + }, + + methods: { + fetchBuilds(e) { + const areaExpanded = e.currentTarget.attributes['aria-expanded']; + + if (areaExpanded && (areaExpanded.textContent === 'true')) return null; + + return this.$http.get(this.stage.dropdown_path) + .then((response) => { + this.builds = JSON.parse(response.body).html; + }, () => { + const flash = new Flash('Something went wrong on our end.'); + return flash; + }); + }, + + /** + * When the user right clicks or cmd/ctrl + click in the job name + * the dropdown should not be closed and the link should open in another tab, + * so we stop propagation of the click event inside the dropdown. + * + * Since this component is rendered multiple times per page we need to guarantee we only + * target the click event of this component. + */ + stopDropdownClickPropagation() { + $(this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')).on('click', (e) => { + e.stopPropagation(); + }); + }, + }, + computed: { + buildsOrSpinner() { + return this.builds ? this.builds : this.spinner; + }, + dropdownClass() { + if (this.builds) return 'js-builds-dropdown-container'; + return 'js-builds-dropdown-loading builds-dropdown-loading'; + }, + buildStatus() { + return `Build: ${this.stage.status.label}`; + }, + tooltip() { + return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`; + }, + triggerButtonClass() { + return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`; + }, + }, + template: ` + <div> + <button + @click="fetchBuilds($event)" + :class="triggerButtonClass" + :title="stage.title" + data-placement="top" + data-toggle="dropdown" + type="button" + :aria-label="stage.title"> + <span v-html="svg" aria-hidden="true"></span> + <i class="fa fa-caret-down" aria-hidden="true"></i> + </button> + <ul class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container"> + <div class="arrow-up" aria-hidden="true"></div> + <div + :class="dropdownClass" + class="js-builds-dropdown-list scrollable-menu" + v-html="buildsOrSpinner"> + </div> + </ul> + </div> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/stage.js.es6 b/app/assets/javascripts/vue_pipelines_index/stage.js.es6 deleted file mode 100644 index 67fdd729e41..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/stage.js.es6 +++ /dev/null @@ -1,111 +0,0 @@ -/* global Vue, Flash, gl */ -/* eslint-disable no-param-reassign */ - -((gl) => { - gl.VueStage = Vue.extend({ - data() { - return { - builds: '', - spinner: '<span class="fa fa-spinner fa-spin"></span>', - }; - }, - props: { - stage: { - type: Object, - required: true, - }, - svgs: { - type: Object, - required: true, - }, - match: { - type: Function, - required: true, - }, - }, - - updated() { - if (this.builds) { - this.stopDropdownClickPropagation(); - } - }, - - methods: { - fetchBuilds(e) { - const areaExpanded = e.currentTarget.attributes['aria-expanded']; - - if (areaExpanded && (areaExpanded.textContent === 'true')) return null; - - return this.$http.get(this.stage.dropdown_path) - .then((response) => { - this.builds = JSON.parse(response.body).html; - }, () => { - const flash = new Flash('Something went wrong on our end.'); - return flash; - }); - }, - - /** - * When the user right clicks or cmd/ctrl + click in the job name - * the dropdown should not be closed and the link should open in another tab, - * so we stop propagation of the click event inside the dropdown. - * - * Since this component is rendered multiple times per page we need to guarantee we only - * target the click event of this component. - */ - stopDropdownClickPropagation() { - $(this.$el.querySelectorAll('.js-builds-dropdown-list a.mini-pipeline-graph-dropdown-item')).on('click', (e) => { - e.stopPropagation(); - }); - }, - }, - computed: { - buildsOrSpinner() { - return this.builds ? this.builds : this.spinner; - }, - dropdownClass() { - if (this.builds) return 'js-builds-dropdown-container'; - return 'js-builds-dropdown-loading builds-dropdown-loading'; - }, - buildStatus() { - return `Build: ${this.stage.status.label}`; - }, - tooltip() { - return `has-tooltip ci-status-icon ci-status-icon-${this.stage.status.group}`; - }, - svg() { - const { icon } = this.stage.status; - const stageIcon = icon.replace(/icon/i, 'stage_icon'); - return this.svgs[this.match(stageIcon)]; - }, - triggerButtonClass() { - return `mini-pipeline-graph-dropdown-toggle has-tooltip js-builds-dropdown-button ci-status-icon-${this.stage.status.group}`; - }, - }, - template: ` - <div> - <button - @click="fetchBuilds($event)" - :class="triggerButtonClass" - :title="stage.title" - data-placement="top" - data-toggle="dropdown" - type="button" - :aria-label="stage.title" - > - <span v-html="svg" aria-hidden="true"></span> - <i class="fa fa-caret-down" aria-hidden="true"></i> - </button> - <ul class="dropdown-menu mini-pipeline-graph-dropdown-menu js-builds-dropdown-container"> - <div class="arrow-up" aria-hidden="true"></div> - <div - :class="dropdownClass" - class="js-builds-dropdown-list scrollable-menu" - v-html="buildsOrSpinner" - > - </div> - </ul> - </div> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/status.js b/app/assets/javascripts/vue_pipelines_index/status.js new file mode 100644 index 00000000000..8d9f83ac113 --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/status.js @@ -0,0 +1,64 @@ +/* global Vue, gl */ +/* eslint-disable no-param-reassign */ + +import canceledSvg from 'icons/_icon_status_canceled.svg'; +import createdSvg from 'icons/_icon_status_created.svg'; +import failedSvg from 'icons/_icon_status_failed.svg'; +import manualSvg from 'icons/_icon_status_manual.svg'; +import pendingSvg from 'icons/_icon_status_pending.svg'; +import runningSvg from 'icons/_icon_status_running.svg'; +import skippedSvg from 'icons/_icon_status_skipped.svg'; +import successSvg from 'icons/_icon_status_success.svg'; +import warningSvg from 'icons/_icon_status_warning.svg'; + +((gl) => { + gl.VueStatusScope = Vue.extend({ + props: [ + 'pipeline', + ], + + data() { + const svgsDictionary = { + icon_status_canceled: canceledSvg, + icon_status_created: createdSvg, + icon_status_failed: failedSvg, + icon_status_manual: manualSvg, + icon_status_pending: pendingSvg, + icon_status_running: runningSvg, + icon_status_skipped: skippedSvg, + icon_status_success: successSvg, + icon_status_warning: warningSvg, + }; + + return { + svg: svgsDictionary[this.pipeline.details.status.icon], + }; + }, + + computed: { + cssClasses() { + const cssObject = { 'ci-status': true }; + cssObject[`ci-${this.pipeline.details.status.group}`] = true; + return cssObject; + }, + + detailsPath() { + const { status } = this.pipeline.details; + return status.has_details ? status.details_path : false; + }, + + content() { + return `${this.svg} ${this.pipeline.details.status.text}`; + }, + }, + template: ` + <td class="commit-link"> + <a + :class="cssClasses" + :href="detailsPath" + v-html="content"> + </a> + </td> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/status.js.es6 b/app/assets/javascripts/vue_pipelines_index/status.js.es6 deleted file mode 100644 index 05175082704..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/status.js.es6 +++ /dev/null @@ -1,34 +0,0 @@ -/* global Vue, gl */ -/* eslint-disable no-param-reassign */ - -((gl) => { - gl.VueStatusScope = Vue.extend({ - props: [ - 'pipeline', 'svgs', 'match', - ], - computed: { - cssClasses() { - const cssObject = { 'ci-status': true }; - cssObject[`ci-${this.pipeline.details.status.group}`] = true; - return cssObject; - }, - svg() { - return this.svgs[this.match(this.pipeline.details.status.icon)]; - }, - detailsPath() { - const { status } = this.pipeline.details; - return status.has_details ? status.details_path : false; - }, - }, - template: ` - <td class="commit-link"> - <a - :class='cssClasses' - :href='detailsPath' - v-html='svg + pipeline.details.status.text' - > - </a> - </td> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/store.js.es6 b/app/assets/javascripts/vue_pipelines_index/store.js index 909007267b9..909007267b9 100644 --- a/app/assets/javascripts/vue_pipelines_index/store.js.es6 +++ b/app/assets/javascripts/vue_pipelines_index/store.js diff --git a/app/assets/javascripts/vue_pipelines_index/time_ago.js b/app/assets/javascripts/vue_pipelines_index/time_ago.js new file mode 100644 index 00000000000..a383570857d --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/time_ago.js @@ -0,0 +1,78 @@ +/* global Vue, gl */ +/* eslint-disable no-param-reassign */ + +window.Vue = require('vue'); +require('../lib/utils/datetime_utility'); + +const iconTimerSvg = require('../../../views/shared/icons/_icon_timer.svg'); + +((gl) => { + gl.VueTimeAgo = Vue.extend({ + data() { + return { + currentTime: new Date(), + iconTimerSvg, + }; + }, + props: ['pipeline'], + computed: { + timeAgo() { + return gl.utils.getTimeago(); + }, + localTimeFinished() { + return gl.utils.formatDate(this.pipeline.details.finished_at); + }, + timeStopped() { + const changeTime = this.currentTime; + const options = { + weekday: 'long', + year: 'numeric', + month: 'short', + day: 'numeric', + }; + options.timeZoneName = 'short'; + const finished = this.pipeline.details.finished_at; + if (!finished && changeTime) return false; + return ({ words: this.timeAgo.format(finished) }); + }, + duration() { + const { duration } = this.pipeline.details; + const date = new Date(duration * 1000); + + let hh = date.getUTCHours(); + let mm = date.getUTCMinutes(); + let ss = date.getSeconds(); + + if (hh < 10) hh = `0${hh}`; + if (mm < 10) mm = `0${mm}`; + if (ss < 10) ss = `0${ss}`; + + if (duration !== null) return `${hh}:${mm}:${ss}`; + return false; + }, + }, + methods: { + changeTime() { + this.currentTime = new Date(); + }, + }, + template: ` + <td class="pipelines-time-ago"> + <p class="duration" v-if='duration'> + <span v-html="iconTimerSvg"></span> + {{duration}} + </p> + <p class="finished-at" v-if='timeStopped'> + <i class="fa fa-calendar"></i> + <time + data-toggle="tooltip" + data-placement="top" + data-container="body" + :data-original-title='localTimeFinished'> + {{timeStopped.words}} + </time> + </p> + </td> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_pipelines_index/time_ago.js.es6 b/app/assets/javascripts/vue_pipelines_index/time_ago.js.es6 deleted file mode 100644 index 6048fa691dc..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/time_ago.js.es6 +++ /dev/null @@ -1,75 +0,0 @@ -/* global Vue, gl */ -/* eslint-disable no-param-reassign */ - -window.Vue = require('vue'); -require('../lib/utils/datetime_utility'); - -((gl) => { - gl.VueTimeAgo = Vue.extend({ - data() { - return { - currentTime: new Date(), - }; - }, - props: ['pipeline', 'svgs'], - computed: { - timeAgo() { - return gl.utils.getTimeago(); - }, - localTimeFinished() { - return gl.utils.formatDate(this.pipeline.details.finished_at); - }, - timeStopped() { - const changeTime = this.currentTime; - const options = { - weekday: 'long', - year: 'numeric', - month: 'short', - day: 'numeric', - }; - options.timeZoneName = 'short'; - const finished = this.pipeline.details.finished_at; - if (!finished && changeTime) return false; - return ({ words: this.timeAgo.format(finished) }); - }, - duration() { - const { duration } = this.pipeline.details; - const date = new Date(duration * 1000); - - let hh = date.getUTCHours(); - let mm = date.getUTCMinutes(); - let ss = date.getSeconds(); - - if (hh < 10) hh = `0${hh}`; - if (mm < 10) mm = `0${mm}`; - if (ss < 10) ss = `0${ss}`; - - if (duration !== null) return `${hh}:${mm}:${ss}`; - return false; - }, - }, - methods: { - changeTime() { - this.currentTime = new Date(); - }, - }, - template: ` - <td class="pipelines-time-ago"> - <p class="duration" v-if='duration'> - <span v-html='svgs.iconTimer'></span> - {{duration}} - </p> - <p class="finished-at" v-if='timeStopped'> - <i class="fa fa-calendar"></i> - <time - data-toggle="tooltip" - data-placement="top" - data-container="body" - :data-original-title='localTimeFinished'> - {{timeStopped.words}} - </time> - </p> - </td> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_realtime_listener/index.js.es6 b/app/assets/javascripts/vue_realtime_listener/index.js index 30f6680a673..30f6680a673 100644 --- a/app/assets/javascripts/vue_realtime_listener/index.js.es6 +++ b/app/assets/javascripts/vue_realtime_listener/index.js diff --git a/app/assets/javascripts/vue_shared/components/commit.js b/app/assets/javascripts/vue_shared/components/commit.js new file mode 100644 index 00000000000..4381487b79e --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/commit.js @@ -0,0 +1,164 @@ +/* global Vue */ +window.Vue = require('vue'); +const commitIconSvg = require('icons/_icon_commit.svg'); + +(() => { + window.gl = window.gl || {}; + + window.gl.CommitComponent = Vue.component('commit-component', { + + props: { + /** + * Indicates the existance of a tag. + * Used to render the correct icon, if true will render `fa-tag` icon, + * if false will render `fa-code-fork` icon. + */ + tag: { + type: Boolean, + required: false, + default: false, + }, + + /** + * If provided is used to render the branch name and url. + * Should contain the following properties: + * name + * ref_url + */ + commitRef: { + type: Object, + required: false, + default: () => ({}), + }, + + /** + * Used to link to the commit sha. + */ + commitUrl: { + type: String, + required: false, + default: '', + }, + + /** + * Used to show the commit short sha that links to the commit url. + */ + shortSha: { + type: String, + required: false, + default: '', + }, + + /** + * If provided shows the commit tile. + */ + title: { + type: String, + required: false, + default: '', + }, + + /** + * If provided renders information about the author of the commit. + * When provided should include: + * `avatar_url` to render the avatar icon + * `web_url` to link to user profile + * `username` to render alt and title tags + */ + author: { + type: Object, + required: false, + default: () => ({}), + }, + }, + + computed: { + /** + * Used to verify if all the properties needed to render the commit + * ref section were provided. + * + * TODO: Improve this! Use lodash _.has when we have it. + * + * @returns {Boolean} + */ + hasCommitRef() { + return this.commitRef && this.commitRef.name && this.commitRef.ref_url; + }, + + /** + * Used to verify if all the properties needed to render the commit + * author section were provided. + * + * TODO: Improve this! Use lodash _.has when we have it. + * + * @returns {Boolean} + */ + hasAuthor() { + return this.author && + this.author.avatar_url && + this.author.web_url && + this.author.username; + }, + + /** + * If information about the author is provided will return a string + * to be rendered as the alt attribute of the img tag. + * + * @returns {String} + */ + userImageAltDescription() { + return this.author && + this.author.username ? `${this.author.username}'s avatar` : null; + }, + }, + + data() { + return { commitIconSvg }; + }, + + template: ` + <div class="branch-commit"> + + <div v-if="hasCommitRef" class="icon-container"> + <i v-if="tag" class="fa fa-tag"></i> + <i v-if="!tag" class="fa fa-code-fork"></i> + </div> + + <a v-if="hasCommitRef" + class="monospace branch-name" + :href="commitRef.ref_url"> + {{commitRef.name}} + </a> + + <div v-html="commitIconSvg" class="commit-icon js-commit-icon"></div> + + <a class="commit-id monospace" + :href="commitUrl"> + {{shortSha}} + </a> + + <p class="commit-title"> + <span v-if="title"> + <a v-if="hasAuthor" + class="avatar-image-container" + :href="author.web_url"> + <img + class="avatar has-tooltip s20" + :src="author.avatar_url" + :alt="userImageAltDescription" + :title="author.username" /> + </a> + + <a class="commit-row-message" + :href="commitUrl"> + {{title}} + </a> + </span> + <span v-else> + Cant find HEAD commit for this branch + </span> + </p> + </div> + `, + }); +})(); diff --git a/app/assets/javascripts/vue_shared/components/commit.js.es6 b/app/assets/javascripts/vue_shared/components/commit.js.es6 deleted file mode 100644 index ff88e236829..00000000000 --- a/app/assets/javascripts/vue_shared/components/commit.js.es6 +++ /dev/null @@ -1,164 +0,0 @@ -/* global Vue */ -window.Vue = require('vue'); - -(() => { - window.gl = window.gl || {}; - - window.gl.CommitComponent = Vue.component('commit-component', { - - props: { - /** - * Indicates the existance of a tag. - * Used to render the correct icon, if true will render `fa-tag` icon, - * if false will render `fa-code-fork` icon. - */ - tag: { - type: Boolean, - required: false, - default: false, - }, - - /** - * If provided is used to render the branch name and url. - * Should contain the following properties: - * name - * ref_url - */ - commitRef: { - type: Object, - required: false, - default: () => ({}), - }, - - /** - * Used to link to the commit sha. - */ - commitUrl: { - type: String, - required: false, - default: '', - }, - - /** - * Used to show the commit short sha that links to the commit url. - */ - shortSha: { - type: String, - required: false, - default: '', - }, - - /** - * If provided shows the commit tile. - */ - title: { - type: String, - required: false, - default: '', - }, - - /** - * If provided renders information about the author of the commit. - * When provided should include: - * `avatar_url` to render the avatar icon - * `web_url` to link to user profile - * `username` to render alt and title tags - */ - author: { - type: Object, - required: false, - default: () => ({}), - }, - - commitIconSvg: { - type: String, - required: false, - }, - }, - - computed: { - /** - * Used to verify if all the properties needed to render the commit - * ref section were provided. - * - * TODO: Improve this! Use lodash _.has when we have it. - * - * @returns {Boolean} - */ - hasCommitRef() { - return this.commitRef && this.commitRef.name && this.commitRef.ref_url; - }, - - /** - * Used to verify if all the properties needed to render the commit - * author section were provided. - * - * TODO: Improve this! Use lodash _.has when we have it. - * - * @returns {Boolean} - */ - hasAuthor() { - return this.author && - this.author.avatar_url && - this.author.web_url && - this.author.username; - }, - - /** - * If information about the author is provided will return a string - * to be rendered as the alt attribute of the img tag. - * - * @returns {String} - */ - userImageAltDescription() { - return this.author && - this.author.username ? `${this.author.username}'s avatar` : null; - }, - }, - - template: ` - <div class="branch-commit"> - - <div v-if="hasCommitRef" class="icon-container"> - <i v-if="tag" class="fa fa-tag"></i> - <i v-if="!tag" class="fa fa-code-fork"></i> - </div> - - <a v-if="hasCommitRef" - class="monospace branch-name" - :href="commitRef.ref_url"> - {{commitRef.name}} - </a> - - <div v-html="commitIconSvg" class="commit-icon js-commit-icon"></div> - - <a class="commit-id monospace" - :href="commitUrl"> - {{shortSha}} - </a> - - <p class="commit-title"> - <span v-if="title"> - <a v-if="hasAuthor" - class="avatar-image-container" - :href="author.web_url"> - <img - class="avatar has-tooltip s20" - :src="author.avatar_url" - :alt="userImageAltDescription" - :title="author.username" /> - </a> - - <a class="commit-row-message" - :href="commitUrl"> - {{title}} - </a> - </span> - <span v-else> - Cant find HEAD commit for this branch - </span> - </p> - </div> - `, - }); -})(); diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.js b/app/assets/javascripts/vue_shared/components/pipelines_table.js new file mode 100644 index 00000000000..0d8f85db965 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/pipelines_table.js @@ -0,0 +1,52 @@ +/* eslint-disable no-param-reassign */ +/* global Vue */ + +require('./pipelines_table_row'); +/** + * Pipelines Table Component. + * + * Given an array of objects, renders a table. + */ + +(() => { + window.gl = window.gl || {}; + gl.pipelines = gl.pipelines || {}; + + gl.pipelines.PipelinesTableComponent = Vue.component('pipelines-table-component', { + + props: { + pipelines: { + type: Array, + required: true, + default: () => ([]), + }, + + }, + + components: { + 'pipelines-table-row-component': gl.pipelines.PipelinesTableRowComponent, + }, + + template: ` + <table class="table ci-table"> + <thead> + <tr> + <th class="js-pipeline-status pipeline-status">Status</th> + <th class="js-pipeline-info pipeline-info">Pipeline</th> + <th class="js-pipeline-commit pipeline-commit">Commit</th> + <th class="js-pipeline-stages pipeline-stages">Stages</th> + <th class="js-pipeline-date pipeline-date"></th> + <th class="js-pipeline-actions pipeline-actions"></th> + </tr> + </thead> + <tbody> + <template v-for="model in pipelines" + v-bind:model="model"> + <tr is="pipelines-table-row-component" + :pipeline="model"></tr> + </template> + </tbody> + </table> + `, + }); +})(); diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 deleted file mode 100644 index 34d3bbdd80d..00000000000 --- a/app/assets/javascripts/vue_shared/components/pipelines_table.js.es6 +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* global Vue */ - -require('./pipelines_table_row'); -/** - * Pipelines Table Component. - * - * Given an array of objects, renders a table. - */ - -(() => { - window.gl = window.gl || {}; - gl.pipelines = gl.pipelines || {}; - - gl.pipelines.PipelinesTableComponent = Vue.component('pipelines-table-component', { - - props: { - pipelines: { - type: Array, - required: true, - default: () => ([]), - }, - - /** - * TODO: Remove this when we have webpack. - */ - svgs: { - type: Object, - required: true, - default: () => ({}), - }, - }, - - components: { - 'pipelines-table-row-component': gl.pipelines.PipelinesTableRowComponent, - }, - - template: ` - <table class="table ci-table"> - <thead> - <tr> - <th class="js-pipeline-status pipeline-status">Status</th> - <th class="js-pipeline-info pipeline-info">Pipeline</th> - <th class="js-pipeline-commit pipeline-commit">Commit</th> - <th class="js-pipeline-stages pipeline-stages">Stages</th> - <th class="js-pipeline-date pipeline-date"></th> - <th class="js-pipeline-actions pipeline-actions"></th> - </tr> - </thead> - <tbody> - <template v-for="model in pipelines" - v-bind:model="model"> - <tr is="pipelines-table-row-component" - :pipeline="model" - :svgs="svgs"></tr> - </template> - </tbody> - </table> - `, - }); -})(); diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js new file mode 100644 index 00000000000..e5e88186a85 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js @@ -0,0 +1,199 @@ +/* eslint-disable no-param-reassign */ +/* global Vue */ + +require('../../vue_pipelines_index/status'); +require('../../vue_pipelines_index/pipeline_url'); +require('../../vue_pipelines_index/stage'); +require('../../vue_pipelines_index/pipeline_actions'); +require('../../vue_pipelines_index/time_ago'); +require('./commit'); +/** + * Pipeline table row. + * + * Given the received object renders a table row in the pipelines' table. + */ +(() => { + window.gl = window.gl || {}; + gl.pipelines = gl.pipelines || {}; + + gl.pipelines.PipelinesTableRowComponent = Vue.component('pipelines-table-row-component', { + + props: { + pipeline: { + type: Object, + required: true, + default: () => ({}), + }, + + }, + + components: { + 'commit-component': gl.CommitComponent, + 'pipeline-actions': gl.VuePipelineActions, + 'dropdown-stage': gl.VueStage, + 'pipeline-url': gl.VuePipelineUrl, + 'status-scope': gl.VueStatusScope, + 'time-ago': gl.VueTimeAgo, + }, + + computed: { + /** + * If provided, returns the commit tag. + * Needed to render the commit component column. + * + * This field needs a lot of verification, because of different possible cases: + * + * 1. person who is an author of a commit might be a GitLab user + * 2. if person who is an author of a commit is a GitLab user he/she can have a GitLab avatar + * 3. If GitLab user does not have avatar he/she might have a Gravatar + * 4. If committer is not a GitLab User he/she can have a Gravatar + * 5. We do not have consistent API object in this case + * 6. We should improve API and the code + * + * @returns {Object|Undefined} + */ + commitAuthor() { + let commitAuthorInformation; + + // 1. person who is an author of a commit might be a GitLab user + if (this.pipeline && + this.pipeline.commit && + this.pipeline.commit.author) { + // 2. if person who is an author of a commit is a GitLab user + // he/she can have a GitLab avatar + if (this.pipeline.commit.author.avatar_url) { + commitAuthorInformation = this.pipeline.commit.author; + + // 3. If GitLab user does not have avatar he/she might have a Gravatar + } else if (this.pipeline.commit.author_gravatar_url) { + commitAuthorInformation = Object.assign({}, this.pipeline.commit.author, { + avatar_url: this.pipeline.commit.author_gravatar_url, + }); + } + } + + // 4. If committer is not a GitLab User he/she can have a Gravatar + if (this.pipeline && + this.pipeline.commit) { + commitAuthorInformation = { + avatar_url: this.pipeline.commit.author_gravatar_url, + web_url: `mailto:${this.pipeline.commit.author_email}`, + username: this.pipeline.commit.author_name, + }; + } + + return commitAuthorInformation; + }, + + /** + * If provided, returns the commit tag. + * Needed to render the commit component column. + * + * @returns {String|Undefined} + */ + commitTag() { + if (this.pipeline.ref && + this.pipeline.ref.tag) { + return this.pipeline.ref.tag; + } + return undefined; + }, + + /** + * If provided, returns the commit ref. + * Needed to render the commit component column. + * + * Matches `path` prop sent in the API to `ref_url` prop needed + * in the commit component. + * + * @returns {Object|Undefined} + */ + commitRef() { + if (this.pipeline.ref) { + return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => { + if (prop === 'path') { + accumulator.ref_url = this.pipeline.ref[prop]; + } else { + accumulator[prop] = this.pipeline.ref[prop]; + } + return accumulator; + }, {}); + } + + return undefined; + }, + + /** + * If provided, returns the commit url. + * Needed to render the commit component column. + * + * @returns {String|Undefined} + */ + commitUrl() { + if (this.pipeline.commit && + this.pipeline.commit.commit_path) { + return this.pipeline.commit.commit_path; + } + return undefined; + }, + + /** + * If provided, returns the commit short sha. + * Needed to render the commit component column. + * + * @returns {String|Undefined} + */ + commitShortSha() { + if (this.pipeline.commit && + this.pipeline.commit.short_id) { + return this.pipeline.commit.short_id; + } + return undefined; + }, + + /** + * If provided, returns the commit title. + * Needed to render the commit component column. + * + * @returns {String|Undefined} + */ + commitTitle() { + if (this.pipeline.commit && + this.pipeline.commit.title) { + return this.pipeline.commit.title; + } + return undefined; + }, + }, + + template: ` + <tr class="commit"> + <status-scope :pipeline="pipeline"/> + + <pipeline-url :pipeline="pipeline"></pipeline-url> + + <td> + <commit-component + :tag="commitTag" + :commit-ref="commitRef" + :commit-url="commitUrl" + :short-sha="commitShortSha" + :title="commitTitle" + :author="commitAuthor"/> + </td> + + <td class="stage-cell"> + <div class="stage-container dropdown js-mini-pipeline-graph" + v-if="pipeline.details.stages.length > 0" + v-for="stage in pipeline.details.stages"> + <dropdown-stage :stage="stage"/> + </div> + </td> + + <time-ago :pipeline="pipeline"/> + + <pipeline-actions :pipeline="pipeline" /> + </tr> + `, + }); +})(); diff --git a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6 b/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6 deleted file mode 100644 index 61c1b72d9d2..00000000000 --- a/app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6 +++ /dev/null @@ -1,234 +0,0 @@ -/* eslint-disable no-param-reassign */ -/* global Vue */ - -require('../../vue_pipelines_index/status'); -require('../../vue_pipelines_index/pipeline_url'); -require('../../vue_pipelines_index/stage'); -require('../../vue_pipelines_index/pipeline_actions'); -require('../../vue_pipelines_index/time_ago'); -require('./commit'); -/** - * Pipeline table row. - * - * Given the received object renders a table row in the pipelines' table. - */ -(() => { - window.gl = window.gl || {}; - gl.pipelines = gl.pipelines || {}; - - gl.pipelines.PipelinesTableRowComponent = Vue.component('pipelines-table-row-component', { - - props: { - pipeline: { - type: Object, - required: true, - default: () => ({}), - }, - - /** - * TODO: Remove this when we have webpack; - */ - svgs: { - type: Object, - required: true, - default: () => ({}), - }, - }, - - components: { - 'commit-component': gl.CommitComponent, - 'pipeline-actions': gl.VuePipelineActions, - 'dropdown-stage': gl.VueStage, - 'pipeline-url': gl.VuePipelineUrl, - 'status-scope': gl.VueStatusScope, - 'time-ago': gl.VueTimeAgo, - }, - - computed: { - /** - * If provided, returns the commit tag. - * Needed to render the commit component column. - * - * This field needs a lot of verification, because of different possible cases: - * - * 1. person who is an author of a commit might be a GitLab user - * 2. if person who is an author of a commit is a GitLab user he/she can have a GitLab avatar - * 3. If GitLab user does not have avatar he/she might have a Gravatar - * 4. If committer is not a GitLab User he/she can have a Gravatar - * 5. We do not have consistent API object in this case - * 6. We should improve API and the code - * - * @returns {Object|Undefined} - */ - commitAuthor() { - let commitAuthorInformation; - - // 1. person who is an author of a commit might be a GitLab user - if (this.pipeline && - this.pipeline.commit && - this.pipeline.commit.author) { - // 2. if person who is an author of a commit is a GitLab user - // he/she can have a GitLab avatar - if (this.pipeline.commit.author.avatar_url) { - commitAuthorInformation = this.pipeline.commit.author; - - // 3. If GitLab user does not have avatar he/she might have a Gravatar - } else if (this.pipeline.commit.author_gravatar_url) { - commitAuthorInformation = Object.assign({}, this.pipeline.commit.author, { - avatar_url: this.pipeline.commit.author_gravatar_url, - }); - } - } - - // 4. If committer is not a GitLab User he/she can have a Gravatar - if (this.pipeline && - this.pipeline.commit) { - commitAuthorInformation = { - avatar_url: this.pipeline.commit.author_gravatar_url, - web_url: `mailto:${this.pipeline.commit.author_email}`, - username: this.pipeline.commit.author_name, - }; - } - - return commitAuthorInformation; - }, - - /** - * If provided, returns the commit tag. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ - commitTag() { - if (this.pipeline.ref && - this.pipeline.ref.tag) { - return this.pipeline.ref.tag; - } - return undefined; - }, - - /** - * If provided, returns the commit ref. - * Needed to render the commit component column. - * - * Matches `path` prop sent in the API to `ref_url` prop needed - * in the commit component. - * - * @returns {Object|Undefined} - */ - commitRef() { - if (this.pipeline.ref) { - return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => { - if (prop === 'path') { - accumulator.ref_url = this.pipeline.ref[prop]; - } else { - accumulator[prop] = this.pipeline.ref[prop]; - } - return accumulator; - }, {}); - } - - return undefined; - }, - - /** - * If provided, returns the commit url. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ - commitUrl() { - if (this.pipeline.commit && - this.pipeline.commit.commit_path) { - return this.pipeline.commit.commit_path; - } - return undefined; - }, - - /** - * If provided, returns the commit short sha. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ - commitShortSha() { - if (this.pipeline.commit && - this.pipeline.commit.short_id) { - return this.pipeline.commit.short_id; - } - return undefined; - }, - - /** - * If provided, returns the commit title. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ - commitTitle() { - if (this.pipeline.commit && - this.pipeline.commit.title) { - return this.pipeline.commit.title; - } - return undefined; - }, - }, - - methods: { - /** - * FIXME: This should not be in this component but in the components that - * need this function. - * - * Used to render SVGs in the following components: - * - status-scope - * - dropdown-stage - * - * @param {String} string - * @return {String} - */ - match(string) { - return string.replace(/_([a-z])/g, (m, w) => w.toUpperCase()); - }, - }, - - template: ` - <tr class="commit"> - <status-scope - :pipeline="pipeline" - :svgs="svgs" - :match="match"> - </status-scope> - - <pipeline-url :pipeline="pipeline"></pipeline-url> - - <td> - <commit-component - :tag="commitTag" - :commit-ref="commitRef" - :commit-url="commitUrl" - :short-sha="commitShortSha" - :title="commitTitle" - :author="commitAuthor" - :commit-icon-svg="svgs.commitIconSvg"> - </commit-component> - </td> - - <td class="stage-cell"> - <div class="stage-container dropdown js-mini-pipeline-graph" - v-if="pipeline.details.stages.length > 0" - v-for="stage in pipeline.details.stages"> - <dropdown-stage - :stage="stage" - :svgs="svgs" - :match="match"> - </dropdown-stage> - </div> - </td> - - <time-ago :pipeline="pipeline" :svgs="svgs"></time-ago> - - <pipeline-actions :pipeline="pipeline" :svgs="svgs"></pipeline-actions> - </tr> - `, - }); -})(); diff --git a/app/assets/javascripts/vue_shared/components/table_pagination.js b/app/assets/javascripts/vue_shared/components/table_pagination.js new file mode 100644 index 00000000000..8943b850a72 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/table_pagination.js @@ -0,0 +1,147 @@ +/* global Vue, gl */ +/* eslint-disable no-param-reassign, no-plusplus */ + +window.Vue = require('vue'); + +((gl) => { + const PAGINATION_UI_BUTTON_LIMIT = 4; + const UI_LIMIT = 6; + const SPREAD = '...'; + const PREV = 'Prev'; + const NEXT = 'Next'; + const FIRST = '<< First'; + const LAST = 'Last >>'; + + gl.VueGlPagination = Vue.extend({ + props: { + + // TODO: Consider refactoring in light of turbolinks removal. + + /** + This function will take the information given by the pagination component + + Here is an example `change` method: + + change(pagenum) { + gl.utils.visitUrl(`?page=${pagenum}`); + }, + */ + + change: { + type: Function, + required: true, + }, + + /** + pageInfo will come from the headers of the API call + in the `.then` clause of the VueResource API call + there should be a function that contructs the pageInfo for this component + + This is an example: + + const pageInfo = headers => ({ + perPage: +headers['X-Per-Page'], + page: +headers['X-Page'], + total: +headers['X-Total'], + totalPages: +headers['X-Total-Pages'], + nextPage: +headers['X-Next-Page'], + previousPage: +headers['X-Prev-Page'], + }); + */ + + pageInfo: { + type: Object, + required: true, + }, + }, + methods: { + changePage(e) { + const text = e.target.innerText; + const { totalPages, nextPage, previousPage } = this.pageInfo; + + switch (text) { + case SPREAD: + break; + case LAST: + this.change(totalPages); + break; + case NEXT: + this.change(nextPage); + break; + case PREV: + this.change(previousPage); + break; + case FIRST: + this.change(1); + break; + default: + this.change(+text); + break; + } + }, + }, + computed: { + prev() { + return this.pageInfo.previousPage; + }, + next() { + return this.pageInfo.nextPage; + }, + getItems() { + const total = this.pageInfo.totalPages; + const page = this.pageInfo.page; + const items = []; + + if (page > 1) items.push({ title: FIRST }); + + if (page > 1) { + items.push({ title: PREV, prev: true }); + } else { + items.push({ title: PREV, disabled: true, prev: true }); + } + + if (page > UI_LIMIT) items.push({ title: SPREAD, separator: true }); + + const start = Math.max(page - PAGINATION_UI_BUTTON_LIMIT, 1); + const end = Math.min(page + PAGINATION_UI_BUTTON_LIMIT, total); + + for (let i = start; i <= end; i++) { + const isActive = i === page; + items.push({ title: i, active: isActive, page: true }); + } + + if (total - page > PAGINATION_UI_BUTTON_LIMIT) { + items.push({ title: SPREAD, separator: true, page: true }); + } + + if (page === total) { + items.push({ title: NEXT, disabled: true, next: true }); + } else if (total - page >= 1) { + items.push({ title: NEXT, next: true }); + } + + if (total - page >= 1) items.push({ title: LAST, last: true }); + + return items; + }, + }, + template: ` + <div class="gl-pagination"> + <ul class="pagination clearfix"> + <li v-for='item in getItems' + :class='{ + page: item.page, + prev: item.prev, + next: item.next, + separator: item.separator, + active: item.active, + disabled: item.disabled + }' + > + <a @click="changePage($event)">{{item.title}}</a> + </li> + </ul> + </div> + `, + }); +})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_shared/components/table_pagination.js.es6 b/app/assets/javascripts/vue_shared/components/table_pagination.js.es6 deleted file mode 100644 index dd046405575..00000000000 --- a/app/assets/javascripts/vue_shared/components/table_pagination.js.es6 +++ /dev/null @@ -1,148 +0,0 @@ -/* global Vue, gl */ -/* eslint-disable no-param-reassign, no-plusplus */ - -window.Vue = require('vue'); - -((gl) => { - const PAGINATION_UI_BUTTON_LIMIT = 4; - const UI_LIMIT = 6; - const SPREAD = '...'; - const PREV = 'Prev'; - const NEXT = 'Next'; - const FIRST = '<< First'; - const LAST = 'Last >>'; - - gl.VueGlPagination = Vue.extend({ - props: { - - // TODO: Consider refactoring in light of turbolinks removal. - - /** - This function will take the information given by the pagination component - And make a new Turbolinks call - - Here is an example `change` method: - - change(pagenum) { - gl.utils.visitUrl(`?page=${pagenum}`); - }, - */ - - change: { - type: Function, - required: true, - }, - - /** - pageInfo will come from the headers of the API call - in the `.then` clause of the VueResource API call - there should be a function that contructs the pageInfo for this component - - This is an example: - - const pageInfo = headers => ({ - perPage: +headers['X-Per-Page'], - page: +headers['X-Page'], - total: +headers['X-Total'], - totalPages: +headers['X-Total-Pages'], - nextPage: +headers['X-Next-Page'], - previousPage: +headers['X-Prev-Page'], - }); - */ - - pageInfo: { - type: Object, - required: true, - }, - }, - methods: { - changePage(e) { - const text = e.target.innerText; - const { totalPages, nextPage, previousPage } = this.pageInfo; - - switch (text) { - case SPREAD: - break; - case LAST: - this.change(totalPages); - break; - case NEXT: - this.change(nextPage); - break; - case PREV: - this.change(previousPage); - break; - case FIRST: - this.change(1); - break; - default: - this.change(+text); - break; - } - }, - }, - computed: { - prev() { - return this.pageInfo.previousPage; - }, - next() { - return this.pageInfo.nextPage; - }, - getItems() { - const total = this.pageInfo.totalPages; - const page = this.pageInfo.page; - const items = []; - - if (page > 1) items.push({ title: FIRST }); - - if (page > 1) { - items.push({ title: PREV, prev: true }); - } else { - items.push({ title: PREV, disabled: true, prev: true }); - } - - if (page > UI_LIMIT) items.push({ title: SPREAD, separator: true }); - - const start = Math.max(page - PAGINATION_UI_BUTTON_LIMIT, 1); - const end = Math.min(page + PAGINATION_UI_BUTTON_LIMIT, total); - - for (let i = start; i <= end; i++) { - const isActive = i === page; - items.push({ title: i, active: isActive, page: true }); - } - - if (total - page > PAGINATION_UI_BUTTON_LIMIT) { - items.push({ title: SPREAD, separator: true, page: true }); - } - - if (page === total) { - items.push({ title: NEXT, disabled: true, next: true }); - } else if (total - page >= 1) { - items.push({ title: NEXT, next: true }); - } - - if (total - page >= 1) items.push({ title: LAST, last: true }); - - return items; - }, - }, - template: ` - <div class="gl-pagination"> - <ul class="pagination clearfix"> - <li v-for='item in getItems' - :class='{ - page: item.page, - prev: item.prev, - next: item.next, - separator: item.separator, - active: item.active, - disabled: item.disabled - }' - > - <a @click="changePage($event)">{{item.title}}</a> - </li> - </ul> - </div> - `, - }); -})(window.gl || (window.gl = {})); diff --git a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js index d3229f9f730..d3229f9f730 100644 --- a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 +++ b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js diff --git a/app/assets/javascripts/wikis.js.es6 b/app/assets/javascripts/wikis.js index 75fd1394a03..75fd1394a03 100644 --- a/app/assets/javascripts/wikis.js.es6 +++ b/app/assets/javascripts/wikis.js diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 39cf3b5f8ae..5bb7e8caec1 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -44,5 +44,6 @@ @import "framework/images.scss"; @import "framework/broadcast-messages"; @import "framework/emojis.scss"; +@import "framework/emoji-sprites.scss"; @import "framework/icons.scss"; @import "framework/snippets.scss"; diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss index 49907417e26..f363affa46c 100644 --- a/app/assets/stylesheets/framework/awards.scss +++ b/app/assets/stylesheets/framework/awards.scss @@ -7,6 +7,7 @@ .emoji-menu { position: absolute; + top: 0; margin-top: 3px; padding: $gl-padding; z-index: 9; @@ -20,7 +21,7 @@ opacity: 0; transform: scale(.2); transform-origin: 0 -45px; - transition: .3s cubic-bezier(.87,-.41,.19,1.44); + transition: .3s cubic-bezier(.67,.06,.19,1.44); transition-property: transform, opacity; &.is-aligned-right { @@ -47,12 +48,13 @@ } .emoji-menu-list { - list-style: none; - padding-left: 0; margin-bottom: 0; + padding-left: 0; + list-style: none; } .emoji-menu-list-item { + float: left; padding: 3px; margin-left: 1px; margin-right: 1px; @@ -97,6 +99,8 @@ padding: 5px 6px; outline: 0; + line-height: 1; + &.disabled { cursor: default; diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index ff31e7f7b3d..2a403589a53 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -96,7 +96,7 @@ .dropdown-menu-toggle { @extend .dropdown-toggle; - padding-right: 20px; + padding-right: 25px; position: relative; width: 163px; text-overflow: ellipsis; @@ -107,11 +107,12 @@ &.fa-spinner { font-size: 16px; - margin-top: -8px; + margin-top: -3px; } } - .fa-chevron-down { + .fa-chevron-down, + .fa-spinner { position: absolute; top: 11px; right: 8px; @@ -192,6 +193,10 @@ &.is-focused { background-color: $dropdown-link-hover-bg; text-decoration: none; + + .badge { + background-color: darken($row-hover, 5%); + } } &.dropdown-menu-empty-link { @@ -228,6 +233,12 @@ padding: 5px 8px; color: $gl-text-color-secondary; } + + .badge { + position: absolute; + right: 8px; + top: 5px; + } } .dropdown-menu-drop-up { diff --git a/app/assets/stylesheets/framework/emoji-sprites.scss b/app/assets/stylesheets/framework/emoji-sprites.scss new file mode 100644 index 00000000000..925415f84b1 --- /dev/null +++ b/app/assets/stylesheets/framework/emoji-sprites.scss @@ -0,0 +1,1811 @@ +.emoji-zzz { background-position: 0 0; } +.emoji-1234 { background-position: -20px 0; } +.emoji-1F627 { background-position: 0 -20px; } +.emoji-8ball { background-position: -20px -20px; } +.emoji-a { background-position: -40px 0; } +.emoji-ab { background-position: -40px -20px; } +.emoji-abc { background-position: 0 -40px; } +.emoji-abcd { background-position: -20px -40px; } +.emoji-accept { background-position: -40px -40px; } +.emoji-aerial_tramway { background-position: -60px 0; } +.emoji-airplane { background-position: -60px -20px; } +.emoji-airplane_arriving { background-position: -60px -40px; } +.emoji-airplane_departure { background-position: 0 -60px; } +.emoji-airplane_small { background-position: -20px -60px; } +.emoji-alarm_clock { background-position: -40px -60px; } +.emoji-alembic { background-position: -60px -60px; } +.emoji-alien { background-position: -80px 0; } +.emoji-ambulance { background-position: -80px -20px; } +.emoji-amphora { background-position: -80px -40px; } +.emoji-anchor { background-position: -80px -60px; } +.emoji-angel { background-position: 0 -80px; } +.emoji-angel_tone1 { background-position: -20px -80px; } +.emoji-angel_tone2 { background-position: -40px -80px; } +.emoji-angel_tone3 { background-position: -60px -80px; } +.emoji-angel_tone4 { background-position: -80px -80px; } +.emoji-angel_tone5 { background-position: -100px 0; } +.emoji-anger { background-position: -100px -20px; } +.emoji-anger_right { background-position: -100px -40px; } +.emoji-angry { background-position: -100px -60px; } +.emoji-ant { background-position: -100px -80px; } +.emoji-apple { background-position: 0 -100px; } +.emoji-aquarius { background-position: -20px -100px; } +.emoji-aries { background-position: -40px -100px; } +.emoji-arrow_backward { background-position: -60px -100px; } +.emoji-arrow_double_down { background-position: -80px -100px; } +.emoji-arrow_double_up { background-position: -100px -100px; } +.emoji-arrow_down { background-position: -120px 0; } +.emoji-arrow_down_small { background-position: -120px -20px; } +.emoji-arrow_forward { background-position: -120px -40px; } +.emoji-arrow_heading_down { background-position: -120px -60px; } +.emoji-arrow_heading_up { background-position: -120px -80px; } +.emoji-arrow_left { background-position: -120px -100px; } +.emoji-arrow_lower_left { background-position: 0 -120px; } +.emoji-arrow_lower_right { background-position: -20px -120px; } +.emoji-arrow_right { background-position: -40px -120px; } +.emoji-arrow_right_hook { background-position: -60px -120px; } +.emoji-arrow_up { background-position: -80px -120px; } +.emoji-arrow_up_down { background-position: -100px -120px; } +.emoji-arrow_up_small { background-position: -120px -120px; } +.emoji-arrow_upper_left { background-position: -140px 0; } +.emoji-arrow_upper_right { background-position: -140px -20px; } +.emoji-arrows_clockwise { background-position: -140px -40px; } +.emoji-arrows_counterclockwise { background-position: -140px -60px; } +.emoji-art { background-position: -140px -80px; } +.emoji-articulated_lorry { background-position: -140px -100px; } +.emoji-asterisk { background-position: -140px -120px; } +.emoji-astonished { background-position: 0 -140px; } +.emoji-athletic_shoe { background-position: -20px -140px; } +.emoji-atm { background-position: -40px -140px; } +.emoji-atom { background-position: -60px -140px; } +.emoji-avocado { background-position: -80px -140px; } +.emoji-b { background-position: -100px -140px; } +.emoji-baby { background-position: -120px -140px; } +.emoji-baby_bottle { background-position: -140px -140px; } +.emoji-baby_chick { background-position: -160px 0; } +.emoji-baby_symbol { background-position: -160px -20px; } +.emoji-baby_tone1 { background-position: -160px -40px; } +.emoji-baby_tone2 { background-position: -160px -60px; } +.emoji-baby_tone3 { background-position: -160px -80px; } +.emoji-baby_tone4 { background-position: -160px -100px; } +.emoji-baby_tone5 { background-position: -160px -120px; } +.emoji-back { background-position: -160px -140px; } +.emoji-bacon { background-position: 0 -160px; } +.emoji-badminton { background-position: -20px -160px; } +.emoji-baggage_claim { background-position: -40px -160px; } +.emoji-balloon { background-position: -60px -160px; } +.emoji-ballot_box { background-position: -80px -160px; } +.emoji-ballot_box_with_check { background-position: -100px -160px; } +.emoji-bamboo { background-position: -120px -160px; } +.emoji-banana { background-position: -140px -160px; } +.emoji-bangbang { background-position: -160px -160px; } +.emoji-bank { background-position: -180px 0; } +.emoji-bar_chart { background-position: -180px -20px; } +.emoji-barber { background-position: -180px -40px; } +.emoji-baseball { background-position: -180px -60px; } +.emoji-basketball { background-position: -180px -80px; } +.emoji-basketball_player { background-position: -180px -100px; } +.emoji-basketball_player_tone1 { background-position: -180px -120px; } +.emoji-basketball_player_tone2 { background-position: -180px -140px; } +.emoji-basketball_player_tone3 { background-position: -180px -160px; } +.emoji-basketball_player_tone4 { background-position: 0 -180px; } +.emoji-basketball_player_tone5 { background-position: -20px -180px; } +.emoji-bat { background-position: -40px -180px; } +.emoji-bath { background-position: -60px -180px; } +.emoji-bath_tone1 { background-position: -80px -180px; } +.emoji-bath_tone2 { background-position: -100px -180px; } +.emoji-bath_tone3 { background-position: -120px -180px; } +.emoji-bath_tone4 { background-position: -140px -180px; } +.emoji-bath_tone5 { background-position: -160px -180px; } +.emoji-bathtub { background-position: -180px -180px; } +.emoji-battery { background-position: -200px 0; } +.emoji-beach { background-position: -200px -20px; } +.emoji-beach_umbrella { background-position: -200px -40px; } +.emoji-bear { background-position: -200px -60px; } +.emoji-bed { background-position: -200px -80px; } +.emoji-bee { background-position: -200px -100px; } +.emoji-beer { background-position: -200px -120px; } +.emoji-beers { background-position: -200px -140px; } +.emoji-beetle { background-position: -200px -160px; } +.emoji-beginner { background-position: -200px -180px; } +.emoji-bell { background-position: 0 -200px; } +.emoji-bellhop { background-position: -20px -200px; } +.emoji-bento { background-position: -40px -200px; } +.emoji-bicyclist { background-position: -60px -200px; } +.emoji-bicyclist_tone1 { background-position: -80px -200px; } +.emoji-bicyclist_tone2 { background-position: -100px -200px; } +.emoji-bicyclist_tone3 { background-position: -120px -200px; } +.emoji-bicyclist_tone4 { background-position: -140px -200px; } +.emoji-bicyclist_tone5 { background-position: -160px -200px; } +.emoji-bike { background-position: -180px -200px; } +.emoji-bikini { background-position: -200px -200px; } +.emoji-biohazard { background-position: -220px 0; } +.emoji-bird { background-position: -220px -20px; } +.emoji-birthday { background-position: -220px -40px; } +.emoji-black_circle { background-position: -220px -60px; } +.emoji-black_heart { background-position: -220px -80px; } +.emoji-black_joker { background-position: -220px -100px; } +.emoji-black_large_square { background-position: -220px -120px; } +.emoji-black_medium_small_square { background-position: -220px -140px; } +.emoji-black_medium_square { background-position: -220px -160px; } +.emoji-black_nib { background-position: -220px -180px; } +.emoji-black_small_square { background-position: -220px -200px; } +.emoji-black_square_button { background-position: 0 -220px; } +.emoji-blossom { background-position: -20px -220px; } +.emoji-blowfish { background-position: -40px -220px; } +.emoji-blue_book { background-position: -60px -220px; } +.emoji-blue_car { background-position: -80px -220px; } +.emoji-blue_heart { background-position: -100px -220px; } +.emoji-blush { background-position: -120px -220px; } +.emoji-boar { background-position: -140px -220px; } +.emoji-bomb { background-position: -160px -220px; } +.emoji-book { background-position: -180px -220px; } +.emoji-bookmark { background-position: -200px -220px; } +.emoji-bookmark_tabs { background-position: -220px -220px; } +.emoji-books { background-position: -240px 0; } +.emoji-boom { background-position: -240px -20px; } +.emoji-boot { background-position: -240px -40px; } +.emoji-bouquet { background-position: -240px -60px; } +.emoji-bow { background-position: -240px -80px; } +.emoji-bow_and_arrow { background-position: -240px -100px; } +.emoji-bow_tone1 { background-position: -240px -120px; } +.emoji-bow_tone2 { background-position: -240px -140px; } +.emoji-bow_tone3 { background-position: -240px -160px; } +.emoji-bow_tone4 { background-position: -240px -180px; } +.emoji-bow_tone5 { background-position: -240px -200px; } +.emoji-bowling { background-position: -240px -220px; } +.emoji-boxing_glove { background-position: 0 -240px; } +.emoji-boy { background-position: -20px -240px; } +.emoji-boy_tone1 { background-position: -40px -240px; } +.emoji-boy_tone2 { background-position: -60px -240px; } +.emoji-boy_tone3 { background-position: -80px -240px; } +.emoji-boy_tone4 { background-position: -100px -240px; } +.emoji-boy_tone5 { background-position: -120px -240px; } +.emoji-bread { background-position: -140px -240px; } +.emoji-bride_with_veil { background-position: -160px -240px; } +.emoji-bride_with_veil_tone1 { background-position: -180px -240px; } +.emoji-bride_with_veil_tone2 { background-position: -200px -240px; } +.emoji-bride_with_veil_tone3 { background-position: -220px -240px; } +.emoji-bride_with_veil_tone4 { background-position: -240px -240px; } +.emoji-bride_with_veil_tone5 { background-position: -260px 0; } +.emoji-bridge_at_night { background-position: -260px -20px; } +.emoji-briefcase { background-position: -260px -40px; } +.emoji-broken_heart { background-position: -260px -60px; } +.emoji-bug { background-position: -260px -80px; } +.emoji-bulb { background-position: -260px -100px; } +.emoji-bullettrain_front { background-position: -260px -120px; } +.emoji-bullettrain_side { background-position: -260px -140px; } +.emoji-burrito { background-position: -260px -160px; } +.emoji-bus { background-position: -260px -180px; } +.emoji-busstop { background-position: -260px -200px; } +.emoji-bust_in_silhouette { background-position: -260px -220px; } +.emoji-busts_in_silhouette { background-position: -260px -240px; } +.emoji-butterfly { background-position: 0 -260px; } +.emoji-cactus { background-position: -20px -260px; } +.emoji-cake { background-position: -40px -260px; } +.emoji-calendar { background-position: -60px -260px; } +.emoji-calendar_spiral { background-position: -80px -260px; } +.emoji-call_me { background-position: -100px -260px; } +.emoji-call_me_tone1 { background-position: -120px -260px; } +.emoji-call_me_tone2 { background-position: -140px -260px; } +.emoji-call_me_tone3 { background-position: -160px -260px; } +.emoji-call_me_tone4 { background-position: -180px -260px; } +.emoji-call_me_tone5 { background-position: -200px -260px; } +.emoji-calling { background-position: -220px -260px; } +.emoji-camel { background-position: -240px -260px; } +.emoji-camera { background-position: -260px -260px; } +.emoji-camera_with_flash { background-position: -280px 0; } +.emoji-camping { background-position: -280px -20px; } +.emoji-cancer { background-position: -280px -40px; } +.emoji-candle { background-position: -280px -60px; } +.emoji-candy { background-position: -280px -80px; } +.emoji-canoe { background-position: -280px -100px; } +.emoji-capital_abcd { background-position: -280px -120px; } +.emoji-capricorn { background-position: -280px -140px; } +.emoji-card_box { background-position: -280px -160px; } +.emoji-card_index { background-position: -280px -180px; } +.emoji-carousel_horse { background-position: -280px -200px; } +.emoji-carrot { background-position: -280px -220px; } +.emoji-cartwheel { background-position: -280px -240px; } +.emoji-cartwheel_tone1 { background-position: -280px -260px; } +.emoji-cartwheel_tone2 { background-position: 0 -280px; } +.emoji-cartwheel_tone3 { background-position: -20px -280px; } +.emoji-cartwheel_tone4 { background-position: -40px -280px; } +.emoji-cartwheel_tone5 { background-position: -60px -280px; } +.emoji-cat { background-position: -80px -280px; } +.emoji-cat2 { background-position: -100px -280px; } +.emoji-cd { background-position: -120px -280px; } +.emoji-chains { background-position: -140px -280px; } +.emoji-champagne { background-position: -160px -280px; } +.emoji-champagne_glass { background-position: -180px -280px; } +.emoji-chart { background-position: -200px -280px; } +.emoji-chart_with_downwards_trend { background-position: -220px -280px; } +.emoji-chart_with_upwards_trend { background-position: -240px -280px; } +.emoji-checkered_flag { background-position: -260px -280px; } +.emoji-cheese { background-position: -280px -280px; } +.emoji-cherries { background-position: -300px 0; } +.emoji-cherry_blossom { background-position: -300px -20px; } +.emoji-chestnut { background-position: -300px -40px; } +.emoji-chicken { background-position: -300px -60px; } +.emoji-children_crossing { background-position: -300px -80px; } +.emoji-chipmunk { background-position: -300px -100px; } +.emoji-chocolate_bar { background-position: -300px -120px; } +.emoji-christmas_tree { background-position: -300px -140px; } +.emoji-church { background-position: -300px -160px; } +.emoji-cinema { background-position: -300px -180px; } +.emoji-circus_tent { background-position: -300px -200px; } +.emoji-city_dusk { background-position: -300px -220px; } +.emoji-city_sunset { background-position: -300px -240px; } +.emoji-cityscape { background-position: -300px -260px; } +.emoji-cl { background-position: -300px -280px; } +.emoji-clap { background-position: 0 -300px; } +.emoji-clap_tone1 { background-position: -20px -300px; } +.emoji-clap_tone2 { background-position: -40px -300px; } +.emoji-clap_tone3 { background-position: -60px -300px; } +.emoji-clap_tone4 { background-position: -80px -300px; } +.emoji-clap_tone5 { background-position: -100px -300px; } +.emoji-clapper { background-position: -120px -300px; } +.emoji-classical_building { background-position: -140px -300px; } +.emoji-clipboard { background-position: -160px -300px; } +.emoji-clock { background-position: -180px -300px; } +.emoji-clock1 { background-position: -200px -300px; } +.emoji-clock10 { background-position: -220px -300px; } +.emoji-clock1030 { background-position: -240px -300px; } +.emoji-clock11 { background-position: -260px -300px; } +.emoji-clock1130 { background-position: -280px -300px; } +.emoji-clock12 { background-position: -300px -300px; } +.emoji-clock1230 { background-position: -320px 0; } +.emoji-clock130 { background-position: -320px -20px; } +.emoji-clock2 { background-position: -320px -40px; } +.emoji-clock230 { background-position: -320px -60px; } +.emoji-clock3 { background-position: -320px -80px; } +.emoji-clock330 { background-position: -320px -100px; } +.emoji-clock4 { background-position: -320px -120px; } +.emoji-clock430 { background-position: -320px -140px; } +.emoji-clock5 { background-position: -320px -160px; } +.emoji-clock530 { background-position: -320px -180px; } +.emoji-clock6 { background-position: -320px -200px; } +.emoji-clock630 { background-position: -320px -220px; } +.emoji-clock7 { background-position: -320px -240px; } +.emoji-clock730 { background-position: -320px -260px; } +.emoji-clock8 { background-position: -320px -280px; } +.emoji-clock830 { background-position: -320px -300px; } +.emoji-clock9 { background-position: 0 -320px; } +.emoji-clock930 { background-position: -20px -320px; } +.emoji-closed_book { background-position: -40px -320px; } +.emoji-closed_lock_with_key { background-position: -60px -320px; } +.emoji-closed_umbrella { background-position: -80px -320px; } +.emoji-cloud { background-position: -100px -320px; } +.emoji-cloud_lightning { background-position: -120px -320px; } +.emoji-cloud_rain { background-position: -140px -320px; } +.emoji-cloud_snow { background-position: -160px -320px; } +.emoji-cloud_tornado { background-position: -180px -320px; } +.emoji-clown { background-position: -200px -320px; } +.emoji-clubs { background-position: -220px -320px; } +.emoji-cocktail { background-position: -240px -320px; } +.emoji-coffee { background-position: -260px -320px; } +.emoji-coffin { background-position: -280px -320px; } +.emoji-cold_sweat { background-position: -300px -320px; } +.emoji-comet { background-position: -320px -320px; } +.emoji-compression { background-position: -340px 0; } +.emoji-computer { background-position: -340px -20px; } +.emoji-confetti_ball { background-position: -340px -40px; } +.emoji-confounded { background-position: -340px -60px; } +.emoji-confused { background-position: -340px -80px; } +.emoji-congratulations { background-position: -340px -100px; } +.emoji-construction { background-position: -340px -120px; } +.emoji-construction_site { background-position: -340px -140px; } +.emoji-construction_worker { background-position: -340px -160px; } +.emoji-construction_worker_tone1 { background-position: -340px -180px; } +.emoji-construction_worker_tone2 { background-position: -340px -200px; } +.emoji-construction_worker_tone3 { background-position: -340px -220px; } +.emoji-construction_worker_tone4 { background-position: -340px -240px; } +.emoji-construction_worker_tone5 { background-position: -340px -260px; } +.emoji-control_knobs { background-position: -340px -280px; } +.emoji-convenience_store { background-position: -340px -300px; } +.emoji-cookie { background-position: -340px -320px; } +.emoji-cooking { background-position: 0 -340px; } +.emoji-cool { background-position: -20px -340px; } +.emoji-cop { background-position: -40px -340px; } +.emoji-cop_tone1 { background-position: -60px -340px; } +.emoji-cop_tone2 { background-position: -80px -340px; } +.emoji-cop_tone3 { background-position: -100px -340px; } +.emoji-cop_tone4 { background-position: -120px -340px; } +.emoji-cop_tone5 { background-position: -140px -340px; } +.emoji-copyright { background-position: -160px -340px; } +.emoji-corn { background-position: -180px -340px; } +.emoji-couch { background-position: -200px -340px; } +.emoji-couple { background-position: -220px -340px; } +.emoji-couple_mm { background-position: -240px -340px; } +.emoji-couple_with_heart { background-position: -260px -340px; } +.emoji-couple_ww { background-position: -280px -340px; } +.emoji-couplekiss { background-position: -300px -340px; } +.emoji-cow { background-position: -320px -340px; } +.emoji-cow2 { background-position: -340px -340px; } +.emoji-cowboy { background-position: -360px 0; } +.emoji-crab { background-position: -360px -20px; } +.emoji-crayon { background-position: -360px -40px; } +.emoji-credit_card { background-position: -360px -60px; } +.emoji-crescent_moon { background-position: -360px -80px; } +.emoji-cricket { background-position: -360px -100px; } +.emoji-crocodile { background-position: -360px -120px; } +.emoji-croissant { background-position: -360px -140px; } +.emoji-cross { background-position: -360px -160px; } +.emoji-crossed_flags { background-position: -360px -180px; } +.emoji-crossed_swords { background-position: -360px -200px; } +.emoji-crown { background-position: -360px -220px; } +.emoji-cruise_ship { background-position: -360px -240px; } +.emoji-cry { background-position: -360px -260px; } +.emoji-crying_cat_face { background-position: -360px -280px; } +.emoji-crystal_ball { background-position: -360px -300px; } +.emoji-cucumber { background-position: -360px -320px; } +.emoji-cupid { background-position: -360px -340px; } +.emoji-curly_loop { background-position: 0 -360px; } +.emoji-currency_exchange { background-position: -20px -360px; } +.emoji-curry { background-position: -40px -360px; } +.emoji-custard { background-position: -60px -360px; } +.emoji-customs { background-position: -80px -360px; } +.emoji-cyclone { background-position: -100px -360px; } +.emoji-dagger { background-position: -120px -360px; } +.emoji-dancer { background-position: -140px -360px; } +.emoji-dancer_tone1 { background-position: -160px -360px; } +.emoji-dancer_tone2 { background-position: -180px -360px; } +.emoji-dancer_tone3 { background-position: -200px -360px; } +.emoji-dancer_tone4 { background-position: -220px -360px; } +.emoji-dancer_tone5 { background-position: -240px -360px; } +.emoji-dancers { background-position: -260px -360px; } +.emoji-dango { background-position: -280px -360px; } +.emoji-dark_sunglasses { background-position: -300px -360px; } +.emoji-dart { background-position: -320px -360px; } +.emoji-dash { background-position: -340px -360px; } +.emoji-date { background-position: -360px -360px; } +.emoji-deciduous_tree { background-position: -380px 0; } +.emoji-deer { background-position: -380px -20px; } +.emoji-department_store { background-position: -380px -40px; } +.emoji-desert { background-position: -380px -60px; } +.emoji-desktop { background-position: -380px -80px; } +.emoji-diamond_shape_with_a_dot_inside { background-position: -380px -100px; } +.emoji-diamonds { background-position: -380px -120px; } +.emoji-disappointed { background-position: -380px -140px; } +.emoji-disappointed_relieved { background-position: -380px -160px; } +.emoji-dividers { background-position: -380px -180px; } +.emoji-dizzy { background-position: -380px -200px; } +.emoji-dizzy_face { background-position: -380px -220px; } +.emoji-do_not_litter { background-position: -380px -240px; } +.emoji-dog { background-position: -380px -260px; } +.emoji-dog2 { background-position: -380px -280px; } +.emoji-dollar { background-position: -380px -300px; } +.emoji-dolls { background-position: -380px -320px; } +.emoji-dolphin { background-position: -380px -340px; } +.emoji-door { background-position: -380px -360px; } +.emoji-doughnut { background-position: 0 -380px; } +.emoji-dove { background-position: -20px -380px; } +.emoji-dragon { background-position: -40px -380px; } +.emoji-dragon_face { background-position: -60px -380px; } +.emoji-dress { background-position: -80px -380px; } +.emoji-dromedary_camel { background-position: -100px -380px; } +.emoji-drooling_face { background-position: -120px -380px; } +.emoji-droplet { background-position: -140px -380px; } +.emoji-drum { background-position: -160px -380px; } +.emoji-duck { background-position: -180px -380px; } +.emoji-dvd { background-position: -200px -380px; } +.emoji-e-mail { background-position: -220px -380px; } +.emoji-eagle { background-position: -240px -380px; } +.emoji-ear { background-position: -260px -380px; } +.emoji-ear_of_rice { background-position: -280px -380px; } +.emoji-ear_tone1 { background-position: -300px -380px; } +.emoji-ear_tone2 { background-position: -320px -380px; } +.emoji-ear_tone3 { background-position: -340px -380px; } +.emoji-ear_tone4 { background-position: -360px -380px; } +.emoji-ear_tone5 { background-position: -380px -380px; } +.emoji-earth_africa { background-position: -400px 0; } +.emoji-earth_americas { background-position: -400px -20px; } +.emoji-earth_asia { background-position: -400px -40px; } +.emoji-egg { background-position: -400px -60px; } +.emoji-eggplant { background-position: -400px -80px; } +.emoji-eight { background-position: -400px -100px; } +.emoji-eight_pointed_black_star { background-position: -400px -120px; } +.emoji-eight_spoked_asterisk { background-position: -400px -140px; } +.emoji-eject { background-position: -400px -160px; } +.emoji-electric_plug { background-position: -400px -180px; } +.emoji-elephant { background-position: -400px -200px; } +.emoji-end { background-position: -400px -220px; } +.emoji-envelope { background-position: -400px -240px; } +.emoji-envelope_with_arrow { background-position: -400px -260px; } +.emoji-euro { background-position: -400px -280px; } +.emoji-european_castle { background-position: -400px -300px; } +.emoji-european_post_office { background-position: -400px -320px; } +.emoji-evergreen_tree { background-position: -400px -340px; } +.emoji-exclamation { background-position: -400px -360px; } +.emoji-expressionless { background-position: -400px -380px; } +.emoji-eye { background-position: 0 -400px; } +.emoji-eye_in_speech_bubble { background-position: -20px -400px; } +.emoji-eyeglasses { background-position: -40px -400px; } +.emoji-eyes { background-position: -60px -400px; } +.emoji-face_palm { background-position: -80px -400px; } +.emoji-face_palm_tone1 { background-position: -100px -400px; } +.emoji-face_palm_tone2 { background-position: -120px -400px; } +.emoji-face_palm_tone3 { background-position: -140px -400px; } +.emoji-face_palm_tone4 { background-position: -160px -400px; } +.emoji-face_palm_tone5 { background-position: -180px -400px; } +.emoji-factory { background-position: -200px -400px; } +.emoji-fallen_leaf { background-position: -220px -400px; } +.emoji-family { background-position: -240px -400px; } +.emoji-family_mmb { background-position: -260px -400px; } +.emoji-family_mmbb { background-position: -280px -400px; } +.emoji-family_mmg { background-position: -300px -400px; } +.emoji-family_mmgb { background-position: -320px -400px; } +.emoji-family_mmgg { background-position: -340px -400px; } +.emoji-family_mwbb { background-position: -360px -400px; } +.emoji-family_mwg { background-position: -380px -400px; } +.emoji-family_mwgb { background-position: -400px -400px; } +.emoji-family_mwgg { background-position: -420px 0; } +.emoji-family_wwb { background-position: -420px -20px; } +.emoji-family_wwbb { background-position: -420px -40px; } +.emoji-family_wwg { background-position: -420px -60px; } +.emoji-family_wwgb { background-position: -420px -80px; } +.emoji-family_wwgg { background-position: -420px -100px; } +.emoji-fast_forward { background-position: -420px -120px; } +.emoji-fax { background-position: -420px -140px; } +.emoji-fearful { background-position: -420px -160px; } +.emoji-feet { background-position: -420px -180px; } +.emoji-fencer { background-position: -420px -200px; } +.emoji-ferris_wheel { background-position: -420px -220px; } +.emoji-ferry { background-position: -420px -240px; } +.emoji-field_hockey { background-position: -420px -260px; } +.emoji-file_cabinet { background-position: -420px -280px; } +.emoji-file_folder { background-position: -420px -300px; } +.emoji-film_frames { background-position: -420px -320px; } +.emoji-fingers_crossed { background-position: -420px -340px; } +.emoji-fingers_crossed_tone1 { background-position: -420px -360px; } +.emoji-fingers_crossed_tone2 { background-position: -420px -380px; } +.emoji-fingers_crossed_tone3 { background-position: -420px -400px; } +.emoji-fingers_crossed_tone4 { background-position: 0 -420px; } +.emoji-fingers_crossed_tone5 { background-position: -20px -420px; } +.emoji-fire { background-position: -40px -420px; } +.emoji-fire_engine { background-position: -60px -420px; } +.emoji-fireworks { background-position: -80px -420px; } +.emoji-first_place { background-position: -100px -420px; } +.emoji-first_quarter_moon { background-position: -120px -420px; } +.emoji-first_quarter_moon_with_face { background-position: -140px -420px; } +.emoji-fish { background-position: -160px -420px; } +.emoji-fish_cake { background-position: -180px -420px; } +.emoji-fishing_pole_and_fish { background-position: -200px -420px; } +.emoji-fist { background-position: -220px -420px; } +.emoji-fist_tone1 { background-position: -240px -420px; } +.emoji-fist_tone2 { background-position: -260px -420px; } +.emoji-fist_tone3 { background-position: -280px -420px; } +.emoji-fist_tone4 { background-position: -300px -420px; } +.emoji-fist_tone5 { background-position: -320px -420px; } +.emoji-five { background-position: -340px -420px; } +.emoji-flag_ac { background-position: -360px -420px; } +.emoji-flag_ad { background-position: -380px -420px; } +.emoji-flag_ae { background-position: -400px -420px; } +.emoji-flag_af { background-position: -420px -420px; } +.emoji-flag_ag { background-position: -440px 0; } +.emoji-flag_ai { background-position: -440px -20px; } +.emoji-flag_al { background-position: -440px -40px; } +.emoji-flag_am { background-position: -440px -60px; } +.emoji-flag_ao { background-position: -440px -80px; } +.emoji-flag_aq { background-position: -440px -100px; } +.emoji-flag_ar { background-position: -440px -120px; } +.emoji-flag_as { background-position: -440px -140px; } +.emoji-flag_at { background-position: -440px -160px; } +.emoji-flag_au { background-position: -440px -180px; } +.emoji-flag_aw { background-position: -440px -200px; } +.emoji-flag_ax { background-position: -440px -220px; } +.emoji-flag_az { background-position: -440px -240px; } +.emoji-flag_ba { background-position: -440px -260px; } +.emoji-flag_bb { background-position: -440px -280px; } +.emoji-flag_bd { background-position: -440px -300px; } +.emoji-flag_be { background-position: -440px -320px; } +.emoji-flag_bf { background-position: -440px -340px; } +.emoji-flag_bg { background-position: -440px -360px; } +.emoji-flag_bh { background-position: -440px -380px; } +.emoji-flag_bi { background-position: -440px -400px; } +.emoji-flag_bj { background-position: -440px -420px; } +.emoji-flag_bl { background-position: 0 -440px; } +.emoji-flag_black { background-position: -20px -440px; } +.emoji-flag_bm { background-position: -40px -440px; } +.emoji-flag_bn { background-position: -60px -440px; } +.emoji-flag_bo { background-position: -80px -440px; } +.emoji-flag_bq { background-position: -100px -440px; } +.emoji-flag_br { background-position: -120px -440px; } +.emoji-flag_bs { background-position: -140px -440px; } +.emoji-flag_bt { background-position: -160px -440px; } +.emoji-flag_bv { background-position: -180px -440px; } +.emoji-flag_bw { background-position: -200px -440px; } +.emoji-flag_by { background-position: -220px -440px; } +.emoji-flag_bz { background-position: -240px -440px; } +.emoji-flag_ca { background-position: -260px -440px; } +.emoji-flag_cc { background-position: -280px -440px; } +.emoji-flag_cd { background-position: -300px -440px; } +.emoji-flag_cf { background-position: -320px -440px; } +.emoji-flag_cg { background-position: -340px -440px; } +.emoji-flag_ch { background-position: -360px -440px; } +.emoji-flag_ci { background-position: -380px -440px; } +.emoji-flag_ck { background-position: -400px -440px; } +.emoji-flag_cl { background-position: -420px -440px; } +.emoji-flag_cm { background-position: -440px -440px; } +.emoji-flag_cn { background-position: -460px 0; } +.emoji-flag_co { background-position: -460px -20px; } +.emoji-flag_cp { background-position: -460px -40px; } +.emoji-flag_cr { background-position: -460px -60px; } +.emoji-flag_cu { background-position: -460px -80px; } +.emoji-flag_cv { background-position: -460px -100px; } +.emoji-flag_cw { background-position: -460px -120px; } +.emoji-flag_cx { background-position: -460px -140px; } +.emoji-flag_cy { background-position: -460px -160px; } +.emoji-flag_cz { background-position: -460px -180px; } +.emoji-flag_de { background-position: -460px -200px; } +.emoji-flag_dg { background-position: -460px -220px; } +.emoji-flag_dj { background-position: -460px -240px; } +.emoji-flag_dk { background-position: -460px -260px; } +.emoji-flag_dm { background-position: -460px -280px; } +.emoji-flag_do { background-position: -460px -300px; } +.emoji-flag_dz { background-position: -460px -320px; } +.emoji-flag_ea { background-position: -460px -340px; } +.emoji-flag_ec { background-position: -460px -360px; } +.emoji-flag_ee { background-position: -460px -380px; } +.emoji-flag_eg { background-position: -460px -400px; } +.emoji-flag_eh { background-position: -460px -420px; } +.emoji-flag_er { background-position: -460px -440px; } +.emoji-flag_es { background-position: 0 -460px; } +.emoji-flag_et { background-position: -20px -460px; } +.emoji-flag_eu { background-position: -40px -460px; } +.emoji-flag_fi { background-position: -60px -460px; } +.emoji-flag_fj { background-position: -80px -460px; } +.emoji-flag_fk { background-position: -100px -460px; } +.emoji-flag_fm { background-position: -120px -460px; } +.emoji-flag_fo { background-position: -140px -460px; } +.emoji-flag_fr { background-position: -160px -460px; } +.emoji-flag_ga { background-position: -180px -460px; } +.emoji-flag_gb { background-position: -200px -460px; } +.emoji-flag_gd { background-position: -220px -460px; } +.emoji-flag_ge { background-position: -240px -460px; } +.emoji-flag_gf { background-position: -260px -460px; } +.emoji-flag_gg { background-position: -280px -460px; } +.emoji-flag_gh { background-position: -300px -460px; } +.emoji-flag_gi { background-position: -320px -460px; } +.emoji-flag_gl { background-position: -340px -460px; } +.emoji-flag_gm { background-position: -360px -460px; } +.emoji-flag_gn { background-position: -380px -460px; } +.emoji-flag_gp { background-position: -400px -460px; } +.emoji-flag_gq { background-position: -420px -460px; } +.emoji-flag_gr { background-position: -440px -460px; } +.emoji-flag_gs { background-position: -460px -460px; } +.emoji-flag_gt { background-position: -480px 0; } +.emoji-flag_gu { background-position: -480px -20px; } +.emoji-flag_gw { background-position: -480px -40px; } +.emoji-flag_gy { background-position: -480px -60px; } +.emoji-flag_hk { background-position: -480px -80px; } +.emoji-flag_hm { background-position: -480px -100px; } +.emoji-flag_hn { background-position: -480px -120px; } +.emoji-flag_hr { background-position: -480px -140px; } +.emoji-flag_ht { background-position: -480px -160px; } +.emoji-flag_hu { background-position: -480px -180px; } +.emoji-flag_ic { background-position: -480px -200px; } +.emoji-flag_id { background-position: -480px -220px; } +.emoji-flag_ie { background-position: -480px -240px; } +.emoji-flag_il { background-position: -480px -260px; } +.emoji-flag_im { background-position: -480px -280px; } +.emoji-flag_in { background-position: -480px -300px; } +.emoji-flag_io { background-position: -480px -320px; } +.emoji-flag_iq { background-position: -480px -340px; } +.emoji-flag_ir { background-position: -480px -360px; } +.emoji-flag_is { background-position: -480px -380px; } +.emoji-flag_it { background-position: -480px -400px; } +.emoji-flag_je { background-position: -480px -420px; } +.emoji-flag_jm { background-position: -480px -440px; } +.emoji-flag_jo { background-position: -480px -460px; } +.emoji-flag_jp { background-position: 0 -480px; } +.emoji-flag_ke { background-position: -20px -480px; } +.emoji-flag_kg { background-position: -40px -480px; } +.emoji-flag_kh { background-position: -60px -480px; } +.emoji-flag_ki { background-position: -80px -480px; } +.emoji-flag_km { background-position: -100px -480px; } +.emoji-flag_kn { background-position: -120px -480px; } +.emoji-flag_kp { background-position: -140px -480px; } +.emoji-flag_kr { background-position: -160px -480px; } +.emoji-flag_kw { background-position: -180px -480px; } +.emoji-flag_ky { background-position: -200px -480px; } +.emoji-flag_kz { background-position: -220px -480px; } +.emoji-flag_la { background-position: -240px -480px; } +.emoji-flag_lb { background-position: -260px -480px; } +.emoji-flag_lc { background-position: -280px -480px; } +.emoji-flag_li { background-position: -300px -480px; } +.emoji-flag_lk { background-position: -320px -480px; } +.emoji-flag_lr { background-position: -340px -480px; } +.emoji-flag_ls { background-position: -360px -480px; } +.emoji-flag_lt { background-position: -380px -480px; } +.emoji-flag_lu { background-position: -400px -480px; } +.emoji-flag_lv { background-position: -420px -480px; } +.emoji-flag_ly { background-position: -440px -480px; } +.emoji-flag_ma { background-position: -460px -480px; } +.emoji-flag_mc { background-position: -480px -480px; } +.emoji-flag_md { background-position: -500px 0; } +.emoji-flag_me { background-position: -500px -20px; } +.emoji-flag_mf { background-position: -500px -40px; } +.emoji-flag_mg { background-position: -500px -60px; } +.emoji-flag_mh { background-position: -500px -80px; } +.emoji-flag_mk { background-position: -500px -100px; } +.emoji-flag_ml { background-position: -500px -120px; } +.emoji-flag_mm { background-position: -500px -140px; } +.emoji-flag_mn { background-position: -500px -160px; } +.emoji-flag_mo { background-position: -500px -180px; } +.emoji-flag_mp { background-position: -500px -200px; } +.emoji-flag_mq { background-position: -500px -220px; } +.emoji-flag_mr { background-position: -500px -240px; } +.emoji-flag_ms { background-position: -500px -260px; } +.emoji-flag_mt { background-position: -500px -280px; } +.emoji-flag_mu { background-position: -500px -300px; } +.emoji-flag_mv { background-position: -500px -320px; } +.emoji-flag_mw { background-position: -500px -340px; } +.emoji-flag_mx { background-position: -500px -360px; } +.emoji-flag_my { background-position: -500px -380px; } +.emoji-flag_mz { background-position: -500px -400px; } +.emoji-flag_na { background-position: -500px -420px; } +.emoji-flag_nc { background-position: -500px -440px; } +.emoji-flag_ne { background-position: -500px -460px; } +.emoji-flag_nf { background-position: -500px -480px; } +.emoji-flag_ng { background-position: 0 -500px; } +.emoji-flag_ni { background-position: -20px -500px; } +.emoji-flag_nl { background-position: -40px -500px; } +.emoji-flag_no { background-position: -60px -500px; } +.emoji-flag_np { background-position: -80px -500px; } +.emoji-flag_nr { background-position: -100px -500px; } +.emoji-flag_nu { background-position: -120px -500px; } +.emoji-flag_nz { background-position: -140px -500px; } +.emoji-flag_om { background-position: -160px -500px; } +.emoji-flag_pa { background-position: -180px -500px; } +.emoji-flag_pe { background-position: -200px -500px; } +.emoji-flag_pf { background-position: -220px -500px; } +.emoji-flag_pg { background-position: -240px -500px; } +.emoji-flag_ph { background-position: -260px -500px; } +.emoji-flag_pk { background-position: -280px -500px; } +.emoji-flag_pl { background-position: -300px -500px; } +.emoji-flag_pm { background-position: -320px -500px; } +.emoji-flag_pn { background-position: -340px -500px; } +.emoji-flag_pr { background-position: -360px -500px; } +.emoji-flag_ps { background-position: -380px -500px; } +.emoji-flag_pt { background-position: -400px -500px; } +.emoji-flag_pw { background-position: -420px -500px; } +.emoji-flag_py { background-position: -440px -500px; } +.emoji-flag_qa { background-position: -460px -500px; } +.emoji-flag_re { background-position: -480px -500px; } +.emoji-flag_ro { background-position: -500px -500px; } +.emoji-flag_rs { background-position: -520px 0; } +.emoji-flag_ru { background-position: -520px -20px; } +.emoji-flag_rw { background-position: -520px -40px; } +.emoji-flag_sa { background-position: -520px -60px; } +.emoji-flag_sb { background-position: -520px -80px; } +.emoji-flag_sc { background-position: -520px -100px; } +.emoji-flag_sd { background-position: -520px -120px; } +.emoji-flag_se { background-position: -520px -140px; } +.emoji-flag_sg { background-position: -520px -160px; } +.emoji-flag_sh { background-position: -520px -180px; } +.emoji-flag_si { background-position: -520px -200px; } +.emoji-flag_sj { background-position: -520px -220px; } +.emoji-flag_sk { background-position: -520px -240px; } +.emoji-flag_sl { background-position: -520px -260px; } +.emoji-flag_sm { background-position: -520px -280px; } +.emoji-flag_sn { background-position: -520px -300px; } +.emoji-flag_so { background-position: -520px -320px; } +.emoji-flag_sr { background-position: -520px -340px; } +.emoji-flag_ss { background-position: -520px -360px; } +.emoji-flag_st { background-position: -520px -380px; } +.emoji-flag_sv { background-position: -520px -400px; } +.emoji-flag_sx { background-position: -520px -420px; } +.emoji-flag_sy { background-position: -520px -440px; } +.emoji-flag_sz { background-position: -520px -460px; } +.emoji-flag_ta { background-position: -520px -480px; } +.emoji-flag_tc { background-position: -520px -500px; } +.emoji-flag_td { background-position: 0 -520px; } +.emoji-flag_tf { background-position: -20px -520px; } +.emoji-flag_tg { background-position: -40px -520px; } +.emoji-flag_th { background-position: -60px -520px; } +.emoji-flag_tj { background-position: -80px -520px; } +.emoji-flag_tk { background-position: -100px -520px; } +.emoji-flag_tl { background-position: -120px -520px; } +.emoji-flag_tm { background-position: -140px -520px; } +.emoji-flag_tn { background-position: -160px -520px; } +.emoji-flag_to { background-position: -180px -520px; } +.emoji-flag_tr { background-position: -200px -520px; } +.emoji-flag_tt { background-position: -220px -520px; } +.emoji-flag_tv { background-position: -240px -520px; } +.emoji-flag_tw { background-position: -260px -520px; } +.emoji-flag_tz { background-position: -280px -520px; } +.emoji-flag_ua { background-position: -300px -520px; } +.emoji-flag_ug { background-position: -320px -520px; } +.emoji-flag_um { background-position: -340px -520px; } +.emoji-flag_us { background-position: -360px -520px; } +.emoji-flag_uy { background-position: -380px -520px; } +.emoji-flag_uz { background-position: -400px -520px; } +.emoji-flag_va { background-position: -420px -520px; } +.emoji-flag_vc { background-position: -440px -520px; } +.emoji-flag_ve { background-position: -460px -520px; } +.emoji-flag_vg { background-position: -480px -520px; } +.emoji-flag_vi { background-position: -500px -520px; } +.emoji-flag_vn { background-position: -520px -520px; } +.emoji-flag_vu { background-position: -540px 0; } +.emoji-flag_wf { background-position: -540px -20px; } +.emoji-flag_white { background-position: -540px -40px; } +.emoji-flag_ws { background-position: -540px -60px; } +.emoji-flag_xk { background-position: -540px -80px; } +.emoji-flag_ye { background-position: -540px -100px; } +.emoji-flag_yt { background-position: -540px -120px; } +.emoji-flag_za { background-position: -540px -140px; } +.emoji-flag_zm { background-position: -540px -160px; } +.emoji-flag_zw { background-position: -540px -180px; } +.emoji-flags { background-position: -540px -200px; } +.emoji-flashlight { background-position: -540px -220px; } +.emoji-fleur-de-lis { background-position: -540px -240px; } +.emoji-floppy_disk { background-position: -540px -260px; } +.emoji-flower_playing_cards { background-position: -540px -280px; } +.emoji-flushed { background-position: -540px -300px; } +.emoji-fog { background-position: -540px -320px; } +.emoji-foggy { background-position: -540px -340px; } +.emoji-football { background-position: -540px -360px; } +.emoji-footprints { background-position: -540px -380px; } +.emoji-fork_and_knife { background-position: -540px -400px; } +.emoji-fork_knife_plate { background-position: -540px -420px; } +.emoji-fountain { background-position: -540px -440px; } +.emoji-four { background-position: -540px -460px; } +.emoji-four_leaf_clover { background-position: -540px -480px; } +.emoji-fox { background-position: -540px -500px; } +.emoji-frame_photo { background-position: -540px -520px; } +.emoji-free { background-position: 0 -540px; } +.emoji-french_bread { background-position: -20px -540px; } +.emoji-fried_shrimp { background-position: -40px -540px; } +.emoji-fries { background-position: -60px -540px; } +.emoji-frog { background-position: -80px -540px; } +.emoji-frowning { background-position: -100px -540px; } +.emoji-frowning2 { background-position: -120px -540px; } +.emoji-fuelpump { background-position: -140px -540px; } +.emoji-full_moon { background-position: -160px -540px; } +.emoji-full_moon_with_face { background-position: -180px -540px; } +.emoji-game_die { background-position: -200px -540px; } +.emoji-gear { background-position: -220px -540px; } +.emoji-gem { background-position: -240px -540px; } +.emoji-gemini { background-position: -260px -540px; } +.emoji-ghost { background-position: -280px -540px; } +.emoji-gift { background-position: -300px -540px; } +.emoji-gift_heart { background-position: -320px -540px; } +.emoji-girl { background-position: -340px -540px; } +.emoji-girl_tone1 { background-position: -360px -540px; } +.emoji-girl_tone2 { background-position: -380px -540px; } +.emoji-girl_tone3 { background-position: -400px -540px; } +.emoji-girl_tone4 { background-position: -420px -540px; } +.emoji-girl_tone5 { background-position: -440px -540px; } +.emoji-globe_with_meridians { background-position: -460px -540px; } +.emoji-goal { background-position: -480px -540px; } +.emoji-goat { background-position: -500px -540px; } +.emoji-golf { background-position: -520px -540px; } +.emoji-golfer { background-position: -540px -540px; } +.emoji-gorilla { background-position: -560px 0; } +.emoji-grapes { background-position: -560px -20px; } +.emoji-green_apple { background-position: -560px -40px; } +.emoji-green_book { background-position: -560px -60px; } +.emoji-green_heart { background-position: -560px -80px; } +.emoji-grey_exclamation { background-position: -560px -100px; } +.emoji-grey_question { background-position: -560px -120px; } +.emoji-grimacing { background-position: -560px -140px; } +.emoji-grin { background-position: -560px -160px; } +.emoji-grinning { background-position: -560px -180px; } +.emoji-guardsman { background-position: -560px -200px; } +.emoji-guardsman_tone1 { background-position: -560px -220px; } +.emoji-guardsman_tone2 { background-position: -560px -240px; } +.emoji-guardsman_tone3 { background-position: -560px -260px; } +.emoji-guardsman_tone4 { background-position: -560px -280px; } +.emoji-guardsman_tone5 { background-position: -560px -300px; } +.emoji-guitar { background-position: -560px -320px; } +.emoji-gun { background-position: -560px -340px; } +.emoji-haircut { background-position: -560px -360px; } +.emoji-haircut_tone1 { background-position: -560px -380px; } +.emoji-haircut_tone2 { background-position: -560px -400px; } +.emoji-haircut_tone3 { background-position: -560px -420px; } +.emoji-haircut_tone4 { background-position: -560px -440px; } +.emoji-haircut_tone5 { background-position: -560px -460px; } +.emoji-hamburger { background-position: -560px -480px; } +.emoji-hammer { background-position: -560px -500px; } +.emoji-hammer_pick { background-position: -560px -520px; } +.emoji-hamster { background-position: -560px -540px; } +.emoji-hand_splayed { background-position: 0 -560px; } +.emoji-hand_splayed_tone1 { background-position: -20px -560px; } +.emoji-hand_splayed_tone2 { background-position: -40px -560px; } +.emoji-hand_splayed_tone3 { background-position: -60px -560px; } +.emoji-hand_splayed_tone4 { background-position: -80px -560px; } +.emoji-hand_splayed_tone5 { background-position: -100px -560px; } +.emoji-handbag { background-position: -120px -560px; } +.emoji-handball { background-position: -140px -560px; } +.emoji-handball_tone1 { background-position: -160px -560px; } +.emoji-handball_tone2 { background-position: -180px -560px; } +.emoji-handball_tone3 { background-position: -200px -560px; } +.emoji-handball_tone4 { background-position: -220px -560px; } +.emoji-handball_tone5 { background-position: -240px -560px; } +.emoji-handshake { background-position: -260px -560px; } +.emoji-handshake_tone1 { background-position: -280px -560px; } +.emoji-handshake_tone2 { background-position: -300px -560px; } +.emoji-handshake_tone3 { background-position: -320px -560px; } +.emoji-handshake_tone4 { background-position: -340px -560px; } +.emoji-handshake_tone5 { background-position: -360px -560px; } +.emoji-hash { background-position: -380px -560px; } +.emoji-hatched_chick { background-position: -400px -560px; } +.emoji-hatching_chick { background-position: -420px -560px; } +.emoji-head_bandage { background-position: -440px -560px; } +.emoji-headphones { background-position: -460px -560px; } +.emoji-hear_no_evil { background-position: -480px -560px; } +.emoji-heart { background-position: -500px -560px; } +.emoji-heart_decoration { background-position: -520px -560px; } +.emoji-heart_exclamation { background-position: -540px -560px; } +.emoji-heart_eyes { background-position: -560px -560px; } +.emoji-heart_eyes_cat { background-position: -580px 0; } +.emoji-heartbeat { background-position: -580px -20px; } +.emoji-heartpulse { background-position: -580px -40px; } +.emoji-hearts { background-position: -580px -60px; } +.emoji-heavy_check_mark { background-position: -580px -80px; } +.emoji-heavy_division_sign { background-position: -580px -100px; } +.emoji-heavy_dollar_sign { background-position: -580px -120px; } +.emoji-heavy_minus_sign { background-position: -580px -140px; } +.emoji-heavy_multiplication_x { background-position: -580px -160px; } +.emoji-heavy_plus_sign { background-position: -580px -180px; } +.emoji-helicopter { background-position: -580px -200px; } +.emoji-helmet_with_cross { background-position: -580px -220px; } +.emoji-herb { background-position: -580px -240px; } +.emoji-hibiscus { background-position: -580px -260px; } +.emoji-high_brightness { background-position: -580px -280px; } +.emoji-high_heel { background-position: -580px -300px; } +.emoji-hockey { background-position: -580px -320px; } +.emoji-hole { background-position: -580px -340px; } +.emoji-homes { background-position: -580px -360px; } +.emoji-honey_pot { background-position: -580px -380px; } +.emoji-horse { background-position: -580px -400px; } +.emoji-horse_racing { background-position: -580px -420px; } +.emoji-horse_racing_tone1 { background-position: -580px -440px; } +.emoji-horse_racing_tone2 { background-position: -580px -460px; } +.emoji-horse_racing_tone3 { background-position: -580px -480px; } +.emoji-horse_racing_tone4 { background-position: -580px -500px; } +.emoji-horse_racing_tone5 { background-position: -580px -520px; } +.emoji-hospital { background-position: -580px -540px; } +.emoji-hot_pepper { background-position: -580px -560px; } +.emoji-hotdog { background-position: 0 -580px; } +.emoji-hotel { background-position: -20px -580px; } +.emoji-hotsprings { background-position: -40px -580px; } +.emoji-hourglass { background-position: -60px -580px; } +.emoji-hourglass_flowing_sand { background-position: -80px -580px; } +.emoji-house { background-position: -100px -580px; } +.emoji-house_abandoned { background-position: -120px -580px; } +.emoji-house_with_garden { background-position: -140px -580px; } +.emoji-hugging { background-position: -160px -580px; } +.emoji-hushed { background-position: -180px -580px; } +.emoji-ice_cream { background-position: -200px -580px; } +.emoji-ice_skate { background-position: -220px -580px; } +.emoji-icecream { background-position: -240px -580px; } +.emoji-id { background-position: -260px -580px; } +.emoji-ideograph_advantage { background-position: -280px -580px; } +.emoji-imp { background-position: -300px -580px; } +.emoji-inbox_tray { background-position: -320px -580px; } +.emoji-incoming_envelope { background-position: -340px -580px; } +.emoji-information_desk_person { background-position: -360px -580px; } +.emoji-information_desk_person_tone1 { background-position: -380px -580px; } +.emoji-information_desk_person_tone2 { background-position: -400px -580px; } +.emoji-information_desk_person_tone3 { background-position: -420px -580px; } +.emoji-information_desk_person_tone4 { background-position: -440px -580px; } +.emoji-information_desk_person_tone5 { background-position: -460px -580px; } +.emoji-information_source { background-position: -480px -580px; } +.emoji-innocent { background-position: -500px -580px; } +.emoji-interrobang { background-position: -520px -580px; } +.emoji-iphone { background-position: -540px -580px; } +.emoji-island { background-position: -560px -580px; } +.emoji-izakaya_lantern { background-position: -580px -580px; } +.emoji-jack_o_lantern { background-position: -600px 0; } +.emoji-japan { background-position: -600px -20px; } +.emoji-japanese_castle { background-position: -600px -40px; } +.emoji-japanese_goblin { background-position: -600px -60px; } +.emoji-japanese_ogre { background-position: -600px -80px; } +.emoji-jeans { background-position: -600px -100px; } +.emoji-joy { background-position: -600px -120px; } +.emoji-joy_cat { background-position: -600px -140px; } +.emoji-joystick { background-position: -600px -160px; } +.emoji-juggling { background-position: -600px -180px; } +.emoji-juggling_tone1 { background-position: -600px -200px; } +.emoji-juggling_tone2 { background-position: -600px -220px; } +.emoji-juggling_tone3 { background-position: -600px -240px; } +.emoji-juggling_tone4 { background-position: -600px -260px; } +.emoji-juggling_tone5 { background-position: -600px -280px; } +.emoji-kaaba { background-position: -600px -300px; } +.emoji-key { background-position: -600px -320px; } +.emoji-key2 { background-position: -600px -340px; } +.emoji-keyboard { background-position: -600px -360px; } +.emoji-kimono { background-position: -600px -380px; } +.emoji-kiss { background-position: -600px -400px; } +.emoji-kiss_mm { background-position: -600px -420px; } +.emoji-kiss_ww { background-position: -600px -440px; } +.emoji-kissing { background-position: -600px -460px; } +.emoji-kissing_cat { background-position: -600px -480px; } +.emoji-kissing_closed_eyes { background-position: -600px -500px; } +.emoji-kissing_heart { background-position: -600px -520px; } +.emoji-kissing_smiling_eyes { background-position: -600px -540px; } +.emoji-kiwi { background-position: -600px -560px; } +.emoji-knife { background-position: -600px -580px; } +.emoji-koala { background-position: 0 -600px; } +.emoji-koko { background-position: -20px -600px; } +.emoji-label { background-position: -40px -600px; } +.emoji-large_blue_circle { background-position: -60px -600px; } +.emoji-large_blue_diamond { background-position: -80px -600px; } +.emoji-large_orange_diamond { background-position: -100px -600px; } +.emoji-last_quarter_moon { background-position: -120px -600px; } +.emoji-last_quarter_moon_with_face { background-position: -140px -600px; } +.emoji-laughing { background-position: -160px -600px; } +.emoji-leaves { background-position: -180px -600px; } +.emoji-ledger { background-position: -200px -600px; } +.emoji-left_facing_fist { background-position: -220px -600px; } +.emoji-left_facing_fist_tone1 { background-position: -240px -600px; } +.emoji-left_facing_fist_tone2 { background-position: -260px -600px; } +.emoji-left_facing_fist_tone3 { background-position: -280px -600px; } +.emoji-left_facing_fist_tone4 { background-position: -300px -600px; } +.emoji-left_facing_fist_tone5 { background-position: -320px -600px; } +.emoji-left_luggage { background-position: -340px -600px; } +.emoji-left_right_arrow { background-position: -360px -600px; } +.emoji-leftwards_arrow_with_hook { background-position: -380px -600px; } +.emoji-lemon { background-position: -400px -600px; } +.emoji-leo { background-position: -420px -600px; } +.emoji-leopard { background-position: -440px -600px; } +.emoji-level_slider { background-position: -460px -600px; } +.emoji-levitate { background-position: -480px -600px; } +.emoji-libra { background-position: -500px -600px; } +.emoji-lifter { background-position: -520px -600px; } +.emoji-lifter_tone1 { background-position: -540px -600px; } +.emoji-lifter_tone2 { background-position: -560px -600px; } +.emoji-lifter_tone3 { background-position: -580px -600px; } +.emoji-lifter_tone4 { background-position: -600px -600px; } +.emoji-lifter_tone5 { background-position: -620px 0; } +.emoji-light_rail { background-position: -620px -20px; } +.emoji-link { background-position: -620px -40px; } +.emoji-lion_face { background-position: -620px -60px; } +.emoji-lips { background-position: -620px -80px; } +.emoji-lipstick { background-position: -620px -100px; } +.emoji-lizard { background-position: -620px -120px; } +.emoji-lock { background-position: -620px -140px; } +.emoji-lock_with_ink_pen { background-position: -620px -160px; } +.emoji-lollipop { background-position: -620px -180px; } +.emoji-loop { background-position: -620px -200px; } +.emoji-loud_sound { background-position: -620px -220px; } +.emoji-loudspeaker { background-position: -620px -240px; } +.emoji-love_hotel { background-position: -620px -260px; } +.emoji-love_letter { background-position: -620px -280px; } +.emoji-low_brightness { background-position: -620px -300px; } +.emoji-lying_face { background-position: -620px -320px; } +.emoji-m { background-position: -620px -340px; } +.emoji-mag { background-position: -620px -360px; } +.emoji-mag_right { background-position: -620px -380px; } +.emoji-mahjong { background-position: -620px -400px; } +.emoji-mailbox { background-position: -620px -420px; } +.emoji-mailbox_closed { background-position: -620px -440px; } +.emoji-mailbox_with_mail { background-position: -620px -460px; } +.emoji-mailbox_with_no_mail { background-position: -620px -480px; } +.emoji-man { background-position: -620px -500px; } +.emoji-man_dancing { background-position: -620px -520px; } +.emoji-man_dancing_tone1 { background-position: -620px -540px; } +.emoji-man_dancing_tone2 { background-position: -620px -560px; } +.emoji-man_dancing_tone3 { background-position: -620px -580px; } +.emoji-man_dancing_tone4 { background-position: -620px -600px; } +.emoji-man_dancing_tone5 { background-position: 0 -620px; } +.emoji-man_in_tuxedo { background-position: -20px -620px; } +.emoji-man_in_tuxedo_tone1 { background-position: -40px -620px; } +.emoji-man_in_tuxedo_tone2 { background-position: -60px -620px; } +.emoji-man_in_tuxedo_tone3 { background-position: -80px -620px; } +.emoji-man_in_tuxedo_tone4 { background-position: -100px -620px; } +.emoji-man_in_tuxedo_tone5 { background-position: -120px -620px; } +.emoji-man_tone1 { background-position: -140px -620px; } +.emoji-man_tone2 { background-position: -160px -620px; } +.emoji-man_tone3 { background-position: -180px -620px; } +.emoji-man_tone4 { background-position: -200px -620px; } +.emoji-man_tone5 { background-position: -220px -620px; } +.emoji-man_with_gua_pi_mao { background-position: -240px -620px; } +.emoji-man_with_gua_pi_mao_tone1 { background-position: -260px -620px; } +.emoji-man_with_gua_pi_mao_tone2 { background-position: -280px -620px; } +.emoji-man_with_gua_pi_mao_tone3 { background-position: -300px -620px; } +.emoji-man_with_gua_pi_mao_tone4 { background-position: -320px -620px; } +.emoji-man_with_gua_pi_mao_tone5 { background-position: -340px -620px; } +.emoji-man_with_turban { background-position: -360px -620px; } +.emoji-man_with_turban_tone1 { background-position: -380px -620px; } +.emoji-man_with_turban_tone2 { background-position: -400px -620px; } +.emoji-man_with_turban_tone3 { background-position: -420px -620px; } +.emoji-man_with_turban_tone4 { background-position: -440px -620px; } +.emoji-man_with_turban_tone5 { background-position: -460px -620px; } +.emoji-mans_shoe { background-position: -480px -620px; } +.emoji-map { background-position: -500px -620px; } +.emoji-maple_leaf { background-position: -520px -620px; } +.emoji-martial_arts_uniform { background-position: -540px -620px; } +.emoji-mask { background-position: -560px -620px; } +.emoji-massage { background-position: -580px -620px; } +.emoji-massage_tone1 { background-position: -600px -620px; } +.emoji-massage_tone2 { background-position: -620px -620px; } +.emoji-massage_tone3 { background-position: -640px 0; } +.emoji-massage_tone4 { background-position: -640px -20px; } +.emoji-massage_tone5 { background-position: -640px -40px; } +.emoji-meat_on_bone { background-position: -640px -60px; } +.emoji-medal { background-position: -640px -80px; } +.emoji-mega { background-position: -640px -100px; } +.emoji-melon { background-position: -640px -120px; } +.emoji-menorah { background-position: -640px -140px; } +.emoji-mens { background-position: -640px -160px; } +.emoji-metal { background-position: -640px -180px; } +.emoji-metal_tone1 { background-position: -640px -200px; } +.emoji-metal_tone2 { background-position: -640px -220px; } +.emoji-metal_tone3 { background-position: -640px -240px; } +.emoji-metal_tone4 { background-position: -640px -260px; } +.emoji-metal_tone5 { background-position: -640px -280px; } +.emoji-metro { background-position: -640px -300px; } +.emoji-microphone { background-position: -640px -320px; } +.emoji-microphone2 { background-position: -640px -340px; } +.emoji-microscope { background-position: -640px -360px; } +.emoji-middle_finger { background-position: -640px -380px; } +.emoji-middle_finger_tone1 { background-position: -640px -400px; } +.emoji-middle_finger_tone2 { background-position: -640px -420px; } +.emoji-middle_finger_tone3 { background-position: -640px -440px; } +.emoji-middle_finger_tone4 { background-position: -640px -460px; } +.emoji-middle_finger_tone5 { background-position: -640px -480px; } +.emoji-military_medal { background-position: -640px -500px; } +.emoji-milk { background-position: -640px -520px; } +.emoji-milky_way { background-position: -640px -540px; } +.emoji-minibus { background-position: -640px -560px; } +.emoji-minidisc { background-position: -640px -580px; } +.emoji-mobile_phone_off { background-position: -640px -600px; } +.emoji-money_mouth { background-position: -640px -620px; } +.emoji-money_with_wings { background-position: 0 -640px; } +.emoji-moneybag { background-position: -20px -640px; } +.emoji-monkey { background-position: -40px -640px; } +.emoji-monkey_face { background-position: -60px -640px; } +.emoji-monorail { background-position: -80px -640px; } +.emoji-mortar_board { background-position: -100px -640px; } +.emoji-mosque { background-position: -120px -640px; } +.emoji-motor_scooter { background-position: -140px -640px; } +.emoji-motorboat { background-position: -160px -640px; } +.emoji-motorcycle { background-position: -180px -640px; } +.emoji-motorway { background-position: -200px -640px; } +.emoji-mount_fuji { background-position: -220px -640px; } +.emoji-mountain { background-position: -240px -640px; } +.emoji-mountain_bicyclist { background-position: -260px -640px; } +.emoji-mountain_bicyclist_tone1 { background-position: -280px -640px; } +.emoji-mountain_bicyclist_tone2 { background-position: -300px -640px; } +.emoji-mountain_bicyclist_tone3 { background-position: -320px -640px; } +.emoji-mountain_bicyclist_tone4 { background-position: -340px -640px; } +.emoji-mountain_bicyclist_tone5 { background-position: -360px -640px; } +.emoji-mountain_cableway { background-position: -380px -640px; } +.emoji-mountain_railway { background-position: -400px -640px; } +.emoji-mountain_snow { background-position: -420px -640px; } +.emoji-mouse { background-position: -440px -640px; } +.emoji-mouse2 { background-position: -460px -640px; } +.emoji-mouse_three_button { background-position: -480px -640px; } +.emoji-movie_camera { background-position: -500px -640px; } +.emoji-moyai { background-position: -520px -640px; } +.emoji-mrs_claus { background-position: -540px -640px; } +.emoji-mrs_claus_tone1 { background-position: -560px -640px; } +.emoji-mrs_claus_tone2 { background-position: -580px -640px; } +.emoji-mrs_claus_tone3 { background-position: -600px -640px; } +.emoji-mrs_claus_tone4 { background-position: -620px -640px; } +.emoji-mrs_claus_tone5 { background-position: -640px -640px; } +.emoji-muscle { background-position: -660px 0; } +.emoji-muscle_tone1 { background-position: -660px -20px; } +.emoji-muscle_tone2 { background-position: -660px -40px; } +.emoji-muscle_tone3 { background-position: -660px -60px; } +.emoji-muscle_tone4 { background-position: -660px -80px; } +.emoji-muscle_tone5 { background-position: -660px -100px; } +.emoji-mushroom { background-position: -660px -120px; } +.emoji-musical_keyboard { background-position: -660px -140px; } +.emoji-musical_note { background-position: -660px -160px; } +.emoji-musical_score { background-position: -660px -180px; } +.emoji-mute { background-position: -660px -200px; } +.emoji-nail_care { background-position: -660px -220px; } +.emoji-nail_care_tone1 { background-position: -660px -240px; } +.emoji-nail_care_tone2 { background-position: -660px -260px; } +.emoji-nail_care_tone3 { background-position: -660px -280px; } +.emoji-nail_care_tone4 { background-position: -660px -300px; } +.emoji-nail_care_tone5 { background-position: -660px -320px; } +.emoji-name_badge { background-position: -660px -340px; } +.emoji-nauseated_face { background-position: -660px -360px; } +.emoji-necktie { background-position: -660px -380px; } +.emoji-negative_squared_cross_mark { background-position: -660px -400px; } +.emoji-nerd { background-position: -660px -420px; } +.emoji-neutral_face { background-position: -660px -440px; } +.emoji-new { background-position: -660px -460px; } +.emoji-new_moon { background-position: -660px -480px; } +.emoji-new_moon_with_face { background-position: -660px -500px; } +.emoji-newspaper { background-position: -660px -520px; } +.emoji-newspaper2 { background-position: -660px -540px; } +.emoji-ng { background-position: -660px -560px; } +.emoji-night_with_stars { background-position: -660px -580px; } +.emoji-nine { background-position: -660px -600px; } +.emoji-no_bell { background-position: -660px -620px; } +.emoji-no_bicycles { background-position: -660px -640px; } +.emoji-no_entry { background-position: 0 -660px; } +.emoji-no_entry_sign { background-position: -20px -660px; } +.emoji-no_good { background-position: -40px -660px; } +.emoji-no_good_tone1 { background-position: -60px -660px; } +.emoji-no_good_tone2 { background-position: -80px -660px; } +.emoji-no_good_tone3 { background-position: -100px -660px; } +.emoji-no_good_tone4 { background-position: -120px -660px; } +.emoji-no_good_tone5 { background-position: -140px -660px; } +.emoji-no_mobile_phones { background-position: -160px -660px; } +.emoji-no_mouth { background-position: -180px -660px; } +.emoji-no_pedestrians { background-position: -200px -660px; } +.emoji-no_smoking { background-position: -220px -660px; } +.emoji-non-potable_water { background-position: -240px -660px; } +.emoji-nose { background-position: -260px -660px; } +.emoji-nose_tone1 { background-position: -280px -660px; } +.emoji-nose_tone2 { background-position: -300px -660px; } +.emoji-nose_tone3 { background-position: -320px -660px; } +.emoji-nose_tone4 { background-position: -340px -660px; } +.emoji-nose_tone5 { background-position: -360px -660px; } +.emoji-notebook { background-position: -380px -660px; } +.emoji-notebook_with_decorative_cover { background-position: -400px -660px; } +.emoji-notepad_spiral { background-position: -420px -660px; } +.emoji-notes { background-position: -440px -660px; } +.emoji-nut_and_bolt { background-position: -460px -660px; } +.emoji-o { background-position: -480px -660px; } +.emoji-o2 { background-position: -500px -660px; } +.emoji-ocean { background-position: -520px -660px; } +.emoji-octagonal_sign { background-position: -540px -660px; } +.emoji-octopus { background-position: -560px -660px; } +.emoji-oden { background-position: -580px -660px; } +.emoji-office { background-position: -600px -660px; } +.emoji-oil { background-position: -620px -660px; } +.emoji-ok { background-position: -640px -660px; } +.emoji-ok_hand { background-position: -660px -660px; } +.emoji-ok_hand_tone1 { background-position: -680px 0; } +.emoji-ok_hand_tone2 { background-position: -680px -20px; } +.emoji-ok_hand_tone3 { background-position: -680px -40px; } +.emoji-ok_hand_tone4 { background-position: -680px -60px; } +.emoji-ok_hand_tone5 { background-position: -680px -80px; } +.emoji-ok_woman { background-position: -680px -100px; } +.emoji-ok_woman_tone1 { background-position: -680px -120px; } +.emoji-ok_woman_tone2 { background-position: -680px -140px; } +.emoji-ok_woman_tone3 { background-position: -680px -160px; } +.emoji-ok_woman_tone4 { background-position: -680px -180px; } +.emoji-ok_woman_tone5 { background-position: -680px -200px; } +.emoji-older_man { background-position: -680px -220px; } +.emoji-older_man_tone1 { background-position: -680px -240px; } +.emoji-older_man_tone2 { background-position: -680px -260px; } +.emoji-older_man_tone3 { background-position: -680px -280px; } +.emoji-older_man_tone4 { background-position: -680px -300px; } +.emoji-older_man_tone5 { background-position: -680px -320px; } +.emoji-older_woman { background-position: -680px -340px; } +.emoji-older_woman_tone1 { background-position: -680px -360px; } +.emoji-older_woman_tone2 { background-position: -680px -380px; } +.emoji-older_woman_tone3 { background-position: -680px -400px; } +.emoji-older_woman_tone4 { background-position: -680px -420px; } +.emoji-older_woman_tone5 { background-position: -680px -440px; } +.emoji-om_symbol { background-position: -680px -460px; } +.emoji-on { background-position: -680px -480px; } +.emoji-oncoming_automobile { background-position: -680px -500px; } +.emoji-oncoming_bus { background-position: -680px -520px; } +.emoji-oncoming_police_car { background-position: -680px -540px; } +.emoji-oncoming_taxi { background-position: -680px -560px; } +.emoji-one { background-position: -680px -580px; } +.emoji-open_file_folder { background-position: -680px -600px; } +.emoji-open_hands { background-position: -680px -620px; } +.emoji-open_hands_tone1 { background-position: -680px -640px; } +.emoji-open_hands_tone2 { background-position: -680px -660px; } +.emoji-open_hands_tone3 { background-position: 0 -680px; } +.emoji-open_hands_tone4 { background-position: -20px -680px; } +.emoji-open_hands_tone5 { background-position: -40px -680px; } +.emoji-open_mouth { background-position: -60px -680px; } +.emoji-ophiuchus { background-position: -80px -680px; } +.emoji-orange_book { background-position: -100px -680px; } +.emoji-orthodox_cross { background-position: -120px -680px; } +.emoji-outbox_tray { background-position: -140px -680px; } +.emoji-owl { background-position: -160px -680px; } +.emoji-ox { background-position: -180px -680px; } +.emoji-package { background-position: -200px -680px; } +.emoji-page_facing_up { background-position: -220px -680px; } +.emoji-page_with_curl { background-position: -240px -680px; } +.emoji-pager { background-position: -260px -680px; } +.emoji-paintbrush { background-position: -280px -680px; } +.emoji-palm_tree { background-position: -300px -680px; } +.emoji-pancakes { background-position: -320px -680px; } +.emoji-panda_face { background-position: -340px -680px; } +.emoji-paperclip { background-position: -360px -680px; } +.emoji-paperclips { background-position: -380px -680px; } +.emoji-park { background-position: -400px -680px; } +.emoji-parking { background-position: -420px -680px; } +.emoji-part_alternation_mark { background-position: -440px -680px; } +.emoji-partly_sunny { background-position: -460px -680px; } +.emoji-passport_control { background-position: -480px -680px; } +.emoji-pause_button { background-position: -500px -680px; } +.emoji-peace { background-position: -520px -680px; } +.emoji-peach { background-position: -540px -680px; } +.emoji-peanuts { background-position: -560px -680px; } +.emoji-pear { background-position: -580px -680px; } +.emoji-pen_ballpoint { background-position: -600px -680px; } +.emoji-pen_fountain { background-position: -620px -680px; } +.emoji-pencil { background-position: -640px -680px; } +.emoji-pencil2 { background-position: -660px -680px; } +.emoji-penguin { background-position: -680px -680px; } +.emoji-pensive { background-position: -700px 0; } +.emoji-performing_arts { background-position: -700px -20px; } +.emoji-persevere { background-position: -700px -40px; } +.emoji-person_frowning { background-position: -700px -60px; } +.emoji-person_frowning_tone1 { background-position: -700px -80px; } +.emoji-person_frowning_tone2 { background-position: -700px -100px; } +.emoji-person_frowning_tone3 { background-position: -700px -120px; } +.emoji-person_frowning_tone4 { background-position: -700px -140px; } +.emoji-person_frowning_tone5 { background-position: -700px -160px; } +.emoji-person_with_blond_hair { background-position: -700px -180px; } +.emoji-person_with_blond_hair_tone1 { background-position: -700px -200px; } +.emoji-person_with_blond_hair_tone2 { background-position: -700px -220px; } +.emoji-person_with_blond_hair_tone3 { background-position: -700px -240px; } +.emoji-person_with_blond_hair_tone4 { background-position: -700px -260px; } +.emoji-person_with_blond_hair_tone5 { background-position: -700px -280px; } +.emoji-person_with_pouting_face { background-position: -700px -300px; } +.emoji-person_with_pouting_face_tone1 { background-position: -700px -320px; } +.emoji-person_with_pouting_face_tone2 { background-position: -700px -340px; } +.emoji-person_with_pouting_face_tone3 { background-position: -700px -360px; } +.emoji-person_with_pouting_face_tone4 { background-position: -700px -380px; } +.emoji-person_with_pouting_face_tone5 { background-position: -700px -400px; } +.emoji-pick { background-position: -700px -420px; } +.emoji-pig { background-position: -700px -440px; } +.emoji-pig2 { background-position: -700px -460px; } +.emoji-pig_nose { background-position: -700px -480px; } +.emoji-pill { background-position: -700px -500px; } +.emoji-pineapple { background-position: -700px -520px; } +.emoji-ping_pong { background-position: -700px -540px; } +.emoji-pisces { background-position: -700px -560px; } +.emoji-pizza { background-position: -700px -580px; } +.emoji-place_of_worship { background-position: -700px -600px; } +.emoji-play_pause { background-position: -700px -620px; } +.emoji-point_down { background-position: -700px -640px; } +.emoji-point_down_tone1 { background-position: -700px -660px; } +.emoji-point_down_tone2 { background-position: -700px -680px; } +.emoji-point_down_tone3 { background-position: 0 -700px; } +.emoji-point_down_tone4 { background-position: -20px -700px; } +.emoji-point_down_tone5 { background-position: -40px -700px; } +.emoji-point_left { background-position: -60px -700px; } +.emoji-point_left_tone1 { background-position: -80px -700px; } +.emoji-point_left_tone2 { background-position: -100px -700px; } +.emoji-point_left_tone3 { background-position: -120px -700px; } +.emoji-point_left_tone4 { background-position: -140px -700px; } +.emoji-point_left_tone5 { background-position: -160px -700px; } +.emoji-point_right { background-position: -180px -700px; } +.emoji-point_right_tone1 { background-position: -200px -700px; } +.emoji-point_right_tone2 { background-position: -220px -700px; } +.emoji-point_right_tone3 { background-position: -240px -700px; } +.emoji-point_right_tone4 { background-position: -260px -700px; } +.emoji-point_right_tone5 { background-position: -280px -700px; } +.emoji-point_up { background-position: -300px -700px; } +.emoji-point_up_2 { background-position: -320px -700px; } +.emoji-point_up_2_tone1 { background-position: -340px -700px; } +.emoji-point_up_2_tone2 { background-position: -360px -700px; } +.emoji-point_up_2_tone3 { background-position: -380px -700px; } +.emoji-point_up_2_tone4 { background-position: -400px -700px; } +.emoji-point_up_2_tone5 { background-position: -420px -700px; } +.emoji-point_up_tone1 { background-position: -440px -700px; } +.emoji-point_up_tone2 { background-position: -460px -700px; } +.emoji-point_up_tone3 { background-position: -480px -700px; } +.emoji-point_up_tone4 { background-position: -500px -700px; } +.emoji-point_up_tone5 { background-position: -520px -700px; } +.emoji-police_car { background-position: -540px -700px; } +.emoji-poodle { background-position: -560px -700px; } +.emoji-poop { background-position: -580px -700px; } +.emoji-popcorn { background-position: -600px -700px; } +.emoji-post_office { background-position: -620px -700px; } +.emoji-postal_horn { background-position: -640px -700px; } +.emoji-postbox { background-position: -660px -700px; } +.emoji-potable_water { background-position: -680px -700px; } +.emoji-potato { background-position: -700px -700px; } +.emoji-pouch { background-position: -720px 0; } +.emoji-poultry_leg { background-position: -720px -20px; } +.emoji-pound { background-position: -720px -40px; } +.emoji-pouting_cat { background-position: -720px -60px; } +.emoji-pray { background-position: -720px -80px; } +.emoji-pray_tone1 { background-position: -720px -100px; } +.emoji-pray_tone2 { background-position: -720px -120px; } +.emoji-pray_tone3 { background-position: -720px -140px; } +.emoji-pray_tone4 { background-position: -720px -160px; } +.emoji-pray_tone5 { background-position: -720px -180px; } +.emoji-prayer_beads { background-position: -720px -200px; } +.emoji-pregnant_woman { background-position: -720px -220px; } +.emoji-pregnant_woman_tone1 { background-position: -720px -240px; } +.emoji-pregnant_woman_tone2 { background-position: -720px -260px; } +.emoji-pregnant_woman_tone3 { background-position: -720px -280px; } +.emoji-pregnant_woman_tone4 { background-position: -720px -300px; } +.emoji-pregnant_woman_tone5 { background-position: -720px -320px; } +.emoji-prince { background-position: -720px -340px; } +.emoji-prince_tone1 { background-position: -720px -360px; } +.emoji-prince_tone2 { background-position: -720px -380px; } +.emoji-prince_tone3 { background-position: -720px -400px; } +.emoji-prince_tone4 { background-position: -720px -420px; } +.emoji-prince_tone5 { background-position: -720px -440px; } +.emoji-princess { background-position: -720px -460px; } +.emoji-princess_tone1 { background-position: -720px -480px; } +.emoji-princess_tone2 { background-position: -720px -500px; } +.emoji-princess_tone3 { background-position: -720px -520px; } +.emoji-princess_tone4 { background-position: -720px -540px; } +.emoji-princess_tone5 { background-position: -720px -560px; } +.emoji-printer { background-position: -720px -580px; } +.emoji-projector { background-position: -720px -600px; } +.emoji-punch { background-position: -720px -620px; } +.emoji-punch_tone1 { background-position: -720px -640px; } +.emoji-punch_tone2 { background-position: -720px -660px; } +.emoji-punch_tone3 { background-position: -720px -680px; } +.emoji-punch_tone4 { background-position: -720px -700px; } +.emoji-punch_tone5 { background-position: 0 -720px; } +.emoji-purple_heart { background-position: -20px -720px; } +.emoji-purse { background-position: -40px -720px; } +.emoji-pushpin { background-position: -60px -720px; } +.emoji-put_litter_in_its_place { background-position: -80px -720px; } +.emoji-question { background-position: -100px -720px; } +.emoji-rabbit { background-position: -120px -720px; } +.emoji-rabbit2 { background-position: -140px -720px; } +.emoji-race_car { background-position: -160px -720px; } +.emoji-racehorse { background-position: -180px -720px; } +.emoji-radio { background-position: -200px -720px; } +.emoji-radio_button { background-position: -220px -720px; } +.emoji-radioactive { background-position: -240px -720px; } +.emoji-rage { background-position: -260px -720px; } +.emoji-railway_car { background-position: -280px -720px; } +.emoji-railway_track { background-position: -300px -720px; } +.emoji-rainbow { background-position: -320px -720px; } +.emoji-raised_back_of_hand { background-position: -340px -720px; } +.emoji-raised_back_of_hand_tone1 { background-position: -360px -720px; } +.emoji-raised_back_of_hand_tone2 { background-position: -380px -720px; } +.emoji-raised_back_of_hand_tone3 { background-position: -400px -720px; } +.emoji-raised_back_of_hand_tone4 { background-position: -420px -720px; } +.emoji-raised_back_of_hand_tone5 { background-position: -440px -720px; } +.emoji-raised_hand { background-position: -460px -720px; } +.emoji-raised_hand_tone1 { background-position: -480px -720px; } +.emoji-raised_hand_tone2 { background-position: -500px -720px; } +.emoji-raised_hand_tone3 { background-position: -520px -720px; } +.emoji-raised_hand_tone4 { background-position: -540px -720px; } +.emoji-raised_hand_tone5 { background-position: -560px -720px; } +.emoji-raised_hands { background-position: -580px -720px; } +.emoji-raised_hands_tone1 { background-position: -600px -720px; } +.emoji-raised_hands_tone2 { background-position: -620px -720px; } +.emoji-raised_hands_tone3 { background-position: -640px -720px; } +.emoji-raised_hands_tone4 { background-position: -660px -720px; } +.emoji-raised_hands_tone5 { background-position: -680px -720px; } +.emoji-raising_hand { background-position: -700px -720px; } +.emoji-raising_hand_tone1 { background-position: -720px -720px; } +.emoji-raising_hand_tone2 { background-position: -740px 0; } +.emoji-raising_hand_tone3 { background-position: -740px -20px; } +.emoji-raising_hand_tone4 { background-position: -740px -40px; } +.emoji-raising_hand_tone5 { background-position: -740px -60px; } +.emoji-ram { background-position: -740px -80px; } +.emoji-ramen { background-position: -740px -100px; } +.emoji-rat { background-position: -740px -120px; } +.emoji-record_button { background-position: -740px -140px; } +.emoji-recycle { background-position: -740px -160px; } +.emoji-red_car { background-position: -740px -180px; } +.emoji-red_circle { background-position: -740px -200px; } +.emoji-registered { background-position: -740px -220px; } +.emoji-relaxed { background-position: -740px -240px; } +.emoji-relieved { background-position: -740px -260px; } +.emoji-reminder_ribbon { background-position: -740px -280px; } +.emoji-repeat { background-position: -740px -300px; } +.emoji-repeat_one { background-position: -740px -320px; } +.emoji-restroom { background-position: -740px -340px; } +.emoji-revolving_hearts { background-position: -740px -360px; } +.emoji-rewind { background-position: -740px -380px; } +.emoji-rhino { background-position: -740px -400px; } +.emoji-ribbon { background-position: -740px -420px; } +.emoji-rice { background-position: -740px -440px; } +.emoji-rice_ball { background-position: -740px -460px; } +.emoji-rice_cracker { background-position: -740px -480px; } +.emoji-rice_scene { background-position: -740px -500px; } +.emoji-right_facing_fist { background-position: -740px -520px; } +.emoji-right_facing_fist_tone1 { background-position: -740px -540px; } +.emoji-right_facing_fist_tone2 { background-position: -740px -560px; } +.emoji-right_facing_fist_tone3 { background-position: -740px -580px; } +.emoji-right_facing_fist_tone4 { background-position: -740px -600px; } +.emoji-right_facing_fist_tone5 { background-position: -740px -620px; } +.emoji-ring { background-position: -740px -640px; } +.emoji-robot { background-position: -740px -660px; } +.emoji-rocket { background-position: -740px -680px; } +.emoji-rofl { background-position: -740px -700px; } +.emoji-roller_coaster { background-position: -740px -720px; } +.emoji-rolling_eyes { background-position: 0 -740px; } +.emoji-rooster { background-position: -20px -740px; } +.emoji-rose { background-position: -40px -740px; } +.emoji-rosette { background-position: -60px -740px; } +.emoji-rotating_light { background-position: -80px -740px; } +.emoji-round_pushpin { background-position: -100px -740px; } +.emoji-rowboat { background-position: -120px -740px; } +.emoji-rowboat_tone1 { background-position: -140px -740px; } +.emoji-rowboat_tone2 { background-position: -160px -740px; } +.emoji-rowboat_tone3 { background-position: -180px -740px; } +.emoji-rowboat_tone4 { background-position: -200px -740px; } +.emoji-rowboat_tone5 { background-position: -220px -740px; } +.emoji-rugby_football { background-position: -240px -740px; } +.emoji-runner { background-position: -260px -740px; } +.emoji-runner_tone1 { background-position: -280px -740px; } +.emoji-runner_tone2 { background-position: -300px -740px; } +.emoji-runner_tone3 { background-position: -320px -740px; } +.emoji-runner_tone4 { background-position: -340px -740px; } +.emoji-runner_tone5 { background-position: -360px -740px; } +.emoji-running_shirt_with_sash { background-position: -380px -740px; } +.emoji-sa { background-position: -400px -740px; } +.emoji-sagittarius { background-position: -420px -740px; } +.emoji-sailboat { background-position: -440px -740px; } +.emoji-sake { background-position: -460px -740px; } +.emoji-salad { background-position: -480px -740px; } +.emoji-sandal { background-position: -500px -740px; } +.emoji-santa { background-position: -520px -740px; } +.emoji-santa_tone1 { background-position: -540px -740px; } +.emoji-santa_tone2 { background-position: -560px -740px; } +.emoji-santa_tone3 { background-position: -580px -740px; } +.emoji-santa_tone4 { background-position: -600px -740px; } +.emoji-santa_tone5 { background-position: -620px -740px; } +.emoji-satellite { background-position: -640px -740px; } +.emoji-satellite_orbital { background-position: -660px -740px; } +.emoji-saxophone { background-position: -680px -740px; } +.emoji-scales { background-position: -700px -740px; } +.emoji-school { background-position: -720px -740px; } +.emoji-school_satchel { background-position: -740px -740px; } +.emoji-scissors { background-position: -760px 0; } +.emoji-scooter { background-position: -760px -20px; } +.emoji-scorpion { background-position: -760px -40px; } +.emoji-scorpius { background-position: -760px -60px; } +.emoji-scream { background-position: -760px -80px; } +.emoji-scream_cat { background-position: -760px -100px; } +.emoji-scroll { background-position: -760px -120px; } +.emoji-seat { background-position: -760px -140px; } +.emoji-second_place { background-position: -760px -160px; } +.emoji-secret { background-position: -760px -180px; } +.emoji-see_no_evil { background-position: -760px -200px; } +.emoji-seedling { background-position: -760px -220px; } +.emoji-selfie { background-position: -760px -240px; } +.emoji-selfie_tone1 { background-position: -760px -260px; } +.emoji-selfie_tone2 { background-position: -760px -280px; } +.emoji-selfie_tone3 { background-position: -760px -300px; } +.emoji-selfie_tone4 { background-position: -760px -320px; } +.emoji-selfie_tone5 { background-position: -760px -340px; } +.emoji-seven { background-position: -760px -360px; } +.emoji-shallow_pan_of_food { background-position: -760px -380px; } +.emoji-shamrock { background-position: -760px -400px; } +.emoji-shark { background-position: -760px -420px; } +.emoji-shaved_ice { background-position: -760px -440px; } +.emoji-sheep { background-position: -760px -460px; } +.emoji-shell { background-position: -760px -480px; } +.emoji-shield { background-position: -760px -500px; } +.emoji-shinto_shrine { background-position: -760px -520px; } +.emoji-ship { background-position: -760px -540px; } +.emoji-shirt { background-position: -760px -560px; } +.emoji-shopping_bags { background-position: -760px -580px; } +.emoji-shopping_cart { background-position: -760px -600px; } +.emoji-shower { background-position: -760px -620px; } +.emoji-shrimp { background-position: -760px -640px; } +.emoji-shrug { background-position: -760px -660px; } +.emoji-shrug_tone1 { background-position: -760px -680px; } +.emoji-shrug_tone2 { background-position: -760px -700px; } +.emoji-shrug_tone3 { background-position: -760px -720px; } +.emoji-shrug_tone4 { background-position: -760px -740px; } +.emoji-shrug_tone5 { background-position: 0 -760px; } +.emoji-signal_strength { background-position: -20px -760px; } +.emoji-six { background-position: -40px -760px; } +.emoji-six_pointed_star { background-position: -60px -760px; } +.emoji-ski { background-position: -80px -760px; } +.emoji-skier { background-position: -100px -760px; } +.emoji-skull { background-position: -120px -760px; } +.emoji-skull_crossbones { background-position: -140px -760px; } +.emoji-sleeping { background-position: -160px -760px; } +.emoji-sleeping_accommodation { background-position: -180px -760px; } +.emoji-sleepy { background-position: -200px -760px; } +.emoji-slight_frown { background-position: -220px -760px; } +.emoji-slight_smile { background-position: -240px -760px; } +.emoji-slot_machine { background-position: -260px -760px; } +.emoji-small_blue_diamond { background-position: -280px -760px; } +.emoji-small_orange_diamond { background-position: -300px -760px; } +.emoji-small_red_triangle { background-position: -320px -760px; } +.emoji-small_red_triangle_down { background-position: -340px -760px; } +.emoji-smile { background-position: -360px -760px; } +.emoji-smile_cat { background-position: -380px -760px; } +.emoji-smiley { background-position: -400px -760px; } +.emoji-smiley_cat { background-position: -420px -760px; } +.emoji-smiling_imp { background-position: -440px -760px; } +.emoji-smirk { background-position: -460px -760px; } +.emoji-smirk_cat { background-position: -480px -760px; } +.emoji-smoking { background-position: -500px -760px; } +.emoji-snail { background-position: -520px -760px; } +.emoji-snake { background-position: -540px -760px; } +.emoji-sneezing_face { background-position: -560px -760px; } +.emoji-snowboarder { background-position: -580px -760px; } +.emoji-snowflake { background-position: -600px -760px; } +.emoji-snowman { background-position: -620px -760px; } +.emoji-snowman2 { background-position: -640px -760px; } +.emoji-sob { background-position: -660px -760px; } +.emoji-soccer { background-position: -680px -760px; } +.emoji-soon { background-position: -700px -760px; } +.emoji-sos { background-position: -720px -760px; } +.emoji-sound { background-position: -740px -760px; } +.emoji-space_invader { background-position: -760px -760px; } +.emoji-spades { background-position: -780px 0; } +.emoji-spaghetti { background-position: -780px -20px; } +.emoji-sparkle { background-position: -780px -40px; } +.emoji-sparkler { background-position: -780px -60px; } +.emoji-sparkles { background-position: -780px -80px; } +.emoji-sparkling_heart { background-position: -780px -100px; } +.emoji-speak_no_evil { background-position: -780px -120px; } +.emoji-speaker { background-position: -780px -140px; } +.emoji-speaking_head { background-position: -780px -160px; } +.emoji-speech_balloon { background-position: -780px -180px; } +.emoji-speedboat { background-position: -780px -200px; } +.emoji-spider { background-position: -780px -220px; } +.emoji-spider_web { background-position: -780px -240px; } +.emoji-spoon { background-position: -780px -260px; } +.emoji-spy { background-position: -780px -280px; } +.emoji-spy_tone1 { background-position: -780px -300px; } +.emoji-spy_tone2 { background-position: -780px -320px; } +.emoji-spy_tone3 { background-position: -780px -340px; } +.emoji-spy_tone4 { background-position: -780px -360px; } +.emoji-spy_tone5 { background-position: -780px -380px; } +.emoji-squid { background-position: -780px -400px; } +.emoji-stadium { background-position: -780px -420px; } +.emoji-star { background-position: -780px -440px; } +.emoji-star2 { background-position: -780px -460px; } +.emoji-star_and_crescent { background-position: -780px -480px; } +.emoji-star_of_david { background-position: -780px -500px; } +.emoji-stars { background-position: -780px -520px; } +.emoji-station { background-position: -780px -540px; } +.emoji-statue_of_liberty { background-position: -780px -560px; } +.emoji-steam_locomotive { background-position: -780px -580px; } +.emoji-stew { background-position: -780px -600px; } +.emoji-stop_button { background-position: -780px -620px; } +.emoji-stopwatch { background-position: -780px -640px; } +.emoji-straight_ruler { background-position: -780px -660px; } +.emoji-strawberry { background-position: -780px -680px; } +.emoji-stuck_out_tongue { background-position: -780px -700px; } +.emoji-stuck_out_tongue_closed_eyes { background-position: -780px -720px; } +.emoji-stuck_out_tongue_winking_eye { background-position: -780px -740px; } +.emoji-stuffed_flatbread { background-position: -780px -760px; } +.emoji-sun_with_face { background-position: 0 -780px; } +.emoji-sunflower { background-position: -20px -780px; } +.emoji-sunglasses { background-position: -40px -780px; } +.emoji-sunny { background-position: -60px -780px; } +.emoji-sunrise { background-position: -80px -780px; } +.emoji-sunrise_over_mountains { background-position: -100px -780px; } +.emoji-surfer { background-position: -120px -780px; } +.emoji-surfer_tone1 { background-position: -140px -780px; } +.emoji-surfer_tone2 { background-position: -160px -780px; } +.emoji-surfer_tone3 { background-position: -180px -780px; } +.emoji-surfer_tone4 { background-position: -200px -780px; } +.emoji-surfer_tone5 { background-position: -220px -780px; } +.emoji-sushi { background-position: -240px -780px; } +.emoji-suspension_railway { background-position: -260px -780px; } +.emoji-sweat { background-position: -280px -780px; } +.emoji-sweat_drops { background-position: -300px -780px; } +.emoji-sweat_smile { background-position: -320px -780px; } +.emoji-sweet_potato { background-position: -340px -780px; } +.emoji-swimmer { background-position: -360px -780px; } +.emoji-swimmer_tone1 { background-position: -380px -780px; } +.emoji-swimmer_tone2 { background-position: -400px -780px; } +.emoji-swimmer_tone3 { background-position: -420px -780px; } +.emoji-swimmer_tone4 { background-position: -440px -780px; } +.emoji-swimmer_tone5 { background-position: -460px -780px; } +.emoji-symbols { background-position: -480px -780px; } +.emoji-synagogue { background-position: -500px -780px; } +.emoji-syringe { background-position: -520px -780px; } +.emoji-taco { background-position: -540px -780px; } +.emoji-tada { background-position: -560px -780px; } +.emoji-tanabata_tree { background-position: -580px -780px; } +.emoji-tangerine { background-position: -600px -780px; } +.emoji-taurus { background-position: -620px -780px; } +.emoji-taxi { background-position: -640px -780px; } +.emoji-tea { background-position: -660px -780px; } +.emoji-telephone { background-position: -680px -780px; } +.emoji-telephone_receiver { background-position: -700px -780px; } +.emoji-telescope { background-position: -720px -780px; } +.emoji-ten { background-position: -740px -780px; } +.emoji-tennis { background-position: -760px -780px; } +.emoji-tent { background-position: -780px -780px; } +.emoji-thermometer { background-position: -800px 0; } +.emoji-thermometer_face { background-position: -800px -20px; } +.emoji-thinking { background-position: -800px -40px; } +.emoji-third_place { background-position: -800px -60px; } +.emoji-thought_balloon { background-position: -800px -80px; } +.emoji-three { background-position: -800px -100px; } +.emoji-thumbsdown { background-position: -800px -120px; } +.emoji-thumbsdown_tone1 { background-position: -800px -140px; } +.emoji-thumbsdown_tone2 { background-position: -800px -160px; } +.emoji-thumbsdown_tone3 { background-position: -800px -180px; } +.emoji-thumbsdown_tone4 { background-position: -800px -200px; } +.emoji-thumbsdown_tone5 { background-position: -800px -220px; } +.emoji-thumbsup { background-position: -800px -240px; } +.emoji-thumbsup_tone1 { background-position: -800px -260px; } +.emoji-thumbsup_tone2 { background-position: -800px -280px; } +.emoji-thumbsup_tone3 { background-position: -800px -300px; } +.emoji-thumbsup_tone4 { background-position: -800px -320px; } +.emoji-thumbsup_tone5 { background-position: -800px -340px; } +.emoji-thunder_cloud_rain { background-position: -800px -360px; } +.emoji-ticket { background-position: -800px -380px; } +.emoji-tickets { background-position: -800px -400px; } +.emoji-tiger { background-position: -800px -420px; } +.emoji-tiger2 { background-position: -800px -440px; } +.emoji-timer { background-position: -800px -460px; } +.emoji-tired_face { background-position: -800px -480px; } +.emoji-tm { background-position: -800px -500px; } +.emoji-toilet { background-position: -800px -520px; } +.emoji-tokyo_tower { background-position: -800px -540px; } +.emoji-tomato { background-position: -800px -560px; } +.emoji-tone1 { background-position: -800px -580px; } +.emoji-tone2 { background-position: -800px -600px; } +.emoji-tone3 { background-position: -800px -620px; } +.emoji-tone4 { background-position: -800px -640px; } +.emoji-tone5 { background-position: -800px -660px; } +.emoji-tongue { background-position: -800px -680px; } +.emoji-tools { background-position: -800px -700px; } +.emoji-top { background-position: -800px -720px; } +.emoji-tophat { background-position: -800px -740px; } +.emoji-track_next { background-position: -800px -760px; } +.emoji-track_previous { background-position: -800px -780px; } +.emoji-trackball { background-position: 0 -800px; } +.emoji-tractor { background-position: -20px -800px; } +.emoji-traffic_light { background-position: -40px -800px; } +.emoji-train { background-position: -60px -800px; } +.emoji-train2 { background-position: -80px -800px; } +.emoji-tram { background-position: -100px -800px; } +.emoji-triangular_flag_on_post { background-position: -120px -800px; } +.emoji-triangular_ruler { background-position: -140px -800px; } +.emoji-trident { background-position: -160px -800px; } +.emoji-triumph { background-position: -180px -800px; } +.emoji-trolleybus { background-position: -200px -800px; } +.emoji-trophy { background-position: -220px -800px; } +.emoji-tropical_drink { background-position: -240px -800px; } +.emoji-tropical_fish { background-position: -260px -800px; } +.emoji-truck { background-position: -280px -800px; } +.emoji-trumpet { background-position: -300px -800px; } +.emoji-tulip { background-position: -320px -800px; } +.emoji-tumbler_glass { background-position: -340px -800px; } +.emoji-turkey { background-position: -360px -800px; } +.emoji-turtle { background-position: -380px -800px; } +.emoji-tv { background-position: -400px -800px; } +.emoji-twisted_rightwards_arrows { background-position: -420px -800px; } +.emoji-two { background-position: -440px -800px; } +.emoji-two_hearts { background-position: -460px -800px; } +.emoji-two_men_holding_hands { background-position: -480px -800px; } +.emoji-two_women_holding_hands { background-position: -500px -800px; } +.emoji-u5272 { background-position: -520px -800px; } +.emoji-u5408 { background-position: -540px -800px; } +.emoji-u55b6 { background-position: -560px -800px; } +.emoji-u6307 { background-position: -580px -800px; } +.emoji-u6708 { background-position: -600px -800px; } +.emoji-u6709 { background-position: -620px -800px; } +.emoji-u6e80 { background-position: -640px -800px; } +.emoji-u7121 { background-position: -660px -800px; } +.emoji-u7533 { background-position: -680px -800px; } +.emoji-u7981 { background-position: -700px -800px; } +.emoji-u7a7a { background-position: -720px -800px; } +.emoji-umbrella { background-position: -740px -800px; } +.emoji-umbrella2 { background-position: -760px -800px; } +.emoji-unamused { background-position: -780px -800px; } +.emoji-underage { background-position: -800px -800px; } +.emoji-unicorn { background-position: -820px 0; } +.emoji-unlock { background-position: -820px -20px; } +.emoji-up { background-position: -820px -40px; } +.emoji-upside_down { background-position: -820px -60px; } +.emoji-urn { background-position: -820px -80px; } +.emoji-v { background-position: -820px -100px; } +.emoji-v_tone1 { background-position: -820px -120px; } +.emoji-v_tone2 { background-position: -820px -140px; } +.emoji-v_tone3 { background-position: -820px -160px; } +.emoji-v_tone4 { background-position: -820px -180px; } +.emoji-v_tone5 { background-position: -820px -200px; } +.emoji-vertical_traffic_light { background-position: -820px -220px; } +.emoji-vhs { background-position: -820px -240px; } +.emoji-vibration_mode { background-position: -820px -260px; } +.emoji-video_camera { background-position: -820px -280px; } +.emoji-video_game { background-position: -820px -300px; } +.emoji-violin { background-position: -820px -320px; } +.emoji-virgo { background-position: -820px -340px; } +.emoji-volcano { background-position: -820px -360px; } +.emoji-volleyball { background-position: -820px -380px; } +.emoji-vs { background-position: -820px -400px; } +.emoji-vulcan { background-position: -820px -420px; } +.emoji-vulcan_tone1 { background-position: -820px -440px; } +.emoji-vulcan_tone2 { background-position: -820px -460px; } +.emoji-vulcan_tone3 { background-position: -820px -480px; } +.emoji-vulcan_tone4 { background-position: -820px -500px; } +.emoji-vulcan_tone5 { background-position: -820px -520px; } +.emoji-walking { background-position: -820px -540px; } +.emoji-walking_tone1 { background-position: -820px -560px; } +.emoji-walking_tone2 { background-position: -820px -580px; } +.emoji-walking_tone3 { background-position: -820px -600px; } +.emoji-walking_tone4 { background-position: -820px -620px; } +.emoji-walking_tone5 { background-position: -820px -640px; } +.emoji-waning_crescent_moon { background-position: -820px -660px; } +.emoji-waning_gibbous_moon { background-position: -820px -680px; } +.emoji-warning { background-position: -820px -700px; } +.emoji-wastebasket { background-position: -820px -720px; } +.emoji-watch { background-position: -820px -740px; } +.emoji-water_buffalo { background-position: -820px -760px; } +.emoji-water_polo { background-position: -820px -780px; } +.emoji-water_polo_tone1 { background-position: -820px -800px; } +.emoji-water_polo_tone2 { background-position: 0 -820px; } +.emoji-water_polo_tone3 { background-position: -20px -820px; } +.emoji-water_polo_tone4 { background-position: -40px -820px; } +.emoji-water_polo_tone5 { background-position: -60px -820px; } +.emoji-watermelon { background-position: -80px -820px; } +.emoji-wave { background-position: -100px -820px; } +.emoji-wave_tone1 { background-position: -120px -820px; } +.emoji-wave_tone2 { background-position: -140px -820px; } +.emoji-wave_tone3 { background-position: -160px -820px; } +.emoji-wave_tone4 { background-position: -180px -820px; } +.emoji-wave_tone5 { background-position: -200px -820px; } +.emoji-wavy_dash { background-position: -220px -820px; } +.emoji-waxing_crescent_moon { background-position: -240px -820px; } +.emoji-waxing_gibbous_moon { background-position: -260px -820px; } +.emoji-wc { background-position: -280px -820px; } +.emoji-weary { background-position: -300px -820px; } +.emoji-wedding { background-position: -320px -820px; } +.emoji-whale { background-position: -340px -820px; } +.emoji-whale2 { background-position: -360px -820px; } +.emoji-wheel_of_dharma { background-position: -380px -820px; } +.emoji-wheelchair { background-position: -400px -820px; } +.emoji-white_check_mark { background-position: -420px -820px; } +.emoji-white_circle { background-position: -440px -820px; } +.emoji-white_flower { background-position: -460px -820px; } +.emoji-white_large_square { background-position: -480px -820px; } +.emoji-white_medium_small_square { background-position: -500px -820px; } +.emoji-white_medium_square { background-position: -520px -820px; } +.emoji-white_small_square { background-position: -540px -820px; } +.emoji-white_square_button { background-position: -560px -820px; } +.emoji-white_sun_cloud { background-position: -580px -820px; } +.emoji-white_sun_rain_cloud { background-position: -600px -820px; } +.emoji-white_sun_small_cloud { background-position: -620px -820px; } +.emoji-wilted_rose { background-position: -640px -820px; } +.emoji-wind_blowing_face { background-position: -660px -820px; } +.emoji-wind_chime { background-position: -680px -820px; } +.emoji-wine_glass { background-position: -700px -820px; } +.emoji-wink { background-position: -720px -820px; } +.emoji-wolf { background-position: -740px -820px; } +.emoji-woman { background-position: -760px -820px; } +.emoji-woman_tone1 { background-position: -780px -820px; } +.emoji-woman_tone2 { background-position: -800px -820px; } +.emoji-woman_tone3 { background-position: -820px -820px; } +.emoji-woman_tone4 { background-position: -840px 0; } +.emoji-woman_tone5 { background-position: -840px -20px; } +.emoji-womans_clothes { background-position: -840px -40px; } +.emoji-womans_hat { background-position: -840px -60px; } +.emoji-womens { background-position: -840px -80px; } +.emoji-worried { background-position: -840px -100px; } +.emoji-wrench { background-position: -840px -120px; } +.emoji-wrestlers { background-position: -840px -140px; } +.emoji-wrestlers_tone1 { background-position: -840px -160px; } +.emoji-wrestlers_tone2 { background-position: -840px -180px; } +.emoji-wrestlers_tone3 { background-position: -840px -200px; } +.emoji-wrestlers_tone4 { background-position: -840px -220px; } +.emoji-wrestlers_tone5 { background-position: -840px -240px; } +.emoji-writing_hand { background-position: -840px -260px; } +.emoji-writing_hand_tone1 { background-position: -840px -280px; } +.emoji-writing_hand_tone2 { background-position: -840px -300px; } +.emoji-writing_hand_tone3 { background-position: -840px -320px; } +.emoji-writing_hand_tone4 { background-position: -840px -340px; } +.emoji-writing_hand_tone5 { background-position: -840px -360px; } +.emoji-x { background-position: -840px -380px; } +.emoji-yellow_heart { background-position: -840px -400px; } +.emoji-yen { background-position: -840px -420px; } +.emoji-yin_yang { background-position: -840px -440px; } +.emoji-yum { background-position: -840px -460px; } +.emoji-zap { background-position: -840px -480px; } +.emoji-zero { background-position: -840px -500px; } +.emoji-zipper_mouth { background-position: -840px -520px; } +.emoji-100 { background-position: -840px -540px; } + +.emoji-icon { + background-image: image-url('emoji.png'); + background-repeat: no-repeat; + color: transparent; + text-indent: -99em; + height: 20px; + width: 20px; + + @media only screen and (-webkit-min-device-pixel-ratio: 2), + only screen and (min--moz-device-pixel-ratio: 2), + only screen and (-o-min-device-pixel-ratio: 2/1), + only screen and (min-device-pixel-ratio: 2), + only screen and (min-resolution: 192dpi), + only screen and (min-resolution: 2dppx) { + background-image: image-url('emoji@2x.png'); + background-size: 860px 840px; + } +} diff --git a/app/assets/stylesheets/framework/emojis.scss b/app/assets/stylesheets/framework/emojis.scss index 7158de65143..0a8bc95590e 100644 --- a/app/assets/stylesheets/framework/emojis.scss +++ b/app/assets/stylesheets/framework/emojis.scss @@ -1,1809 +1,6 @@ -.emoji-0023-20E3 { background-position: 0 0; } -.emoji-002A-20E3 { background-position: -20px 0; } -.emoji-0030-20E3 { background-position: 0 -20px; } -.emoji-0031-20E3 { background-position: -20px -20px; } -.emoji-0032-20E3 { background-position: -40px 0; } -.emoji-0033-20E3 { background-position: -40px -20px; } -.emoji-0034-20E3 { background-position: 0 -40px; } -.emoji-0035-20E3 { background-position: -20px -40px; } -.emoji-0036-20E3 { background-position: -40px -40px; } -.emoji-0037-20E3 { background-position: -60px 0; } -.emoji-0038-20E3 { background-position: -60px -20px; } -.emoji-0039-20E3 { background-position: -60px -40px; } -.emoji-00A9 { background-position: 0 -60px; } -.emoji-00AE { background-position: -20px -60px; } -.emoji-1F004 { background-position: -40px -60px; } -.emoji-1F0CF { background-position: -60px -60px; } -.emoji-1F170 { background-position: -80px 0; } -.emoji-1F171 { background-position: -80px -20px; } -.emoji-1F17E { background-position: -80px -40px; } -.emoji-1F17F { background-position: -80px -60px; } -.emoji-1F18E { background-position: 0 -80px; } -.emoji-1F191 { background-position: -20px -80px; } -.emoji-1F192 { background-position: -40px -80px; } -.emoji-1F193 { background-position: -60px -80px; } -.emoji-1F194 { background-position: -80px -80px; } -.emoji-1F195 { background-position: -100px 0; } -.emoji-1F196 { background-position: -100px -20px; } -.emoji-1F197 { background-position: -100px -40px; } -.emoji-1F198 { background-position: -100px -60px; } -.emoji-1F199 { background-position: -100px -80px; } -.emoji-1F19A { background-position: 0 -100px; } -.emoji-1F1E6-1F1E8 { background-position: -20px -100px; } -.emoji-1F1E6-1F1E9 { background-position: -40px -100px; } -.emoji-1F1E6-1F1EA { background-position: -60px -100px; } -.emoji-1F1E6-1F1EB { background-position: -80px -100px; } -.emoji-1F1E6-1F1EC { background-position: -100px -100px; } -.emoji-1F1E6-1F1EE { background-position: -120px 0; } -.emoji-1F1E6-1F1F1 { background-position: -120px -20px; } -.emoji-1F1E6-1F1F2 { background-position: -120px -40px; } -.emoji-1F1E6-1F1F4 { background-position: -120px -60px; } -.emoji-1F1E6-1F1F6 { background-position: -120px -80px; } -.emoji-1F1E6-1F1F7 { background-position: -120px -100px; } -.emoji-1F1E6-1F1F8 { background-position: 0 -120px; } -.emoji-1F1E6-1F1F9 { background-position: -20px -120px; } -.emoji-1F1E6-1F1FA { background-position: -40px -120px; } -.emoji-1F1E6-1F1FC { background-position: -60px -120px; } -.emoji-1F1E6-1F1FD { background-position: -80px -120px; } -.emoji-1F1E6-1F1FF { background-position: -100px -120px; } -.emoji-1F1E7-1F1E6 { background-position: -120px -120px; } -.emoji-1F1E7-1F1E7 { background-position: -140px 0; } -.emoji-1F1E7-1F1E9 { background-position: -140px -20px; } -.emoji-1F1E7-1F1EA { background-position: -140px -40px; } -.emoji-1F1E7-1F1EB { background-position: -140px -60px; } -.emoji-1F1E7-1F1EC { background-position: -140px -80px; } -.emoji-1F1E7-1F1ED { background-position: -140px -100px; } -.emoji-1F1E7-1F1EE { background-position: -140px -120px; } -.emoji-1F1E7-1F1EF { background-position: 0 -140px; } -.emoji-1F1E7-1F1F1 { background-position: -20px -140px; } -.emoji-1F1E7-1F1F2 { background-position: -40px -140px; } -.emoji-1F1E7-1F1F3 { background-position: -60px -140px; } -.emoji-1F1E7-1F1F4 { background-position: -80px -140px; } -.emoji-1F1E7-1F1F6 { background-position: -100px -140px; } -.emoji-1F1E7-1F1F7 { background-position: -120px -140px; } -.emoji-1F1E7-1F1F8 { background-position: -140px -140px; } -.emoji-1F1E7-1F1F9 { background-position: -160px 0; } -.emoji-1F1E7-1F1FB { background-position: -160px -20px; } -.emoji-1F1E7-1F1FC { background-position: -160px -40px; } -.emoji-1F1E7-1F1FE { background-position: -160px -60px; } -.emoji-1F1E7-1F1FF { background-position: -160px -80px; } -.emoji-1F1E8-1F1E6 { background-position: -160px -100px; } -.emoji-1F1E8-1F1E8 { background-position: -160px -120px; } -.emoji-1F1E8-1F1E9 { background-position: -160px -140px; } -.emoji-1F1E8-1F1EB { background-position: 0 -160px; } -.emoji-1F1E8-1F1EC { background-position: -20px -160px; } -.emoji-1F1E8-1F1ED { background-position: -40px -160px; } -.emoji-1F1E8-1F1EE { background-position: -60px -160px; } -.emoji-1F1E8-1F1F0 { background-position: -80px -160px; } -.emoji-1F1E8-1F1F1 { background-position: -100px -160px; } -.emoji-1F1E8-1F1F2 { background-position: -120px -160px; } -.emoji-1F1E8-1F1F3 { background-position: -140px -160px; } -.emoji-1F1E8-1F1F4 { background-position: -160px -160px; } -.emoji-1F1E8-1F1F5 { background-position: -180px 0; } -.emoji-1F1E8-1F1F7 { background-position: -180px -20px; } -.emoji-1F1E8-1F1FA { background-position: -180px -40px; } -.emoji-1F1E8-1F1FB { background-position: -180px -60px; } -.emoji-1F1E8-1F1FC { background-position: -180px -80px; } -.emoji-1F1E8-1F1FD { background-position: -180px -100px; } -.emoji-1F1E8-1F1FE { background-position: -180px -120px; } -.emoji-1F1E8-1F1FF { background-position: -180px -140px; } -.emoji-1F1E9-1F1EA { background-position: -180px -160px; } -.emoji-1F1E9-1F1EC { background-position: 0 -180px; } -.emoji-1F1E9-1F1EF { background-position: -20px -180px; } -.emoji-1F1E9-1F1F0 { background-position: -40px -180px; } -.emoji-1F1E9-1F1F2 { background-position: -60px -180px; } -.emoji-1F1E9-1F1F4 { background-position: -80px -180px; } -.emoji-1F1E9-1F1FF { background-position: -100px -180px; } -.emoji-1F1EA-1F1E6 { background-position: -120px -180px; } -.emoji-1F1EA-1F1E8 { background-position: -140px -180px; } -.emoji-1F1EA-1F1EA { background-position: -160px -180px; } -.emoji-1F1EA-1F1EC { background-position: -180px -180px; } -.emoji-1F1EA-1F1ED { background-position: -200px 0; } -.emoji-1F1EA-1F1F7 { background-position: -200px -20px; } -.emoji-1F1EA-1F1F8 { background-position: -200px -40px; } -.emoji-1F1EA-1F1F9 { background-position: -200px -60px; } -.emoji-1F1EA-1F1FA { background-position: -200px -80px; } -.emoji-1F1EB-1F1EE { background-position: -200px -100px; } -.emoji-1F1EB-1F1EF { background-position: -200px -120px; } -.emoji-1F1EB-1F1F0 { background-position: -200px -140px; } -.emoji-1F1EB-1F1F2 { background-position: -200px -160px; } -.emoji-1F1EB-1F1F4 { background-position: -200px -180px; } -.emoji-1F1EB-1F1F7 { background-position: 0 -200px; } -.emoji-1F1EC-1F1E6 { background-position: -20px -200px; } -.emoji-1F1EC-1F1E7 { background-position: -40px -200px; } -.emoji-1F1EC-1F1E9 { background-position: -60px -200px; } -.emoji-1F1EC-1F1EA { background-position: -80px -200px; } -.emoji-1F1EC-1F1EB { background-position: -100px -200px; } -.emoji-1F1EC-1F1EC { background-position: -120px -200px; } -.emoji-1F1EC-1F1ED { background-position: -140px -200px; } -.emoji-1F1EC-1F1EE { background-position: -160px -200px; } -.emoji-1F1EC-1F1F1 { background-position: -180px -200px; } -.emoji-1F1EC-1F1F2 { background-position: -200px -200px; } -.emoji-1F1EC-1F1F3 { background-position: -220px 0; } -.emoji-1F1EC-1F1F5 { background-position: -220px -20px; } -.emoji-1F1EC-1F1F6 { background-position: -220px -40px; } -.emoji-1F1EC-1F1F7 { background-position: -220px -60px; } -.emoji-1F1EC-1F1F8 { background-position: -220px -80px; } -.emoji-1F1EC-1F1F9 { background-position: -220px -100px; } -.emoji-1F1EC-1F1FA { background-position: -220px -120px; } -.emoji-1F1EC-1F1FC { background-position: -220px -140px; } -.emoji-1F1EC-1F1FE { background-position: -220px -160px; } -.emoji-1F1ED-1F1F0 { background-position: -220px -180px; } -.emoji-1F1ED-1F1F2 { background-position: -220px -200px; } -.emoji-1F1ED-1F1F3 { background-position: 0 -220px; } -.emoji-1F1ED-1F1F7 { background-position: -20px -220px; } -.emoji-1F1ED-1F1F9 { background-position: -40px -220px; } -.emoji-1F1ED-1F1FA { background-position: -60px -220px; } -.emoji-1F1EE-1F1E8 { background-position: -80px -220px; } -.emoji-1F1EE-1F1E9 { background-position: -100px -220px; } -.emoji-1F1EE-1F1EA { background-position: -120px -220px; } -.emoji-1F1EE-1F1F1 { background-position: -140px -220px; } -.emoji-1F1EE-1F1F2 { background-position: -160px -220px; } -.emoji-1F1EE-1F1F3 { background-position: -180px -220px; } -.emoji-1F1EE-1F1F4 { background-position: -200px -220px; } -.emoji-1F1EE-1F1F6 { background-position: -220px -220px; } -.emoji-1F1EE-1F1F7 { background-position: -240px 0; } -.emoji-1F1EE-1F1F8 { background-position: -240px -20px; } -.emoji-1F1EE-1F1F9 { background-position: -240px -40px; } -.emoji-1F1EF-1F1EA { background-position: -240px -60px; } -.emoji-1F1EF-1F1F2 { background-position: -240px -80px; } -.emoji-1F1EF-1F1F4 { background-position: -240px -100px; } -.emoji-1F1EF-1F1F5 { background-position: -240px -120px; } -.emoji-1F1F0-1F1EA { background-position: -240px -140px; } -.emoji-1F1F0-1F1EC { background-position: -240px -160px; } -.emoji-1F1F0-1F1ED { background-position: -240px -180px; } -.emoji-1F1F0-1F1EE { background-position: -240px -200px; } -.emoji-1F1F0-1F1F2 { background-position: -240px -220px; } -.emoji-1F1F0-1F1F3 { background-position: 0 -240px; } -.emoji-1F1F0-1F1F5 { background-position: -20px -240px; } -.emoji-1F1F0-1F1F7 { background-position: -40px -240px; } -.emoji-1F1F0-1F1FC { background-position: -60px -240px; } -.emoji-1F1F0-1F1FE { background-position: -80px -240px; } -.emoji-1F1F0-1F1FF { background-position: -100px -240px; } -.emoji-1F1F1-1F1E6 { background-position: -120px -240px; } -.emoji-1F1F1-1F1E7 { background-position: -140px -240px; } -.emoji-1F1F1-1F1E8 { background-position: -160px -240px; } -.emoji-1F1F1-1F1EE { background-position: -180px -240px; } -.emoji-1F1F1-1F1F0 { background-position: -200px -240px; } -.emoji-1F1F1-1F1F7 { background-position: -220px -240px; } -.emoji-1F1F1-1F1F8 { background-position: -240px -240px; } -.emoji-1F1F1-1F1F9 { background-position: -260px 0; } -.emoji-1F1F1-1F1FA { background-position: -260px -20px; } -.emoji-1F1F1-1F1FB { background-position: -260px -40px; } -.emoji-1F1F1-1F1FE { background-position: -260px -60px; } -.emoji-1F1F2-1F1E6 { background-position: -260px -80px; } -.emoji-1F1F2-1F1E8 { background-position: -260px -100px; } -.emoji-1F1F2-1F1E9 { background-position: -260px -120px; } -.emoji-1F1F2-1F1EA { background-position: -260px -140px; } -.emoji-1F1F2-1F1EB { background-position: -260px -160px; } -.emoji-1F1F2-1F1EC { background-position: -260px -180px; } -.emoji-1F1F2-1F1ED { background-position: -260px -200px; } -.emoji-1F1F2-1F1F0 { background-position: -260px -220px; } -.emoji-1F1F2-1F1F1 { background-position: -260px -240px; } -.emoji-1F1F2-1F1F2 { background-position: 0 -260px; } -.emoji-1F1F2-1F1F3 { background-position: -20px -260px; } -.emoji-1F1F2-1F1F4 { background-position: -40px -260px; } -.emoji-1F1F2-1F1F5 { background-position: -60px -260px; } -.emoji-1F1F2-1F1F6 { background-position: -80px -260px; } -.emoji-1F1F2-1F1F7 { background-position: -100px -260px; } -.emoji-1F1F2-1F1F8 { background-position: -120px -260px; } -.emoji-1F1F2-1F1F9 { background-position: -140px -260px; } -.emoji-1F1F2-1F1FA { background-position: -160px -260px; } -.emoji-1F1F2-1F1FB { background-position: -180px -260px; } -.emoji-1F1F2-1F1FC { background-position: -200px -260px; } -.emoji-1F1F2-1F1FD { background-position: -220px -260px; } -.emoji-1F1F2-1F1FE { background-position: -240px -260px; } -.emoji-1F1F2-1F1FF { background-position: -260px -260px; } -.emoji-1F1F3-1F1E6 { background-position: -280px 0; } -.emoji-1F1F3-1F1E8 { background-position: -280px -20px; } -.emoji-1F1F3-1F1EA { background-position: -280px -40px; } -.emoji-1F1F3-1F1EB { background-position: -280px -60px; } -.emoji-1F1F3-1F1EC { background-position: -280px -80px; } -.emoji-1F1F3-1F1EE { background-position: -280px -100px; } -.emoji-1F1F3-1F1F1 { background-position: -280px -120px; } -.emoji-1F1F3-1F1F4 { background-position: -280px -140px; } -.emoji-1F1F3-1F1F5 { background-position: -280px -160px; } -.emoji-1F1F3-1F1F7 { background-position: -280px -180px; } -.emoji-1F1F3-1F1FA { background-position: -280px -200px; } -.emoji-1F1F3-1F1FF { background-position: -280px -220px; } -.emoji-1F1F4-1F1F2 { background-position: -280px -240px; } -.emoji-1F1F5-1F1E6 { background-position: -280px -260px; } -.emoji-1F1F5-1F1EA { background-position: 0 -280px; } -.emoji-1F1F5-1F1EB { background-position: -20px -280px; } -.emoji-1F1F5-1F1EC { background-position: -40px -280px; } -.emoji-1F1F5-1F1ED { background-position: -60px -280px; } -.emoji-1F1F5-1F1F0 { background-position: -80px -280px; } -.emoji-1F1F5-1F1F1 { background-position: -100px -280px; } -.emoji-1F1F5-1F1F2 { background-position: -120px -280px; } -.emoji-1F1F5-1F1F3 { background-position: -140px -280px; } -.emoji-1F1F5-1F1F7 { background-position: -160px -280px; } -.emoji-1F1F5-1F1F8 { background-position: -180px -280px; } -.emoji-1F1F5-1F1F9 { background-position: -200px -280px; } -.emoji-1F1F5-1F1FC { background-position: -220px -280px; } -.emoji-1F1F5-1F1FE { background-position: -240px -280px; } -.emoji-1F1F6-1F1E6 { background-position: -260px -280px; } -.emoji-1F1F7-1F1EA { background-position: -280px -280px; } -.emoji-1F1F7-1F1F4 { background-position: -300px 0; } -.emoji-1F1F7-1F1F8 { background-position: -300px -20px; } -.emoji-1F1F7-1F1FA { background-position: -300px -40px; } -.emoji-1F1F7-1F1FC { background-position: -300px -60px; } -.emoji-1F1F8-1F1E6 { background-position: -300px -80px; } -.emoji-1F1F8-1F1E7 { background-position: -300px -100px; } -.emoji-1F1F8-1F1E8 { background-position: -300px -120px; } -.emoji-1F1F8-1F1E9 { background-position: -300px -140px; } -.emoji-1F1F8-1F1EA { background-position: -300px -160px; } -.emoji-1F1F8-1F1EC { background-position: -300px -180px; } -.emoji-1F1F8-1F1ED { background-position: -300px -200px; } -.emoji-1F1F8-1F1EE { background-position: -300px -220px; } -.emoji-1F1F8-1F1EF { background-position: -300px -240px; } -.emoji-1F1F8-1F1F0 { background-position: -300px -260px; } -.emoji-1F1F8-1F1F1 { background-position: -300px -280px; } -.emoji-1F1F8-1F1F2 { background-position: 0 -300px; } -.emoji-1F1F8-1F1F3 { background-position: -20px -300px; } -.emoji-1F1F8-1F1F4 { background-position: -40px -300px; } -.emoji-1F1F8-1F1F7 { background-position: -60px -300px; } -.emoji-1F1F8-1F1F8 { background-position: -80px -300px; } -.emoji-1F1F8-1F1F9 { background-position: -100px -300px; } -.emoji-1F1F8-1F1FB { background-position: -120px -300px; } -.emoji-1F1F8-1F1FD { background-position: -140px -300px; } -.emoji-1F1F8-1F1FE { background-position: -160px -300px; } -.emoji-1F1F8-1F1FF { background-position: -180px -300px; } -.emoji-1F1F9-1F1E6 { background-position: -200px -300px; } -.emoji-1F1F9-1F1E8 { background-position: -220px -300px; } -.emoji-1F1F9-1F1E9 { background-position: -240px -300px; } -.emoji-1F1F9-1F1EB { background-position: -260px -300px; } -.emoji-1F1F9-1F1EC { background-position: -280px -300px; } -.emoji-1F1F9-1F1ED { background-position: -300px -300px; } -.emoji-1F1F9-1F1EF { background-position: -320px 0; } -.emoji-1F1F9-1F1F0 { background-position: -320px -20px; } -.emoji-1F1F9-1F1F1 { background-position: -320px -40px; } -.emoji-1F1F9-1F1F2 { background-position: -320px -60px; } -.emoji-1F1F9-1F1F3 { background-position: -320px -80px; } -.emoji-1F1F9-1F1F4 { background-position: -320px -100px; } -.emoji-1F1F9-1F1F7 { background-position: -320px -120px; } -.emoji-1F1F9-1F1F9 { background-position: -320px -140px; } -.emoji-1F1F9-1F1FB { background-position: -320px -160px; } -.emoji-1F1F9-1F1FC { background-position: -320px -180px; } -.emoji-1F1F9-1F1FF { background-position: -320px -200px; } -.emoji-1F1FA-1F1E6 { background-position: -320px -220px; } -.emoji-1F1FA-1F1EC { background-position: -320px -240px; } -.emoji-1F1FA-1F1F2 { background-position: -320px -260px; } -.emoji-1F1FA-1F1F8 { background-position: -320px -280px; } -.emoji-1F1FA-1F1FE { background-position: -320px -300px; } -.emoji-1F1FA-1F1FF { background-position: 0 -320px; } -.emoji-1F1FB-1F1E6 { background-position: -20px -320px; } -.emoji-1F1FB-1F1E8 { background-position: -40px -320px; } -.emoji-1F1FB-1F1EA { background-position: -60px -320px; } -.emoji-1F1FB-1F1EC { background-position: -80px -320px; } -.emoji-1F1FB-1F1EE { background-position: -100px -320px; } -.emoji-1F1FB-1F1F3 { background-position: -120px -320px; } -.emoji-1F1FB-1F1FA { background-position: -140px -320px; } -.emoji-1F1FC-1F1EB { background-position: -160px -320px; } -.emoji-1F1FC-1F1F8 { background-position: -180px -320px; } -.emoji-1F1FD-1F1F0 { background-position: -200px -320px; } -.emoji-1F1FE-1F1EA { background-position: -220px -320px; } -.emoji-1F1FE-1F1F9 { background-position: -240px -320px; } -.emoji-1F1FF-1F1E6 { background-position: -260px -320px; } -.emoji-1F1FF-1F1F2 { background-position: -280px -320px; } -.emoji-1F1FF-1F1FC { background-position: -300px -320px; } -.emoji-1F201 { background-position: -320px -320px; } -.emoji-1F202 { background-position: -340px 0; } -.emoji-1F21A { background-position: -340px -20px; } -.emoji-1F22F { background-position: -340px -40px; } -.emoji-1F232 { background-position: -340px -60px; } -.emoji-1F233 { background-position: -340px -80px; } -.emoji-1F234 { background-position: -340px -100px; } -.emoji-1F235 { background-position: -340px -120px; } -.emoji-1F236 { background-position: -340px -140px; } -.emoji-1F237 { background-position: -340px -160px; } -.emoji-1F238 { background-position: -340px -180px; } -.emoji-1F239 { background-position: -340px -200px; } -.emoji-1F23A { background-position: -340px -220px; } -.emoji-1F250 { background-position: -340px -240px; } -.emoji-1F251 { background-position: -340px -260px; } -.emoji-1F300 { background-position: -340px -280px; } -.emoji-1F301 { background-position: -340px -300px; } -.emoji-1F302 { background-position: -340px -320px; } -.emoji-1F303 { background-position: 0 -340px; } -.emoji-1F304 { background-position: -20px -340px; } -.emoji-1F305 { background-position: -40px -340px; } -.emoji-1F306 { background-position: -60px -340px; } -.emoji-1F307 { background-position: -80px -340px; } -.emoji-1F308 { background-position: -100px -340px; } -.emoji-1F309 { background-position: -120px -340px; } -.emoji-1F30A { background-position: -140px -340px; } -.emoji-1F30B { background-position: -160px -340px; } -.emoji-1F30C { background-position: -180px -340px; } -.emoji-1F30D { background-position: -200px -340px; } -.emoji-1F30E { background-position: -220px -340px; } -.emoji-1F30F { background-position: -240px -340px; } -.emoji-1F310 { background-position: -260px -340px; } -.emoji-1F311 { background-position: -280px -340px; } -.emoji-1F312 { background-position: -300px -340px; } -.emoji-1F313 { background-position: -320px -340px; } -.emoji-1F314 { background-position: -340px -340px; } -.emoji-1F315 { background-position: -360px 0; } -.emoji-1F316 { background-position: -360px -20px; } -.emoji-1F317 { background-position: -360px -40px; } -.emoji-1F318 { background-position: -360px -60px; } -.emoji-1F319 { background-position: -360px -80px; } -.emoji-1F31A { background-position: -360px -100px; } -.emoji-1F31B { background-position: -360px -120px; } -.emoji-1F31C { background-position: -360px -140px; } -.emoji-1F31D { background-position: -360px -160px; } -.emoji-1F31E { background-position: -360px -180px; } -.emoji-1F31F { background-position: -360px -200px; } -.emoji-1F320 { background-position: -360px -220px; } -.emoji-1F321 { background-position: -360px -240px; } -.emoji-1F324 { background-position: -360px -260px; } -.emoji-1F325 { background-position: -360px -280px; } -.emoji-1F326 { background-position: -360px -300px; } -.emoji-1F327 { background-position: -360px -320px; } -.emoji-1F328 { background-position: -360px -340px; } -.emoji-1F329 { background-position: 0 -360px; } -.emoji-1F32A { background-position: -20px -360px; } -.emoji-1F32B { background-position: -40px -360px; } -.emoji-1F32C { background-position: -60px -360px; } -.emoji-1F32D { background-position: -80px -360px; } -.emoji-1F32E { background-position: -100px -360px; } -.emoji-1F32F { background-position: -120px -360px; } -.emoji-1F330 { background-position: -140px -360px; } -.emoji-1F331 { background-position: -160px -360px; } -.emoji-1F332 { background-position: -180px -360px; } -.emoji-1F333 { background-position: -200px -360px; } -.emoji-1F334 { background-position: -220px -360px; } -.emoji-1F335 { background-position: -240px -360px; } -.emoji-1F336 { background-position: -260px -360px; } -.emoji-1F337 { background-position: -280px -360px; } -.emoji-1F338 { background-position: -300px -360px; } -.emoji-1F339 { background-position: -320px -360px; } -.emoji-1F33A { background-position: -340px -360px; } -.emoji-1F33B { background-position: -360px -360px; } -.emoji-1F33C { background-position: -380px 0; } -.emoji-1F33D { background-position: -380px -20px; } -.emoji-1F33E { background-position: -380px -40px; } -.emoji-1F33F { background-position: -380px -60px; } -.emoji-1F340 { background-position: -380px -80px; } -.emoji-1F341 { background-position: -380px -100px; } -.emoji-1F342 { background-position: -380px -120px; } -.emoji-1F343 { background-position: -380px -140px; } -.emoji-1F344 { background-position: -380px -160px; } -.emoji-1F345 { background-position: -380px -180px; } -.emoji-1F346 { background-position: -380px -200px; } -.emoji-1F347 { background-position: -380px -220px; } -.emoji-1F348 { background-position: -380px -240px; } -.emoji-1F349 { background-position: -380px -260px; } -.emoji-1F34A { background-position: -380px -280px; } -.emoji-1F34B { background-position: -380px -300px; } -.emoji-1F34C { background-position: -380px -320px; } -.emoji-1F34D { background-position: -380px -340px; } -.emoji-1F34E { background-position: -380px -360px; } -.emoji-1F34F { background-position: 0 -380px; } -.emoji-1F350 { background-position: -20px -380px; } -.emoji-1F351 { background-position: -40px -380px; } -.emoji-1F352 { background-position: -60px -380px; } -.emoji-1F353 { background-position: -80px -380px; } -.emoji-1F354 { background-position: -100px -380px; } -.emoji-1F355 { background-position: -120px -380px; } -.emoji-1F356 { background-position: -140px -380px; } -.emoji-1F357 { background-position: -160px -380px; } -.emoji-1F358 { background-position: -180px -380px; } -.emoji-1F359 { background-position: -200px -380px; } -.emoji-1F35A { background-position: -220px -380px; } -.emoji-1F35B { background-position: -240px -380px; } -.emoji-1F35C { background-position: -260px -380px; } -.emoji-1F35D { background-position: -280px -380px; } -.emoji-1F35E { background-position: -300px -380px; } -.emoji-1F35F { background-position: -320px -380px; } -.emoji-1F360 { background-position: -340px -380px; } -.emoji-1F361 { background-position: -360px -380px; } -.emoji-1F362 { background-position: -380px -380px; } -.emoji-1F363 { background-position: -400px 0; } -.emoji-1F364 { background-position: -400px -20px; } -.emoji-1F365 { background-position: -400px -40px; } -.emoji-1F366 { background-position: -400px -60px; } -.emoji-1F367 { background-position: -400px -80px; } -.emoji-1F368 { background-position: -400px -100px; } -.emoji-1F369 { background-position: -400px -120px; } -.emoji-1F36A { background-position: -400px -140px; } -.emoji-1F36B { background-position: -400px -160px; } -.emoji-1F36C { background-position: -400px -180px; } -.emoji-1F36D { background-position: -400px -200px; } -.emoji-1F36E { background-position: -400px -220px; } -.emoji-1F36F { background-position: -400px -240px; } -.emoji-1F370 { background-position: -400px -260px; } -.emoji-1F371 { background-position: -400px -280px; } -.emoji-1F372 { background-position: -400px -300px; } -.emoji-1F373 { background-position: -400px -320px; } -.emoji-1F374 { background-position: -400px -340px; } -.emoji-1F375 { background-position: -400px -360px; } -.emoji-1F376 { background-position: -400px -380px; } -.emoji-1F377 { background-position: 0 -400px; } -.emoji-1F378 { background-position: -20px -400px; } -.emoji-1F379 { background-position: -40px -400px; } -.emoji-1F37A { background-position: -60px -400px; } -.emoji-1F37B { background-position: -80px -400px; } -.emoji-1F37C { background-position: -100px -400px; } -.emoji-1F37D { background-position: -120px -400px; } -.emoji-1F37E { background-position: -140px -400px; } -.emoji-1F37F { background-position: -160px -400px; } -.emoji-1F380 { background-position: -180px -400px; } -.emoji-1F381 { background-position: -200px -400px; } -.emoji-1F382 { background-position: -220px -400px; } -.emoji-1F383 { background-position: -240px -400px; } -.emoji-1F384 { background-position: -260px -400px; } -.emoji-1F385 { background-position: -280px -400px; } -.emoji-1F385-1F3FB { background-position: -300px -400px; } -.emoji-1F385-1F3FC { background-position: -320px -400px; } -.emoji-1F385-1F3FD { background-position: -340px -400px; } -.emoji-1F385-1F3FE { background-position: -360px -400px; } -.emoji-1F385-1F3FF { background-position: -380px -400px; } -.emoji-1F386 { background-position: -400px -400px; } -.emoji-1F387 { background-position: -420px 0; } -.emoji-1F388 { background-position: -420px -20px; } -.emoji-1F389 { background-position: -420px -40px; } -.emoji-1F38A { background-position: -420px -60px; } -.emoji-1F38B { background-position: -420px -80px; } -.emoji-1F38C { background-position: -420px -100px; } -.emoji-1F38D { background-position: -420px -120px; } -.emoji-1F38E { background-position: -420px -140px; } -.emoji-1F38F { background-position: -420px -160px; } -.emoji-1F390 { background-position: -420px -180px; } -.emoji-1F391 { background-position: -420px -200px; } -.emoji-1F392 { background-position: -420px -220px; } -.emoji-1F393 { background-position: -420px -240px; } -.emoji-1F396 { background-position: -420px -260px; } -.emoji-1F397 { background-position: -420px -280px; } -.emoji-1F399 { background-position: -420px -300px; } -.emoji-1F39A { background-position: -420px -320px; } -.emoji-1F39B { background-position: -420px -340px; } -.emoji-1F39E { background-position: -420px -360px; } -.emoji-1F39F { background-position: -420px -380px; } -.emoji-1F3A0 { background-position: -420px -400px; } -.emoji-1F3A1 { background-position: 0 -420px; } -.emoji-1F3A2 { background-position: -20px -420px; } -.emoji-1F3A3 { background-position: -40px -420px; } -.emoji-1F3A4 { background-position: -60px -420px; } -.emoji-1F3A5 { background-position: -80px -420px; } -.emoji-1F3A6 { background-position: -100px -420px; } -.emoji-1F3A7 { background-position: -120px -420px; } -.emoji-1F3A8 { background-position: -140px -420px; } -.emoji-1F3A9 { background-position: -160px -420px; } -.emoji-1F3AA { background-position: -180px -420px; } -.emoji-1F3AB { background-position: -200px -420px; } -.emoji-1F3AC { background-position: -220px -420px; } -.emoji-1F3AD { background-position: -240px -420px; } -.emoji-1F3AE { background-position: -260px -420px; } -.emoji-1F3AF { background-position: -280px -420px; } -.emoji-1F3B0 { background-position: -300px -420px; } -.emoji-1F3B1 { background-position: -320px -420px; } -.emoji-1F3B2 { background-position: -340px -420px; } -.emoji-1F3B3 { background-position: -360px -420px; } -.emoji-1F3B4 { background-position: -380px -420px; } -.emoji-1F3B5 { background-position: -400px -420px; } -.emoji-1F3B6 { background-position: -420px -420px; } -.emoji-1F3B7 { background-position: -440px 0; } -.emoji-1F3B8 { background-position: -440px -20px; } -.emoji-1F3B9 { background-position: -440px -40px; } -.emoji-1F3BA { background-position: -440px -60px; } -.emoji-1F3BB { background-position: -440px -80px; } -.emoji-1F3BC { background-position: -440px -100px; } -.emoji-1F3BD { background-position: -440px -120px; } -.emoji-1F3BE { background-position: -440px -140px; } -.emoji-1F3BF { background-position: -440px -160px; } -.emoji-1F3C0 { background-position: -440px -180px; } -.emoji-1F3C1 { background-position: -440px -200px; } -.emoji-1F3C2 { background-position: -440px -220px; } -.emoji-1F3C3 { background-position: -440px -240px; } -.emoji-1F3C3-1F3FB { background-position: -440px -260px; } -.emoji-1F3C3-1F3FC { background-position: -440px -280px; } -.emoji-1F3C3-1F3FD { background-position: -440px -300px; } -.emoji-1F3C3-1F3FE { background-position: -440px -320px; } -.emoji-1F3C3-1F3FF { background-position: -440px -340px; } -.emoji-1F3C4 { background-position: -440px -360px; } -.emoji-1F3C4-1F3FB { background-position: -440px -380px; } -.emoji-1F3C4-1F3FC { background-position: -440px -400px; } -.emoji-1F3C4-1F3FD { background-position: -440px -420px; } -.emoji-1F3C4-1F3FE { background-position: 0 -440px; } -.emoji-1F3C4-1F3FF { background-position: -20px -440px; } -.emoji-1F3C5 { background-position: -40px -440px; } -.emoji-1F3C6 { background-position: -60px -440px; } -.emoji-1F3C7 { background-position: -80px -440px; } -.emoji-1F3C7-1F3FB { background-position: -100px -440px; } -.emoji-1F3C7-1F3FC { background-position: -120px -440px; } -.emoji-1F3C7-1F3FD { background-position: -140px -440px; } -.emoji-1F3C7-1F3FE { background-position: -160px -440px; } -.emoji-1F3C7-1F3FF { background-position: -180px -440px; } -.emoji-1F3C8 { background-position: -200px -440px; } -.emoji-1F3C9 { background-position: -220px -440px; } -.emoji-1F3CA { background-position: -240px -440px; } -.emoji-1F3CA-1F3FB { background-position: -260px -440px; } -.emoji-1F3CA-1F3FC { background-position: -280px -440px; } -.emoji-1F3CA-1F3FD { background-position: -300px -440px; } -.emoji-1F3CA-1F3FE { background-position: -320px -440px; } -.emoji-1F3CA-1F3FF { background-position: -340px -440px; } -.emoji-1F3CB { background-position: -360px -440px; } -.emoji-1F3CB-1F3FB { background-position: -380px -440px; } -.emoji-1F3CB-1F3FC { background-position: -400px -440px; } -.emoji-1F3CB-1F3FD { background-position: -420px -440px; } -.emoji-1F3CB-1F3FE { background-position: -440px -440px; } -.emoji-1F3CB-1F3FF { background-position: -460px 0; } -.emoji-1F3CC { background-position: -460px -20px; } -.emoji-1F3CD { background-position: -460px -40px; } -.emoji-1F3CE { background-position: -460px -60px; } -.emoji-1F3CF { background-position: -460px -80px; } -.emoji-1F3D0 { background-position: -460px -100px; } -.emoji-1F3D1 { background-position: -460px -120px; } -.emoji-1F3D2 { background-position: -460px -140px; } -.emoji-1F3D3 { background-position: -460px -160px; } -.emoji-1F3D4 { background-position: -460px -180px; } -.emoji-1F3D5 { background-position: -460px -200px; } -.emoji-1F3D6 { background-position: -460px -220px; } -.emoji-1F3D7 { background-position: -460px -240px; } -.emoji-1F3D8 { background-position: -460px -260px; } -.emoji-1F3D9 { background-position: -460px -280px; } -.emoji-1F3DA { background-position: -460px -300px; } -.emoji-1F3DB { background-position: -460px -320px; } -.emoji-1F3DC { background-position: -460px -340px; } -.emoji-1F3DD { background-position: -460px -360px; } -.emoji-1F3DE { background-position: -460px -380px; } -.emoji-1F3DF { background-position: -460px -400px; } -.emoji-1F3E0 { background-position: -460px -420px; } -.emoji-1F3E1 { background-position: -460px -440px; } -.emoji-1F3E2 { background-position: 0 -460px; } -.emoji-1F3E3 { background-position: -20px -460px; } -.emoji-1F3E4 { background-position: -40px -460px; } -.emoji-1F3E5 { background-position: -60px -460px; } -.emoji-1F3E6 { background-position: -80px -460px; } -.emoji-1F3E7 { background-position: -100px -460px; } -.emoji-1F3E8 { background-position: -120px -460px; } -.emoji-1F3E9 { background-position: -140px -460px; } -.emoji-1F3EA { background-position: -160px -460px; } -.emoji-1F3EB { background-position: -180px -460px; } -.emoji-1F3EC { background-position: -200px -460px; } -.emoji-1F3ED { background-position: -220px -460px; } -.emoji-1F3EE { background-position: -240px -460px; } -.emoji-1F3EF { background-position: -260px -460px; } -.emoji-1F3F0 { background-position: -280px -460px; } -.emoji-1F3F3 { background-position: -300px -460px; } -.emoji-1F3F4 { background-position: -320px -460px; } -.emoji-1F3F5 { background-position: -340px -460px; } -.emoji-1F3F7 { background-position: -360px -460px; } -.emoji-1F3F8 { background-position: -380px -460px; } -.emoji-1F3F9 { background-position: -400px -460px; } -.emoji-1F3FA { background-position: -420px -460px; } -.emoji-1F3FB { background-position: -440px -460px; } -.emoji-1F3FC { background-position: -460px -460px; } -.emoji-1F3FD { background-position: -480px 0; } -.emoji-1F3FE { background-position: -480px -20px; } -.emoji-1F3FF { background-position: -480px -40px; } -.emoji-1F400 { background-position: -480px -60px; } -.emoji-1F401 { background-position: -480px -80px; } -.emoji-1F402 { background-position: -480px -100px; } -.emoji-1F403 { background-position: -480px -120px; } -.emoji-1F404 { background-position: -480px -140px; } -.emoji-1F405 { background-position: -480px -160px; } -.emoji-1F406 { background-position: -480px -180px; } -.emoji-1F407 { background-position: -480px -200px; } -.emoji-1F408 { background-position: -480px -220px; } -.emoji-1F409 { background-position: -480px -240px; } -.emoji-1F40A { background-position: -480px -260px; } -.emoji-1F40B { background-position: -480px -280px; } -.emoji-1F40C { background-position: -480px -300px; } -.emoji-1F40D { background-position: -480px -320px; } -.emoji-1F40E { background-position: -480px -340px; } -.emoji-1F40F { background-position: -480px -360px; } -.emoji-1F410 { background-position: -480px -380px; } -.emoji-1F411 { background-position: -480px -400px; } -.emoji-1F412 { background-position: -480px -420px; } -.emoji-1F413 { background-position: -480px -440px; } -.emoji-1F414 { background-position: -480px -460px; } -.emoji-1F415 { background-position: 0 -480px; } -.emoji-1F416 { background-position: -20px -480px; } -.emoji-1F417 { background-position: -40px -480px; } -.emoji-1F418 { background-position: -60px -480px; } -.emoji-1F419 { background-position: -80px -480px; } -.emoji-1F41A { background-position: -100px -480px; } -.emoji-1F41B { background-position: -120px -480px; } -.emoji-1F41C { background-position: -140px -480px; } -.emoji-1F41D { background-position: -160px -480px; } -.emoji-1F41E { background-position: -180px -480px; } -.emoji-1F41F { background-position: -200px -480px; } -.emoji-1F420 { background-position: -220px -480px; } -.emoji-1F421 { background-position: -240px -480px; } -.emoji-1F422 { background-position: -260px -480px; } -.emoji-1F423 { background-position: -280px -480px; } -.emoji-1F424 { background-position: -300px -480px; } -.emoji-1F425 { background-position: -320px -480px; } -.emoji-1F426 { background-position: -340px -480px; } -.emoji-1F427 { background-position: -360px -480px; } -.emoji-1F428 { background-position: -380px -480px; } -.emoji-1F429 { background-position: -400px -480px; } -.emoji-1F42A { background-position: -420px -480px; } -.emoji-1F42B { background-position: -440px -480px; } -.emoji-1F42C { background-position: -460px -480px; } -.emoji-1F42D { background-position: -480px -480px; } -.emoji-1F42E { background-position: -500px 0; } -.emoji-1F42F { background-position: -500px -20px; } -.emoji-1F430 { background-position: -500px -40px; } -.emoji-1F431 { background-position: -500px -60px; } -.emoji-1F432 { background-position: -500px -80px; } -.emoji-1F433 { background-position: -500px -100px; } -.emoji-1F434 { background-position: -500px -120px; } -.emoji-1F435 { background-position: -500px -140px; } -.emoji-1F436 { background-position: -500px -160px; } -.emoji-1F437 { background-position: -500px -180px; } -.emoji-1F438 { background-position: -500px -200px; } -.emoji-1F439 { background-position: -500px -220px; } -.emoji-1F43A { background-position: -500px -240px; } -.emoji-1F43B { background-position: -500px -260px; } -.emoji-1F43C { background-position: -500px -280px; } -.emoji-1F43D { background-position: -500px -300px; } -.emoji-1F43E { background-position: -500px -320px; } -.emoji-1F43F { background-position: -500px -340px; } -.emoji-1F440 { background-position: -500px -360px; } -.emoji-1F441 { background-position: -500px -380px; } -.emoji-1F441-1F5E8 { background-position: -500px -400px; } -.emoji-1F442 { background-position: -500px -420px; } -.emoji-1F442-1F3FB { background-position: -500px -440px; } -.emoji-1F442-1F3FC { background-position: -500px -460px; } -.emoji-1F442-1F3FD { background-position: -500px -480px; } -.emoji-1F442-1F3FE { background-position: 0 -500px; } -.emoji-1F442-1F3FF { background-position: -20px -500px; } -.emoji-1F443 { background-position: -40px -500px; } -.emoji-1F443-1F3FB { background-position: -60px -500px; } -.emoji-1F443-1F3FC { background-position: -80px -500px; } -.emoji-1F443-1F3FD { background-position: -100px -500px; } -.emoji-1F443-1F3FE { background-position: -120px -500px; } -.emoji-1F443-1F3FF { background-position: -140px -500px; } -.emoji-1F444 { background-position: -160px -500px; } -.emoji-1F445 { background-position: -180px -500px; } -.emoji-1F446 { background-position: -200px -500px; } -.emoji-1F446-1F3FB { background-position: -220px -500px; } -.emoji-1F446-1F3FC { background-position: -240px -500px; } -.emoji-1F446-1F3FD { background-position: -260px -500px; } -.emoji-1F446-1F3FE { background-position: -280px -500px; } -.emoji-1F446-1F3FF { background-position: -300px -500px; } -.emoji-1F447 { background-position: -320px -500px; } -.emoji-1F447-1F3FB { background-position: -340px -500px; } -.emoji-1F447-1F3FC { background-position: -360px -500px; } -.emoji-1F447-1F3FD { background-position: -380px -500px; } -.emoji-1F447-1F3FE { background-position: -400px -500px; } -.emoji-1F447-1F3FF { background-position: -420px -500px; } -.emoji-1F448 { background-position: -440px -500px; } -.emoji-1F448-1F3FB { background-position: -460px -500px; } -.emoji-1F448-1F3FC { background-position: -480px -500px; } -.emoji-1F448-1F3FD { background-position: -500px -500px; } -.emoji-1F448-1F3FE { background-position: -520px 0; } -.emoji-1F448-1F3FF { background-position: -520px -20px; } -.emoji-1F449 { background-position: -520px -40px; } -.emoji-1F449-1F3FB { background-position: -520px -60px; } -.emoji-1F449-1F3FC { background-position: -520px -80px; } -.emoji-1F449-1F3FD { background-position: -520px -100px; } -.emoji-1F449-1F3FE { background-position: -520px -120px; } -.emoji-1F449-1F3FF { background-position: -520px -140px; } -.emoji-1F44A { background-position: -520px -160px; } -.emoji-1F44A-1F3FB { background-position: -520px -180px; } -.emoji-1F44A-1F3FC { background-position: -520px -200px; } -.emoji-1F44A-1F3FD { background-position: -520px -220px; } -.emoji-1F44A-1F3FE { background-position: -520px -240px; } -.emoji-1F44A-1F3FF { background-position: -520px -260px; } -.emoji-1F44B { background-position: -520px -280px; } -.emoji-1F44B-1F3FB { background-position: -520px -300px; } -.emoji-1F44B-1F3FC { background-position: -520px -320px; } -.emoji-1F44B-1F3FD { background-position: -520px -340px; } -.emoji-1F44B-1F3FE { background-position: -520px -360px; } -.emoji-1F44B-1F3FF { background-position: -520px -380px; } -.emoji-1F44C { background-position: -520px -400px; } -.emoji-1F44C-1F3FB { background-position: -520px -420px; } -.emoji-1F44C-1F3FC { background-position: -520px -440px; } -.emoji-1F44C-1F3FD { background-position: -520px -460px; } -.emoji-1F44C-1F3FE { background-position: -520px -480px; } -.emoji-1F44C-1F3FF { background-position: -520px -500px; } -.emoji-1F44D { background-position: 0 -520px; } -.emoji-1F44D-1F3FB { background-position: -20px -520px; } -.emoji-1F44D-1F3FC { background-position: -40px -520px; } -.emoji-1F44D-1F3FD { background-position: -60px -520px; } -.emoji-1F44D-1F3FE { background-position: -80px -520px; } -.emoji-1F44D-1F3FF { background-position: -100px -520px; } -.emoji-1F44E { background-position: -120px -520px; } -.emoji-1F44E-1F3FB { background-position: -140px -520px; } -.emoji-1F44E-1F3FC { background-position: -160px -520px; } -.emoji-1F44E-1F3FD { background-position: -180px -520px; } -.emoji-1F44E-1F3FE { background-position: -200px -520px; } -.emoji-1F44E-1F3FF { background-position: -220px -520px; } -.emoji-1F44F { background-position: -240px -520px; } -.emoji-1F44F-1F3FB { background-position: -260px -520px; } -.emoji-1F44F-1F3FC { background-position: -280px -520px; } -.emoji-1F44F-1F3FD { background-position: -300px -520px; } -.emoji-1F44F-1F3FE { background-position: -320px -520px; } -.emoji-1F44F-1F3FF { background-position: -340px -520px; } -.emoji-1F450 { background-position: -360px -520px; } -.emoji-1F450-1F3FB { background-position: -380px -520px; } -.emoji-1F450-1F3FC { background-position: -400px -520px; } -.emoji-1F450-1F3FD { background-position: -420px -520px; } -.emoji-1F450-1F3FE { background-position: -440px -520px; } -.emoji-1F450-1F3FF { background-position: -460px -520px; } -.emoji-1F451 { background-position: -480px -520px; } -.emoji-1F452 { background-position: -500px -520px; } -.emoji-1F453 { background-position: -520px -520px; } -.emoji-1F454 { background-position: -540px 0; } -.emoji-1F455 { background-position: -540px -20px; } -.emoji-1F456 { background-position: -540px -40px; } -.emoji-1F457 { background-position: -540px -60px; } -.emoji-1F458 { background-position: -540px -80px; } -.emoji-1F459 { background-position: -540px -100px; } -.emoji-1F45A { background-position: -540px -120px; } -.emoji-1F45B { background-position: -540px -140px; } -.emoji-1F45C { background-position: -540px -160px; } -.emoji-1F45D { background-position: -540px -180px; } -.emoji-1F45E { background-position: -540px -200px; } -.emoji-1F45F { background-position: -540px -220px; } -.emoji-1F460 { background-position: -540px -240px; } -.emoji-1F461 { background-position: -540px -260px; } -.emoji-1F462 { background-position: -540px -280px; } -.emoji-1F463 { background-position: -540px -300px; } -.emoji-1F464 { background-position: -540px -320px; } -.emoji-1F465 { background-position: -540px -340px; } -.emoji-1F466 { background-position: -540px -360px; } -.emoji-1F466-1F3FB { background-position: -540px -380px; } -.emoji-1F466-1F3FC { background-position: -540px -400px; } -.emoji-1F466-1F3FD { background-position: -540px -420px; } -.emoji-1F466-1F3FE { background-position: -540px -440px; } -.emoji-1F466-1F3FF { background-position: -540px -460px; } -.emoji-1F467 { background-position: -540px -480px; } -.emoji-1F467-1F3FB { background-position: -540px -500px; } -.emoji-1F467-1F3FC { background-position: -540px -520px; } -.emoji-1F467-1F3FD { background-position: 0 -540px; } -.emoji-1F467-1F3FE { background-position: -20px -540px; } -.emoji-1F467-1F3FF { background-position: -40px -540px; } -.emoji-1F468 { background-position: -60px -540px; } -.emoji-1F468-1F3FB { background-position: -80px -540px; } -.emoji-1F468-1F3FC { background-position: -100px -540px; } -.emoji-1F468-1F3FD { background-position: -120px -540px; } -.emoji-1F468-1F3FE { background-position: -140px -540px; } -.emoji-1F468-1F3FF { background-position: -160px -540px; } -.emoji-1F468-1F468-1F466 { background-position: -180px -540px; } -.emoji-1F468-1F468-1F466-1F466 { background-position: -200px -540px; } -.emoji-1F468-1F468-1F467 { background-position: -220px -540px; } -.emoji-1F468-1F468-1F467-1F466 { background-position: -240px -540px; } -.emoji-1F468-1F468-1F467-1F467 { background-position: -260px -540px; } -.emoji-1F468-1F469-1F466-1F466 { background-position: -280px -540px; } -.emoji-1F468-1F469-1F467 { background-position: -300px -540px; } -.emoji-1F468-1F469-1F467-1F466 { background-position: -320px -540px; } -.emoji-1F468-1F469-1F467-1F467 { background-position: -340px -540px; } -.emoji-1F468-2764-1F468 { background-position: -360px -540px; } -.emoji-1F468-2764-1F48B-1F468 { background-position: -380px -540px; } -.emoji-1F469 { background-position: -400px -540px; } -.emoji-1F469-1F3FB { background-position: -420px -540px; } -.emoji-1F469-1F3FC { background-position: -440px -540px; } -.emoji-1F469-1F3FD { background-position: -460px -540px; } -.emoji-1F469-1F3FE { background-position: -480px -540px; } -.emoji-1F469-1F3FF { background-position: -500px -540px; } -.emoji-1F469-1F469-1F466 { background-position: -520px -540px; } -.emoji-1F469-1F469-1F466-1F466 { background-position: -540px -540px; } -.emoji-1F469-1F469-1F467 { background-position: -560px 0; } -.emoji-1F469-1F469-1F467-1F466 { background-position: -560px -20px; } -.emoji-1F469-1F469-1F467-1F467 { background-position: -560px -40px; } -.emoji-1F469-2764-1F469 { background-position: -560px -60px; } -.emoji-1F469-2764-1F48B-1F469 { background-position: -560px -80px; } -.emoji-1F46A { background-position: -560px -100px; } -.emoji-1F46B { background-position: -560px -120px; } -.emoji-1F46C { background-position: -560px -140px; } -.emoji-1F46D { background-position: -560px -160px; } -.emoji-1F46E { background-position: -560px -180px; } -.emoji-1F46E-1F3FB { background-position: -560px -200px; } -.emoji-1F46E-1F3FC { background-position: -560px -220px; } -.emoji-1F46E-1F3FD { background-position: -560px -240px; } -.emoji-1F46E-1F3FE { background-position: -560px -260px; } -.emoji-1F46E-1F3FF { background-position: -560px -280px; } -.emoji-1F46F { background-position: -560px -300px; } -.emoji-1F470 { background-position: -560px -320px; } -.emoji-1F470-1F3FB { background-position: -560px -340px; } -.emoji-1F470-1F3FC { background-position: -560px -360px; } -.emoji-1F470-1F3FD { background-position: -560px -380px; } -.emoji-1F470-1F3FE { background-position: -560px -400px; } -.emoji-1F470-1F3FF { background-position: -560px -420px; } -.emoji-1F471 { background-position: -560px -440px; } -.emoji-1F471-1F3FB { background-position: -560px -460px; } -.emoji-1F471-1F3FC { background-position: -560px -480px; } -.emoji-1F471-1F3FD { background-position: -560px -500px; } -.emoji-1F471-1F3FE { background-position: -560px -520px; } -.emoji-1F471-1F3FF { background-position: -560px -540px; } -.emoji-1F472 { background-position: 0 -560px; } -.emoji-1F472-1F3FB { background-position: -20px -560px; } -.emoji-1F472-1F3FC { background-position: -40px -560px; } -.emoji-1F472-1F3FD { background-position: -60px -560px; } -.emoji-1F472-1F3FE { background-position: -80px -560px; } -.emoji-1F472-1F3FF { background-position: -100px -560px; } -.emoji-1F473 { background-position: -120px -560px; } -.emoji-1F473-1F3FB { background-position: -140px -560px; } -.emoji-1F473-1F3FC { background-position: -160px -560px; } -.emoji-1F473-1F3FD { background-position: -180px -560px; } -.emoji-1F473-1F3FE { background-position: -200px -560px; } -.emoji-1F473-1F3FF { background-position: -220px -560px; } -.emoji-1F474 { background-position: -240px -560px; } -.emoji-1F474-1F3FB { background-position: -260px -560px; } -.emoji-1F474-1F3FC { background-position: -280px -560px; } -.emoji-1F474-1F3FD { background-position: -300px -560px; } -.emoji-1F474-1F3FE { background-position: -320px -560px; } -.emoji-1F474-1F3FF { background-position: -340px -560px; } -.emoji-1F475 { background-position: -360px -560px; } -.emoji-1F475-1F3FB { background-position: -380px -560px; } -.emoji-1F475-1F3FC { background-position: -400px -560px; } -.emoji-1F475-1F3FD { background-position: -420px -560px; } -.emoji-1F475-1F3FE { background-position: -440px -560px; } -.emoji-1F475-1F3FF { background-position: -460px -560px; } -.emoji-1F476 { background-position: -480px -560px; } -.emoji-1F476-1F3FB { background-position: -500px -560px; } -.emoji-1F476-1F3FC { background-position: -520px -560px; } -.emoji-1F476-1F3FD { background-position: -540px -560px; } -.emoji-1F476-1F3FE { background-position: -560px -560px; } -.emoji-1F476-1F3FF { background-position: -580px 0; } -.emoji-1F477 { background-position: -580px -20px; } -.emoji-1F477-1F3FB { background-position: -580px -40px; } -.emoji-1F477-1F3FC { background-position: -580px -60px; } -.emoji-1F477-1F3FD { background-position: -580px -80px; } -.emoji-1F477-1F3FE { background-position: -580px -100px; } -.emoji-1F477-1F3FF { background-position: -580px -120px; } -.emoji-1F478 { background-position: -580px -140px; } -.emoji-1F478-1F3FB { background-position: -580px -160px; } -.emoji-1F478-1F3FC { background-position: -580px -180px; } -.emoji-1F478-1F3FD { background-position: -580px -200px; } -.emoji-1F478-1F3FE { background-position: -580px -220px; } -.emoji-1F478-1F3FF { background-position: -580px -240px; } -.emoji-1F479 { background-position: -580px -260px; } -.emoji-1F47A { background-position: -580px -280px; } -.emoji-1F47B { background-position: -580px -300px; } -.emoji-1F47C { background-position: -580px -320px; } -.emoji-1F47C-1F3FB { background-position: -580px -340px; } -.emoji-1F47C-1F3FC { background-position: -580px -360px; } -.emoji-1F47C-1F3FD { background-position: -580px -380px; } -.emoji-1F47C-1F3FE { background-position: -580px -400px; } -.emoji-1F47C-1F3FF { background-position: -580px -420px; } -.emoji-1F47D { background-position: -580px -440px; } -.emoji-1F47E { background-position: -580px -460px; } -.emoji-1F47F { background-position: -580px -480px; } -.emoji-1F480 { background-position: -580px -500px; } -.emoji-1F481 { background-position: -580px -520px; } -.emoji-1F481-1F3FB { background-position: -580px -540px; } -.emoji-1F481-1F3FC { background-position: -580px -560px; } -.emoji-1F481-1F3FD { background-position: 0 -580px; } -.emoji-1F481-1F3FE { background-position: -20px -580px; } -.emoji-1F481-1F3FF { background-position: -40px -580px; } -.emoji-1F482 { background-position: -60px -580px; } -.emoji-1F482-1F3FB { background-position: -80px -580px; } -.emoji-1F482-1F3FC { background-position: -100px -580px; } -.emoji-1F482-1F3FD { background-position: -120px -580px; } -.emoji-1F482-1F3FE { background-position: -140px -580px; } -.emoji-1F482-1F3FF { background-position: -160px -580px; } -.emoji-1F483 { background-position: -180px -580px; } -.emoji-1F483-1F3FB { background-position: -200px -580px; } -.emoji-1F483-1F3FC { background-position: -220px -580px; } -.emoji-1F483-1F3FD { background-position: -240px -580px; } -.emoji-1F483-1F3FE { background-position: -260px -580px; } -.emoji-1F483-1F3FF { background-position: -280px -580px; } -.emoji-1F484 { background-position: -300px -580px; } -.emoji-1F485 { background-position: -320px -580px; } -.emoji-1F485-1F3FB { background-position: -340px -580px; } -.emoji-1F485-1F3FC { background-position: -360px -580px; } -.emoji-1F485-1F3FD { background-position: -380px -580px; } -.emoji-1F485-1F3FE { background-position: -400px -580px; } -.emoji-1F485-1F3FF { background-position: -420px -580px; } -.emoji-1F486 { background-position: -440px -580px; } -.emoji-1F486-1F3FB { background-position: -460px -580px; } -.emoji-1F486-1F3FC { background-position: -480px -580px; } -.emoji-1F486-1F3FD { background-position: -500px -580px; } -.emoji-1F486-1F3FE { background-position: -520px -580px; } -.emoji-1F486-1F3FF { background-position: -540px -580px; } -.emoji-1F487 { background-position: -560px -580px; } -.emoji-1F487-1F3FB { background-position: -580px -580px; } -.emoji-1F487-1F3FC { background-position: -600px 0; } -.emoji-1F487-1F3FD { background-position: -600px -20px; } -.emoji-1F487-1F3FE { background-position: -600px -40px; } -.emoji-1F487-1F3FF { background-position: -600px -60px; } -.emoji-1F488 { background-position: -600px -80px; } -.emoji-1F489 { background-position: -600px -100px; } -.emoji-1F48A { background-position: -600px -120px; } -.emoji-1F48B { background-position: -600px -140px; } -.emoji-1F48C { background-position: -600px -160px; } -.emoji-1F48D { background-position: -600px -180px; } -.emoji-1F48E { background-position: -600px -200px; } -.emoji-1F48F { background-position: -600px -220px; } -.emoji-1F490 { background-position: -600px -240px; } -.emoji-1F491 { background-position: -600px -260px; } -.emoji-1F492 { background-position: -600px -280px; } -.emoji-1F493 { background-position: -600px -300px; } -.emoji-1F494 { background-position: -600px -320px; } -.emoji-1F495 { background-position: -600px -340px; } -.emoji-1F496 { background-position: -600px -360px; } -.emoji-1F497 { background-position: -600px -380px; } -.emoji-1F498 { background-position: -600px -400px; } -.emoji-1F499 { background-position: -600px -420px; } -.emoji-1F49A { background-position: -600px -440px; } -.emoji-1F49B { background-position: -600px -460px; } -.emoji-1F49C { background-position: -600px -480px; } -.emoji-1F49D { background-position: -600px -500px; } -.emoji-1F49E { background-position: -600px -520px; } -.emoji-1F49F { background-position: -600px -540px; } -.emoji-1F4A0 { background-position: -600px -560px; } -.emoji-1F4A1 { background-position: -600px -580px; } -.emoji-1F4A2 { background-position: 0 -600px; } -.emoji-1F4A3 { background-position: -20px -600px; } -.emoji-1F4A4 { background-position: -40px -600px; } -.emoji-1F4A5 { background-position: -60px -600px; } -.emoji-1F4A6 { background-position: -80px -600px; } -.emoji-1F4A7 { background-position: -100px -600px; } -.emoji-1F4A8 { background-position: -120px -600px; } -.emoji-1F4A9 { background-position: -140px -600px; } -.emoji-1F4AA { background-position: -160px -600px; } -.emoji-1F4AA-1F3FB { background-position: -180px -600px; } -.emoji-1F4AA-1F3FC { background-position: -200px -600px; } -.emoji-1F4AA-1F3FD { background-position: -220px -600px; } -.emoji-1F4AA-1F3FE { background-position: -240px -600px; } -.emoji-1F4AA-1F3FF { background-position: -260px -600px; } -.emoji-1F4AB { background-position: -280px -600px; } -.emoji-1F4AC { background-position: -300px -600px; } -.emoji-1F4AD { background-position: -320px -600px; } -.emoji-1F4AE { background-position: -340px -600px; } -.emoji-1F4AF { background-position: -360px -600px; } -.emoji-1F4B0 { background-position: -380px -600px; } -.emoji-1F4B1 { background-position: -400px -600px; } -.emoji-1F4B2 { background-position: -420px -600px; } -.emoji-1F4B3 { background-position: -440px -600px; } -.emoji-1F4B4 { background-position: -460px -600px; } -.emoji-1F4B5 { background-position: -480px -600px; } -.emoji-1F4B6 { background-position: -500px -600px; } -.emoji-1F4B7 { background-position: -520px -600px; } -.emoji-1F4B8 { background-position: -540px -600px; } -.emoji-1F4B9 { background-position: -560px -600px; } -.emoji-1F4BA { background-position: -580px -600px; } -.emoji-1F4BB { background-position: -600px -600px; } -.emoji-1F4BC { background-position: -620px 0; } -.emoji-1F4BD { background-position: -620px -20px; } -.emoji-1F4BE { background-position: -620px -40px; } -.emoji-1F4BF { background-position: -620px -60px; } -.emoji-1F4C0 { background-position: -620px -80px; } -.emoji-1F4C1 { background-position: -620px -100px; } -.emoji-1F4C2 { background-position: -620px -120px; } -.emoji-1F4C3 { background-position: -620px -140px; } -.emoji-1F4C4 { background-position: -620px -160px; } -.emoji-1F4C5 { background-position: -620px -180px; } -.emoji-1F4C6 { background-position: -620px -200px; } -.emoji-1F4C7 { background-position: -620px -220px; } -.emoji-1F4C8 { background-position: -620px -240px; } -.emoji-1F4C9 { background-position: -620px -260px; } -.emoji-1F4CA { background-position: -620px -280px; } -.emoji-1F4CB { background-position: -620px -300px; } -.emoji-1F4CC { background-position: -620px -320px; } -.emoji-1F4CD { background-position: -620px -340px; } -.emoji-1F4CE { background-position: -620px -360px; } -.emoji-1F4CF { background-position: -620px -380px; } -.emoji-1F4D0 { background-position: -620px -400px; } -.emoji-1F4D1 { background-position: -620px -420px; } -.emoji-1F4D2 { background-position: -620px -440px; } -.emoji-1F4D3 { background-position: -620px -460px; } -.emoji-1F4D4 { background-position: -620px -480px; } -.emoji-1F4D5 { background-position: -620px -500px; } -.emoji-1F4D6 { background-position: -620px -520px; } -.emoji-1F4D7 { background-position: -620px -540px; } -.emoji-1F4D8 { background-position: -620px -560px; } -.emoji-1F4D9 { background-position: -620px -580px; } -.emoji-1F4DA { background-position: -620px -600px; } -.emoji-1F4DB { background-position: 0 -620px; } -.emoji-1F4DC { background-position: -20px -620px; } -.emoji-1F4DD { background-position: -40px -620px; } -.emoji-1F4DE { background-position: -60px -620px; } -.emoji-1F4DF { background-position: -80px -620px; } -.emoji-1F4E0 { background-position: -100px -620px; } -.emoji-1F4E1 { background-position: -120px -620px; } -.emoji-1F4E2 { background-position: -140px -620px; } -.emoji-1F4E3 { background-position: -160px -620px; } -.emoji-1F4E4 { background-position: -180px -620px; } -.emoji-1F4E5 { background-position: -200px -620px; } -.emoji-1F4E6 { background-position: -220px -620px; } -.emoji-1F4E7 { background-position: -240px -620px; } -.emoji-1F4E8 { background-position: -260px -620px; } -.emoji-1F4E9 { background-position: -280px -620px; } -.emoji-1F4EA { background-position: -300px -620px; } -.emoji-1F4EB { background-position: -320px -620px; } -.emoji-1F4EC { background-position: -340px -620px; } -.emoji-1F4ED { background-position: -360px -620px; } -.emoji-1F4EE { background-position: -380px -620px; } -.emoji-1F4EF { background-position: -400px -620px; } -.emoji-1F4F0 { background-position: -420px -620px; } -.emoji-1F4F1 { background-position: -440px -620px; } -.emoji-1F4F2 { background-position: -460px -620px; } -.emoji-1F4F3 { background-position: -480px -620px; } -.emoji-1F4F4 { background-position: -500px -620px; } -.emoji-1F4F5 { background-position: -520px -620px; } -.emoji-1F4F6 { background-position: -540px -620px; } -.emoji-1F4F7 { background-position: -560px -620px; } -.emoji-1F4F8 { background-position: -580px -620px; } -.emoji-1F4F9 { background-position: -600px -620px; } -.emoji-1F4FA { background-position: -620px -620px; } -.emoji-1F4FB { background-position: -640px 0; } -.emoji-1F4FC { background-position: -640px -20px; } -.emoji-1F4FD { background-position: -640px -40px; } -.emoji-1F4FF { background-position: -640px -60px; } -.emoji-1F500 { background-position: -640px -80px; } -.emoji-1F501 { background-position: -640px -100px; } -.emoji-1F502 { background-position: -640px -120px; } -.emoji-1F503 { background-position: -640px -140px; } -.emoji-1F504 { background-position: -640px -160px; } -.emoji-1F505 { background-position: -640px -180px; } -.emoji-1F506 { background-position: -640px -200px; } -.emoji-1F507 { background-position: -640px -220px; } -.emoji-1F508 { background-position: -640px -240px; } -.emoji-1F509 { background-position: -640px -260px; } -.emoji-1F50A { background-position: -640px -280px; } -.emoji-1F50B { background-position: -640px -300px; } -.emoji-1F50C { background-position: -640px -320px; } -.emoji-1F50D { background-position: -640px -340px; } -.emoji-1F50E { background-position: -640px -360px; } -.emoji-1F50F { background-position: -640px -380px; } -.emoji-1F510 { background-position: -640px -400px; } -.emoji-1F511 { background-position: -640px -420px; } -.emoji-1F512 { background-position: -640px -440px; } -.emoji-1F513 { background-position: -640px -460px; } -.emoji-1F514 { background-position: -640px -480px; } -.emoji-1F515 { background-position: -640px -500px; } -.emoji-1F516 { background-position: -640px -520px; } -.emoji-1F517 { background-position: -640px -540px; } -.emoji-1F518 { background-position: -640px -560px; } -.emoji-1F519 { background-position: -640px -580px; } -.emoji-1F51A { background-position: -640px -600px; } -.emoji-1F51B { background-position: -640px -620px; } -.emoji-1F51C { background-position: 0 -640px; } -.emoji-1F51D { background-position: -20px -640px; } -.emoji-1F51E { background-position: -40px -640px; } -.emoji-1F51F { background-position: -60px -640px; } -.emoji-1F520 { background-position: -80px -640px; } -.emoji-1F521 { background-position: -100px -640px; } -.emoji-1F522 { background-position: -120px -640px; } -.emoji-1F523 { background-position: -140px -640px; } -.emoji-1F524 { background-position: -160px -640px; } -.emoji-1F525 { background-position: -180px -640px; } -.emoji-1F526 { background-position: -200px -640px; } -.emoji-1F527 { background-position: -220px -640px; } -.emoji-1F528 { background-position: -240px -640px; } -.emoji-1F529 { background-position: -260px -640px; } -.emoji-1F52A { background-position: -280px -640px; } -.emoji-1F52B { background-position: -300px -640px; } -.emoji-1F52C { background-position: -320px -640px; } -.emoji-1F52D { background-position: -340px -640px; } -.emoji-1F52E { background-position: -360px -640px; } -.emoji-1F52F { background-position: -380px -640px; } -.emoji-1F530 { background-position: -400px -640px; } -.emoji-1F531 { background-position: -420px -640px; } -.emoji-1F532 { background-position: -440px -640px; } -.emoji-1F533 { background-position: -460px -640px; } -.emoji-1F534 { background-position: -480px -640px; } -.emoji-1F535 { background-position: -500px -640px; } -.emoji-1F536 { background-position: -520px -640px; } -.emoji-1F537 { background-position: -540px -640px; } -.emoji-1F538 { background-position: -560px -640px; } -.emoji-1F539 { background-position: -580px -640px; } -.emoji-1F53A { background-position: -600px -640px; } -.emoji-1F53B { background-position: -620px -640px; } -.emoji-1F53C { background-position: -640px -640px; } -.emoji-1F53D { background-position: -660px 0; } -.emoji-1F549 { background-position: -660px -20px; } -.emoji-1F54A { background-position: -660px -40px; } -.emoji-1F54B { background-position: -660px -60px; } -.emoji-1F54C { background-position: -660px -80px; } -.emoji-1F54D { background-position: -660px -100px; } -.emoji-1F54E { background-position: -660px -120px; } -.emoji-1F550 { background-position: -660px -140px; } -.emoji-1F551 { background-position: -660px -160px; } -.emoji-1F552 { background-position: -660px -180px; } -.emoji-1F553 { background-position: -660px -200px; } -.emoji-1F554 { background-position: -660px -220px; } -.emoji-1F555 { background-position: -660px -240px; } -.emoji-1F556 { background-position: -660px -260px; } -.emoji-1F557 { background-position: -660px -280px; } -.emoji-1F558 { background-position: -660px -300px; } -.emoji-1F559 { background-position: -660px -320px; } -.emoji-1F55A { background-position: -660px -340px; } -.emoji-1F55B { background-position: -660px -360px; } -.emoji-1F55C { background-position: -660px -380px; } -.emoji-1F55D { background-position: -660px -400px; } -.emoji-1F55E { background-position: -660px -420px; } -.emoji-1F55F { background-position: -660px -440px; } -.emoji-1F560 { background-position: -660px -460px; } -.emoji-1F561 { background-position: -660px -480px; } -.emoji-1F562 { background-position: -660px -500px; } -.emoji-1F563 { background-position: -660px -520px; } -.emoji-1F564 { background-position: -660px -540px; } -.emoji-1F565 { background-position: -660px -560px; } -.emoji-1F566 { background-position: -660px -580px; } -.emoji-1F567 { background-position: -660px -600px; } -.emoji-1F56F { background-position: -660px -620px; } -.emoji-1F570 { background-position: -660px -640px; } -.emoji-1F573 { background-position: 0 -660px; } -.emoji-1F574 { background-position: -20px -660px; } -.emoji-1F575 { background-position: -40px -660px; } -.emoji-1F575-1F3FB { background-position: -60px -660px; } -.emoji-1F575-1F3FC { background-position: -80px -660px; } -.emoji-1F575-1F3FD { background-position: -100px -660px; } -.emoji-1F575-1F3FE { background-position: -120px -660px; } -.emoji-1F575-1F3FF { background-position: -140px -660px; } -.emoji-1F576 { background-position: -160px -660px; } -.emoji-1F577 { background-position: -180px -660px; } -.emoji-1F578 { background-position: -200px -660px; } -.emoji-1F579 { background-position: -220px -660px; } -.emoji-1F57A { background-position: -240px -660px; } -.emoji-1F57A-1F3FB { background-position: -260px -660px; } -.emoji-1F57A-1F3FC { background-position: -280px -660px; } -.emoji-1F57A-1F3FD { background-position: -300px -660px; } -.emoji-1F57A-1F3FE { background-position: -320px -660px; } -.emoji-1F57A-1F3FF { background-position: -340px -660px; } -.emoji-1F587 { background-position: -360px -660px; } -.emoji-1F58A { background-position: -380px -660px; } -.emoji-1F58B { background-position: -400px -660px; } -.emoji-1F58C { background-position: -420px -660px; } -.emoji-1F58D { background-position: -440px -660px; } -.emoji-1F590 { background-position: -460px -660px; } -.emoji-1F590-1F3FB { background-position: -480px -660px; } -.emoji-1F590-1F3FC { background-position: -500px -660px; } -.emoji-1F590-1F3FD { background-position: -520px -660px; } -.emoji-1F590-1F3FE { background-position: -540px -660px; } -.emoji-1F590-1F3FF { background-position: -560px -660px; } -.emoji-1F595 { background-position: -580px -660px; } -.emoji-1F595-1F3FB { background-position: -600px -660px; } -.emoji-1F595-1F3FC { background-position: -620px -660px; } -.emoji-1F595-1F3FD { background-position: -640px -660px; } -.emoji-1F595-1F3FE { background-position: -660px -660px; } -.emoji-1F595-1F3FF { background-position: -680px 0; } -.emoji-1F596 { background-position: -680px -20px; } -.emoji-1F596-1F3FB { background-position: -680px -40px; } -.emoji-1F596-1F3FC { background-position: -680px -60px; } -.emoji-1F596-1F3FD { background-position: -680px -80px; } -.emoji-1F596-1F3FE { background-position: -680px -100px; } -.emoji-1F596-1F3FF { background-position: -680px -120px; } -.emoji-1F5A4 { background-position: -680px -140px; } -.emoji-1F5A5 { background-position: -680px -160px; } -.emoji-1F5A8 { background-position: -680px -180px; } -.emoji-1F5B1 { background-position: -680px -200px; } -.emoji-1F5B2 { background-position: -680px -220px; } -.emoji-1F5BC { background-position: -680px -240px; } -.emoji-1F5C2 { background-position: -680px -260px; } -.emoji-1F5C3 { background-position: -680px -280px; } -.emoji-1F5C4 { background-position: -680px -300px; } -.emoji-1F5D1 { background-position: -680px -320px; } -.emoji-1F5D2 { background-position: -680px -340px; } -.emoji-1F5D3 { background-position: -680px -360px; } -.emoji-1F5DC { background-position: -680px -380px; } -.emoji-1F5DD { background-position: -680px -400px; } -.emoji-1F5DE { background-position: -680px -420px; } -.emoji-1F5E1 { background-position: -680px -440px; } -.emoji-1F5E3 { background-position: -680px -460px; } -.emoji-1F5EF { background-position: -680px -480px; } -.emoji-1F5F3 { background-position: -680px -500px; } -.emoji-1F5FA { background-position: -680px -520px; } -.emoji-1F5FB { background-position: -680px -540px; } -.emoji-1F5FC { background-position: -680px -560px; } -.emoji-1F5FD { background-position: -680px -580px; } -.emoji-1F5FE { background-position: -680px -600px; } -.emoji-1F5FF { background-position: -680px -620px; } -.emoji-1F600 { background-position: -680px -640px; } -.emoji-1F601 { background-position: -680px -660px; } -.emoji-1F602 { background-position: 0 -680px; } -.emoji-1F603 { background-position: -20px -680px; } -.emoji-1F604 { background-position: -40px -680px; } -.emoji-1F605 { background-position: -60px -680px; } -.emoji-1F606 { background-position: -80px -680px; } -.emoji-1F607 { background-position: -100px -680px; } -.emoji-1F608 { background-position: -120px -680px; } -.emoji-1F609 { background-position: -140px -680px; } -.emoji-1F60A { background-position: -160px -680px; } -.emoji-1F60B { background-position: -180px -680px; } -.emoji-1F60C { background-position: -200px -680px; } -.emoji-1F60D { background-position: -220px -680px; } -.emoji-1F60E { background-position: -240px -680px; } -.emoji-1F60F { background-position: -260px -680px; } -.emoji-1F610 { background-position: -280px -680px; } -.emoji-1F611 { background-position: -300px -680px; } -.emoji-1F612 { background-position: -320px -680px; } -.emoji-1F613 { background-position: -340px -680px; } -.emoji-1F614 { background-position: -360px -680px; } -.emoji-1F615 { background-position: -380px -680px; } -.emoji-1F616 { background-position: -400px -680px; } -.emoji-1F617 { background-position: -420px -680px; } -.emoji-1F618 { background-position: -440px -680px; } -.emoji-1F619 { background-position: -460px -680px; } -.emoji-1F61A { background-position: -480px -680px; } -.emoji-1F61B { background-position: -500px -680px; } -.emoji-1F61C { background-position: -520px -680px; } -.emoji-1F61D { background-position: -540px -680px; } -.emoji-1F61E { background-position: -560px -680px; } -.emoji-1F61F { background-position: -580px -680px; } -.emoji-1F620 { background-position: -600px -680px; } -.emoji-1F621 { background-position: -620px -680px; } -.emoji-1F622 { background-position: -640px -680px; } -.emoji-1F623 { background-position: -660px -680px; } -.emoji-1F624 { background-position: -680px -680px; } -.emoji-1F625 { background-position: -700px 0; } -.emoji-1F626 { background-position: -700px -20px; } -.emoji-1F627 { background-position: -700px -40px; } -.emoji-1F628 { background-position: -700px -60px; } -.emoji-1F629 { background-position: -700px -80px; } -.emoji-1F62A { background-position: -700px -100px; } -.emoji-1F62B { background-position: -700px -120px; } -.emoji-1F62C { background-position: -700px -140px; } -.emoji-1F62D { background-position: -700px -160px; } -.emoji-1F62E { background-position: -700px -180px; } -.emoji-1F62F { background-position: -700px -200px; } -.emoji-1F630 { background-position: -700px -220px; } -.emoji-1F631 { background-position: -700px -240px; } -.emoji-1F632 { background-position: -700px -260px; } -.emoji-1F633 { background-position: -700px -280px; } -.emoji-1F634 { background-position: -700px -300px; } -.emoji-1F635 { background-position: -700px -320px; } -.emoji-1F636 { background-position: -700px -340px; } -.emoji-1F637 { background-position: -700px -360px; } -.emoji-1F638 { background-position: -700px -380px; } -.emoji-1F639 { background-position: -700px -400px; } -.emoji-1F63A { background-position: -700px -420px; } -.emoji-1F63B { background-position: -700px -440px; } -.emoji-1F63C { background-position: -700px -460px; } -.emoji-1F63D { background-position: -700px -480px; } -.emoji-1F63E { background-position: -700px -500px; } -.emoji-1F63F { background-position: -700px -520px; } -.emoji-1F640 { background-position: -700px -540px; } -.emoji-1F641 { background-position: -700px -560px; } -.emoji-1F642 { background-position: -700px -580px; } -.emoji-1F643 { background-position: -700px -600px; } -.emoji-1F644 { background-position: -700px -620px; } -.emoji-1F645 { background-position: -700px -640px; } -.emoji-1F645-1F3FB { background-position: -700px -660px; } -.emoji-1F645-1F3FC { background-position: -700px -680px; } -.emoji-1F645-1F3FD { background-position: 0 -700px; } -.emoji-1F645-1F3FE { background-position: -20px -700px; } -.emoji-1F645-1F3FF { background-position: -40px -700px; } -.emoji-1F646 { background-position: -60px -700px; } -.emoji-1F646-1F3FB { background-position: -80px -700px; } -.emoji-1F646-1F3FC { background-position: -100px -700px; } -.emoji-1F646-1F3FD { background-position: -120px -700px; } -.emoji-1F646-1F3FE { background-position: -140px -700px; } -.emoji-1F646-1F3FF { background-position: -160px -700px; } -.emoji-1F647 { background-position: -180px -700px; } -.emoji-1F647-1F3FB { background-position: -200px -700px; } -.emoji-1F647-1F3FC { background-position: -220px -700px; } -.emoji-1F647-1F3FD { background-position: -240px -700px; } -.emoji-1F647-1F3FE { background-position: -260px -700px; } -.emoji-1F647-1F3FF { background-position: -280px -700px; } -.emoji-1F648 { background-position: -300px -700px; } -.emoji-1F649 { background-position: -320px -700px; } -.emoji-1F64A { background-position: -340px -700px; } -.emoji-1F64B { background-position: -360px -700px; } -.emoji-1F64B-1F3FB { background-position: -380px -700px; } -.emoji-1F64B-1F3FC { background-position: -400px -700px; } -.emoji-1F64B-1F3FD { background-position: -420px -700px; } -.emoji-1F64B-1F3FE { background-position: -440px -700px; } -.emoji-1F64B-1F3FF { background-position: -460px -700px; } -.emoji-1F64C { background-position: -480px -700px; } -.emoji-1F64C-1F3FB { background-position: -500px -700px; } -.emoji-1F64C-1F3FC { background-position: -520px -700px; } -.emoji-1F64C-1F3FD { background-position: -540px -700px; } -.emoji-1F64C-1F3FE { background-position: -560px -700px; } -.emoji-1F64C-1F3FF { background-position: -580px -700px; } -.emoji-1F64D { background-position: -600px -700px; } -.emoji-1F64D-1F3FB { background-position: -620px -700px; } -.emoji-1F64D-1F3FC { background-position: -640px -700px; } -.emoji-1F64D-1F3FD { background-position: -660px -700px; } -.emoji-1F64D-1F3FE { background-position: -680px -700px; } -.emoji-1F64D-1F3FF { background-position: -700px -700px; } -.emoji-1F64E { background-position: -720px 0; } -.emoji-1F64E-1F3FB { background-position: -720px -20px; } -.emoji-1F64E-1F3FC { background-position: -720px -40px; } -.emoji-1F64E-1F3FD { background-position: -720px -60px; } -.emoji-1F64E-1F3FE { background-position: -720px -80px; } -.emoji-1F64E-1F3FF { background-position: -720px -100px; } -.emoji-1F64F { background-position: -720px -120px; } -.emoji-1F64F-1F3FB { background-position: -720px -140px; } -.emoji-1F64F-1F3FC { background-position: -720px -160px; } -.emoji-1F64F-1F3FD { background-position: -720px -180px; } -.emoji-1F64F-1F3FE { background-position: -720px -200px; } -.emoji-1F64F-1F3FF { background-position: -720px -220px; } -.emoji-1F680 { background-position: -720px -240px; } -.emoji-1F681 { background-position: -720px -260px; } -.emoji-1F682 { background-position: -720px -280px; } -.emoji-1F683 { background-position: -720px -300px; } -.emoji-1F684 { background-position: -720px -320px; } -.emoji-1F685 { background-position: -720px -340px; } -.emoji-1F686 { background-position: -720px -360px; } -.emoji-1F687 { background-position: -720px -380px; } -.emoji-1F688 { background-position: -720px -400px; } -.emoji-1F689 { background-position: -720px -420px; } -.emoji-1F68A { background-position: -720px -440px; } -.emoji-1F68B { background-position: -720px -460px; } -.emoji-1F68C { background-position: -720px -480px; } -.emoji-1F68D { background-position: -720px -500px; } -.emoji-1F68E { background-position: -720px -520px; } -.emoji-1F68F { background-position: -720px -540px; } -.emoji-1F690 { background-position: -720px -560px; } -.emoji-1F691 { background-position: -720px -580px; } -.emoji-1F692 { background-position: -720px -600px; } -.emoji-1F693 { background-position: -720px -620px; } -.emoji-1F694 { background-position: -720px -640px; } -.emoji-1F695 { background-position: -720px -660px; } -.emoji-1F696 { background-position: -720px -680px; } -.emoji-1F697 { background-position: -720px -700px; } -.emoji-1F698 { background-position: 0 -720px; } -.emoji-1F699 { background-position: -20px -720px; } -.emoji-1F69A { background-position: -40px -720px; } -.emoji-1F69B { background-position: -60px -720px; } -.emoji-1F69C { background-position: -80px -720px; } -.emoji-1F69D { background-position: -100px -720px; } -.emoji-1F69E { background-position: -120px -720px; } -.emoji-1F69F { background-position: -140px -720px; } -.emoji-1F6A0 { background-position: -160px -720px; } -.emoji-1F6A1 { background-position: -180px -720px; } -.emoji-1F6A2 { background-position: -200px -720px; } -.emoji-1F6A3 { background-position: -220px -720px; } -.emoji-1F6A3-1F3FB { background-position: -240px -720px; } -.emoji-1F6A3-1F3FC { background-position: -260px -720px; } -.emoji-1F6A3-1F3FD { background-position: -280px -720px; } -.emoji-1F6A3-1F3FE { background-position: -300px -720px; } -.emoji-1F6A3-1F3FF { background-position: -320px -720px; } -.emoji-1F6A4 { background-position: -340px -720px; } -.emoji-1F6A5 { background-position: -360px -720px; } -.emoji-1F6A6 { background-position: -380px -720px; } -.emoji-1F6A7 { background-position: -400px -720px; } -.emoji-1F6A8 { background-position: -420px -720px; } -.emoji-1F6A9 { background-position: -440px -720px; } -.emoji-1F6AA { background-position: -460px -720px; } -.emoji-1F6AB { background-position: -480px -720px; } -.emoji-1F6AC { background-position: -500px -720px; } -.emoji-1F6AD { background-position: -520px -720px; } -.emoji-1F6AE { background-position: -540px -720px; } -.emoji-1F6AF { background-position: -560px -720px; } -.emoji-1F6B0 { background-position: -580px -720px; } -.emoji-1F6B1 { background-position: -600px -720px; } -.emoji-1F6B2 { background-position: -620px -720px; } -.emoji-1F6B3 { background-position: -640px -720px; } -.emoji-1F6B4 { background-position: -660px -720px; } -.emoji-1F6B4-1F3FB { background-position: -680px -720px; } -.emoji-1F6B4-1F3FC { background-position: -700px -720px; } -.emoji-1F6B4-1F3FD { background-position: -720px -720px; } -.emoji-1F6B4-1F3FE { background-position: -740px 0; } -.emoji-1F6B4-1F3FF { background-position: -740px -20px; } -.emoji-1F6B5 { background-position: -740px -40px; } -.emoji-1F6B5-1F3FB { background-position: -740px -60px; } -.emoji-1F6B5-1F3FC { background-position: -740px -80px; } -.emoji-1F6B5-1F3FD { background-position: -740px -100px; } -.emoji-1F6B5-1F3FE { background-position: -740px -120px; } -.emoji-1F6B5-1F3FF { background-position: -740px -140px; } -.emoji-1F6B6 { background-position: -740px -160px; } -.emoji-1F6B6-1F3FB { background-position: -740px -180px; } -.emoji-1F6B6-1F3FC { background-position: -740px -200px; } -.emoji-1F6B6-1F3FD { background-position: -740px -220px; } -.emoji-1F6B6-1F3FE { background-position: -740px -240px; } -.emoji-1F6B6-1F3FF { background-position: -740px -260px; } -.emoji-1F6B7 { background-position: -740px -280px; } -.emoji-1F6B8 { background-position: -740px -300px; } -.emoji-1F6B9 { background-position: -740px -320px; } -.emoji-1F6BA { background-position: -740px -340px; } -.emoji-1F6BB { background-position: -740px -360px; } -.emoji-1F6BC { background-position: -740px -380px; } -.emoji-1F6BD { background-position: -740px -400px; } -.emoji-1F6BE { background-position: -740px -420px; } -.emoji-1F6BF { background-position: -740px -440px; } -.emoji-1F6C0 { background-position: -740px -460px; } -.emoji-1F6C0-1F3FB { background-position: -740px -480px; } -.emoji-1F6C0-1F3FC { background-position: -740px -500px; } -.emoji-1F6C0-1F3FD { background-position: -740px -520px; } -.emoji-1F6C0-1F3FE { background-position: -740px -540px; } -.emoji-1F6C0-1F3FF { background-position: -740px -560px; } -.emoji-1F6C1 { background-position: -740px -580px; } -.emoji-1F6C2 { background-position: -740px -600px; } -.emoji-1F6C3 { background-position: -740px -620px; } -.emoji-1F6C4 { background-position: -740px -640px; } -.emoji-1F6C5 { background-position: -740px -660px; } -.emoji-1F6CB { background-position: -740px -680px; } -.emoji-1F6CC { background-position: -740px -700px; } -.emoji-1F6CD { background-position: -740px -720px; } -.emoji-1F6CE { background-position: 0 -740px; } -.emoji-1F6CF { background-position: -20px -740px; } -.emoji-1F6D0 { background-position: -40px -740px; } -.emoji-1F6D1 { background-position: -60px -740px; } -.emoji-1F6D2 { background-position: -80px -740px; } -.emoji-1F6E0 { background-position: -100px -740px; } -.emoji-1F6E1 { background-position: -120px -740px; } -.emoji-1F6E2 { background-position: -140px -740px; } -.emoji-1F6E3 { background-position: -160px -740px; } -.emoji-1F6E4 { background-position: -180px -740px; } -.emoji-1F6E5 { background-position: -200px -740px; } -.emoji-1F6E9 { background-position: -220px -740px; } -.emoji-1F6EB { background-position: -240px -740px; } -.emoji-1F6EC { background-position: -260px -740px; } -.emoji-1F6F0 { background-position: -280px -740px; } -.emoji-1F6F3 { background-position: -300px -740px; } -.emoji-1F6F4 { background-position: -320px -740px; } -.emoji-1F6F5 { background-position: -340px -740px; } -.emoji-1F6F6 { background-position: -360px -740px; } -.emoji-1F910 { background-position: -380px -740px; } -.emoji-1F911 { background-position: -400px -740px; } -.emoji-1F912 { background-position: -420px -740px; } -.emoji-1F913 { background-position: -440px -740px; } -.emoji-1F914 { background-position: -460px -740px; } -.emoji-1F915 { background-position: -480px -740px; } -.emoji-1F916 { background-position: -500px -740px; } -.emoji-1F917 { background-position: -520px -740px; } -.emoji-1F918 { background-position: -540px -740px; } -.emoji-1F918-1F3FB { background-position: -560px -740px; } -.emoji-1F918-1F3FC { background-position: -580px -740px; } -.emoji-1F918-1F3FD { background-position: -600px -740px; } -.emoji-1F918-1F3FE { background-position: -620px -740px; } -.emoji-1F918-1F3FF { background-position: -640px -740px; } -.emoji-1F919 { background-position: -660px -740px; } -.emoji-1F919-1F3FB { background-position: -680px -740px; } -.emoji-1F919-1F3FC { background-position: -700px -740px; } -.emoji-1F919-1F3FD { background-position: -720px -740px; } -.emoji-1F919-1F3FE { background-position: -740px -740px; } -.emoji-1F919-1F3FF { background-position: -760px 0; } -.emoji-1F91A { background-position: -760px -20px; } -.emoji-1F91A-1F3FB { background-position: -760px -40px; } -.emoji-1F91A-1F3FC { background-position: -760px -60px; } -.emoji-1F91A-1F3FD { background-position: -760px -80px; } -.emoji-1F91A-1F3FE { background-position: -760px -100px; } -.emoji-1F91A-1F3FF { background-position: -760px -120px; } -.emoji-1F91B { background-position: -760px -140px; } -.emoji-1F91B-1F3FB { background-position: -760px -160px; } -.emoji-1F91B-1F3FC { background-position: -760px -180px; } -.emoji-1F91B-1F3FD { background-position: -760px -200px; } -.emoji-1F91B-1F3FE { background-position: -760px -220px; } -.emoji-1F91B-1F3FF { background-position: -760px -240px; } -.emoji-1F91C { background-position: -760px -260px; } -.emoji-1F91C-1F3FB { background-position: -760px -280px; } -.emoji-1F91C-1F3FC { background-position: -760px -300px; } -.emoji-1F91C-1F3FD { background-position: -760px -320px; } -.emoji-1F91C-1F3FE { background-position: -760px -340px; } -.emoji-1F91C-1F3FF { background-position: -760px -360px; } -.emoji-1F91D { background-position: -760px -380px; } -.emoji-1F91D-1F3FB { background-position: -760px -400px; } -.emoji-1F91D-1F3FC { background-position: -760px -420px; } -.emoji-1F91D-1F3FD { background-position: -760px -440px; } -.emoji-1F91D-1F3FE { background-position: -760px -460px; } -.emoji-1F91D-1F3FF { background-position: -760px -480px; } -.emoji-1F91E { background-position: -760px -500px; } -.emoji-1F91E-1F3FB { background-position: -760px -520px; } -.emoji-1F91E-1F3FC { background-position: -760px -540px; } -.emoji-1F91E-1F3FD { background-position: -760px -560px; } -.emoji-1F91E-1F3FE { background-position: -760px -580px; } -.emoji-1F91E-1F3FF { background-position: -760px -600px; } -.emoji-1F920 { background-position: -760px -620px; } -.emoji-1F921 { background-position: -760px -640px; } -.emoji-1F922 { background-position: -760px -660px; } -.emoji-1F923 { background-position: -760px -680px; } -.emoji-1F924 { background-position: -760px -700px; } -.emoji-1F925 { background-position: -760px -720px; } -.emoji-1F926 { background-position: -760px -740px; } -.emoji-1F926-1F3FB { background-position: 0 -760px; } -.emoji-1F926-1F3FC { background-position: -20px -760px; } -.emoji-1F926-1F3FD { background-position: -40px -760px; } -.emoji-1F926-1F3FE { background-position: -60px -760px; } -.emoji-1F926-1F3FF { background-position: -80px -760px; } -.emoji-1F927 { background-position: -100px -760px; } -.emoji-1F930 { background-position: -120px -760px; } -.emoji-1F930-1F3FB { background-position: -140px -760px; } -.emoji-1F930-1F3FC { background-position: -160px -760px; } -.emoji-1F930-1F3FD { background-position: -180px -760px; } -.emoji-1F930-1F3FE { background-position: -200px -760px; } -.emoji-1F930-1F3FF { background-position: -220px -760px; } -.emoji-1F933 { background-position: -240px -760px; } -.emoji-1F933-1F3FB { background-position: -260px -760px; } -.emoji-1F933-1F3FC { background-position: -280px -760px; } -.emoji-1F933-1F3FD { background-position: -300px -760px; } -.emoji-1F933-1F3FE { background-position: -320px -760px; } -.emoji-1F933-1F3FF { background-position: -340px -760px; } -.emoji-1F934 { background-position: -360px -760px; } -.emoji-1F934-1F3FB { background-position: -380px -760px; } -.emoji-1F934-1F3FC { background-position: -400px -760px; } -.emoji-1F934-1F3FD { background-position: -420px -760px; } -.emoji-1F934-1F3FE { background-position: -440px -760px; } -.emoji-1F934-1F3FF { background-position: -460px -760px; } -.emoji-1F935 { background-position: -480px -760px; } -.emoji-1F935-1F3FB { background-position: -500px -760px; } -.emoji-1F935-1F3FC { background-position: -520px -760px; } -.emoji-1F935-1F3FD { background-position: -540px -760px; } -.emoji-1F935-1F3FE { background-position: -560px -760px; } -.emoji-1F935-1F3FF { background-position: -580px -760px; } -.emoji-1F936 { background-position: -600px -760px; } -.emoji-1F936-1F3FB { background-position: -620px -760px; } -.emoji-1F936-1F3FC { background-position: -640px -760px; } -.emoji-1F936-1F3FD { background-position: -660px -760px; } -.emoji-1F936-1F3FE { background-position: -680px -760px; } -.emoji-1F936-1F3FF { background-position: -700px -760px; } -.emoji-1F937 { background-position: -720px -760px; } -.emoji-1F937-1F3FB { background-position: -740px -760px; } -.emoji-1F937-1F3FC { background-position: -760px -760px; } -.emoji-1F937-1F3FD { background-position: -780px 0; } -.emoji-1F937-1F3FE { background-position: -780px -20px; } -.emoji-1F937-1F3FF { background-position: -780px -40px; } -.emoji-1F938 { background-position: -780px -60px; } -.emoji-1F938-1F3FB { background-position: -780px -80px; } -.emoji-1F938-1F3FC { background-position: -780px -100px; } -.emoji-1F938-1F3FD { background-position: -780px -120px; } -.emoji-1F938-1F3FE { background-position: -780px -140px; } -.emoji-1F938-1F3FF { background-position: -780px -160px; } -.emoji-1F939 { background-position: -780px -180px; } -.emoji-1F939-1F3FB { background-position: -780px -200px; } -.emoji-1F939-1F3FC { background-position: -780px -220px; } -.emoji-1F939-1F3FD { background-position: -780px -240px; } -.emoji-1F939-1F3FE { background-position: -780px -260px; } -.emoji-1F939-1F3FF { background-position: -780px -280px; } -.emoji-1F93A { background-position: -780px -300px; } -.emoji-1F93C { background-position: -780px -320px; } -.emoji-1F93C-1F3FB { background-position: -780px -340px; } -.emoji-1F93C-1F3FC { background-position: -780px -360px; } -.emoji-1F93C-1F3FD { background-position: -780px -380px; } -.emoji-1F93C-1F3FE { background-position: -780px -400px; } -.emoji-1F93C-1F3FF { background-position: -780px -420px; } -.emoji-1F93D { background-position: -780px -440px; } -.emoji-1F93D-1F3FB { background-position: -780px -460px; } -.emoji-1F93D-1F3FC { background-position: -780px -480px; } -.emoji-1F93D-1F3FD { background-position: -780px -500px; } -.emoji-1F93D-1F3FE { background-position: -780px -520px; } -.emoji-1F93D-1F3FF { background-position: -780px -540px; } -.emoji-1F93E { background-position: -780px -560px; } -.emoji-1F93E-1F3FB { background-position: -780px -580px; } -.emoji-1F93E-1F3FC { background-position: -780px -600px; } -.emoji-1F93E-1F3FD { background-position: -780px -620px; } -.emoji-1F93E-1F3FE { background-position: -780px -640px; } -.emoji-1F93E-1F3FF { background-position: -780px -660px; } -.emoji-1F940 { background-position: -780px -680px; } -.emoji-1F941 { background-position: -780px -700px; } -.emoji-1F942 { background-position: -780px -720px; } -.emoji-1F943 { background-position: -780px -740px; } -.emoji-1F944 { background-position: -780px -760px; } -.emoji-1F945 { background-position: 0 -780px; } -.emoji-1F947 { background-position: -20px -780px; } -.emoji-1F948 { background-position: -40px -780px; } -.emoji-1F949 { background-position: -60px -780px; } -.emoji-1F94A { background-position: -80px -780px; } -.emoji-1F94B { background-position: -100px -780px; } -.emoji-1F950 { background-position: -120px -780px; } -.emoji-1F951 { background-position: -140px -780px; } -.emoji-1F952 { background-position: -160px -780px; } -.emoji-1F953 { background-position: -180px -780px; } -.emoji-1F954 { background-position: -200px -780px; } -.emoji-1F955 { background-position: -220px -780px; } -.emoji-1F956 { background-position: -240px -780px; } -.emoji-1F957 { background-position: -260px -780px; } -.emoji-1F958 { background-position: -280px -780px; } -.emoji-1F959 { background-position: -300px -780px; } -.emoji-1F95A { background-position: -320px -780px; } -.emoji-1F95B { background-position: -340px -780px; } -.emoji-1F95C { background-position: -360px -780px; } -.emoji-1F95D { background-position: -380px -780px; } -.emoji-1F95E { background-position: -400px -780px; } -.emoji-1F980 { background-position: -420px -780px; } -.emoji-1F981 { background-position: -440px -780px; } -.emoji-1F982 { background-position: -460px -780px; } -.emoji-1F983 { background-position: -480px -780px; } -.emoji-1F984 { background-position: -500px -780px; } -.emoji-1F985 { background-position: -520px -780px; } -.emoji-1F986 { background-position: -540px -780px; } -.emoji-1F987 { background-position: -560px -780px; } -.emoji-1F988 { background-position: -580px -780px; } -.emoji-1F989 { background-position: -600px -780px; } -.emoji-1F98A { background-position: -620px -780px; } -.emoji-1F98B { background-position: -640px -780px; } -.emoji-1F98C { background-position: -660px -780px; } -.emoji-1F98D { background-position: -680px -780px; } -.emoji-1F98E { background-position: -700px -780px; } -.emoji-1F98F { background-position: -720px -780px; } -.emoji-1F990 { background-position: -740px -780px; } -.emoji-1F991 { background-position: -760px -780px; } -.emoji-1F9C0 { background-position: -780px -780px; } -.emoji-203C { background-position: -800px 0; } -.emoji-2049 { background-position: -800px -20px; } -.emoji-2122 { background-position: -800px -40px; } -.emoji-2139 { background-position: -800px -60px; } -.emoji-2194 { background-position: -800px -80px; } -.emoji-2195 { background-position: -800px -100px; } -.emoji-2196 { background-position: -800px -120px; } -.emoji-2197 { background-position: -800px -140px; } -.emoji-2198 { background-position: -800px -160px; } -.emoji-2199 { background-position: -800px -180px; } -.emoji-21A9 { background-position: -800px -200px; } -.emoji-21AA { background-position: -800px -220px; } -.emoji-231A { background-position: -800px -240px; } -.emoji-231B { background-position: -800px -260px; } -.emoji-2328 { background-position: -800px -280px; } -.emoji-23CF { background-position: -800px -300px; } -.emoji-23E9 { background-position: -800px -320px; } -.emoji-23EA { background-position: -800px -340px; } -.emoji-23EB { background-position: -800px -360px; } -.emoji-23EC { background-position: -800px -380px; } -.emoji-23ED { background-position: -800px -400px; } -.emoji-23EE { background-position: -800px -420px; } -.emoji-23EF { background-position: -800px -440px; } -.emoji-23F0 { background-position: -800px -460px; } -.emoji-23F1 { background-position: -800px -480px; } -.emoji-23F2 { background-position: -800px -500px; } -.emoji-23F3 { background-position: -800px -520px; } -.emoji-23F8 { background-position: -800px -540px; } -.emoji-23F9 { background-position: -800px -560px; } -.emoji-23FA { background-position: -800px -580px; } -.emoji-24C2 { background-position: -800px -600px; } -.emoji-25AA { background-position: -800px -620px; } -.emoji-25AB { background-position: -800px -640px; } -.emoji-25B6 { background-position: -800px -660px; } -.emoji-25C0 { background-position: -800px -680px; } -.emoji-25FB { background-position: -800px -700px; } -.emoji-25FC { background-position: -800px -720px; } -.emoji-25FD { background-position: -800px -740px; } -.emoji-25FE { background-position: -800px -760px; } -.emoji-2600 { background-position: -800px -780px; } -.emoji-2601 { background-position: 0 -800px; } -.emoji-2602 { background-position: -20px -800px; } -.emoji-2603 { background-position: -40px -800px; } -.emoji-2604 { background-position: -60px -800px; } -.emoji-260E { background-position: -80px -800px; } -.emoji-2611 { background-position: -100px -800px; } -.emoji-2614 { background-position: -120px -800px; } -.emoji-2615 { background-position: -140px -800px; } -.emoji-2618 { background-position: -160px -800px; } -.emoji-261D { background-position: -180px -800px; } -.emoji-261D-1F3FB { background-position: -200px -800px; } -.emoji-261D-1F3FC { background-position: -220px -800px; } -.emoji-261D-1F3FD { background-position: -240px -800px; } -.emoji-261D-1F3FE { background-position: -260px -800px; } -.emoji-261D-1F3FF { background-position: -280px -800px; } -.emoji-2620 { background-position: -300px -800px; } -.emoji-2622 { background-position: -320px -800px; } -.emoji-2623 { background-position: -340px -800px; } -.emoji-2626 { background-position: -360px -800px; } -.emoji-262A { background-position: -380px -800px; } -.emoji-262E { background-position: -400px -800px; } -.emoji-262F { background-position: -420px -800px; } -.emoji-2638 { background-position: -440px -800px; } -.emoji-2639 { background-position: -460px -800px; } -.emoji-263A { background-position: -480px -800px; } -.emoji-2648 { background-position: -500px -800px; } -.emoji-2649 { background-position: -520px -800px; } -.emoji-264A { background-position: -540px -800px; } -.emoji-264B { background-position: -560px -800px; } -.emoji-264C { background-position: -580px -800px; } -.emoji-264D { background-position: -600px -800px; } -.emoji-264E { background-position: -620px -800px; } -.emoji-264F { background-position: -640px -800px; } -.emoji-2650 { background-position: -660px -800px; } -.emoji-2651 { background-position: -680px -800px; } -.emoji-2652 { background-position: -700px -800px; } -.emoji-2653 { background-position: -720px -800px; } -.emoji-2660 { background-position: -740px -800px; } -.emoji-2663 { background-position: -760px -800px; } -.emoji-2665 { background-position: -780px -800px; } -.emoji-2666 { background-position: -800px -800px; } -.emoji-2668 { background-position: -820px 0; } -.emoji-267B { background-position: -820px -20px; } -.emoji-267F { background-position: -820px -40px; } -.emoji-2692 { background-position: -820px -60px; } -.emoji-2693 { background-position: -820px -80px; } -.emoji-2694 { background-position: -820px -100px; } -.emoji-2696 { background-position: -820px -120px; } -.emoji-2697 { background-position: -820px -140px; } -.emoji-2699 { background-position: -820px -160px; } -.emoji-269B { background-position: -820px -180px; } -.emoji-269C { background-position: -820px -200px; } -.emoji-26A0 { background-position: -820px -220px; } -.emoji-26A1 { background-position: -820px -240px; } -.emoji-26AA { background-position: -820px -260px; } -.emoji-26AB { background-position: -820px -280px; } -.emoji-26B0 { background-position: -820px -300px; } -.emoji-26B1 { background-position: -820px -320px; } -.emoji-26BD { background-position: -820px -340px; } -.emoji-26BE { background-position: -820px -360px; } -.emoji-26C4 { background-position: -820px -380px; } -.emoji-26C5 { background-position: -820px -400px; } -.emoji-26C8 { background-position: -820px -420px; } -.emoji-26CE { background-position: -820px -440px; } -.emoji-26CF { background-position: -820px -460px; } -.emoji-26D1 { background-position: -820px -480px; } -.emoji-26D3 { background-position: -820px -500px; } -.emoji-26D4 { background-position: -820px -520px; } -.emoji-26E9 { background-position: -820px -540px; } -.emoji-26EA { background-position: -820px -560px; } -.emoji-26F0 { background-position: -820px -580px; } -.emoji-26F1 { background-position: -820px -600px; } -.emoji-26F2 { background-position: -820px -620px; } -.emoji-26F3 { background-position: -820px -640px; } -.emoji-26F4 { background-position: -820px -660px; } -.emoji-26F5 { background-position: -820px -680px; } -.emoji-26F7 { background-position: -820px -700px; } -.emoji-26F8 { background-position: -820px -720px; } -.emoji-26F9 { background-position: -820px -740px; } -.emoji-26F9-1F3FB { background-position: -820px -760px; } -.emoji-26F9-1F3FC { background-position: -820px -780px; } -.emoji-26F9-1F3FD { background-position: -820px -800px; } -.emoji-26F9-1F3FE { background-position: 0 -820px; } -.emoji-26F9-1F3FF { background-position: -20px -820px; } -.emoji-26FA { background-position: -40px -820px; } -.emoji-26FD { background-position: -60px -820px; } -.emoji-2702 { background-position: -80px -820px; } -.emoji-2705 { background-position: -100px -820px; } -.emoji-2708 { background-position: -120px -820px; } -.emoji-2709 { background-position: -140px -820px; } -.emoji-270A { background-position: -160px -820px; } -.emoji-270A-1F3FB { background-position: -180px -820px; } -.emoji-270A-1F3FC { background-position: -200px -820px; } -.emoji-270A-1F3FD { background-position: -220px -820px; } -.emoji-270A-1F3FE { background-position: -240px -820px; } -.emoji-270A-1F3FF { background-position: -260px -820px; } -.emoji-270B { background-position: -280px -820px; } -.emoji-270B-1F3FB { background-position: -300px -820px; } -.emoji-270B-1F3FC { background-position: -320px -820px; } -.emoji-270B-1F3FD { background-position: -340px -820px; } -.emoji-270B-1F3FE { background-position: -360px -820px; } -.emoji-270B-1F3FF { background-position: -380px -820px; } -.emoji-270C { background-position: -400px -820px; } -.emoji-270C-1F3FB { background-position: -420px -820px; } -.emoji-270C-1F3FC { background-position: -440px -820px; } -.emoji-270C-1F3FD { background-position: -460px -820px; } -.emoji-270C-1F3FE { background-position: -480px -820px; } -.emoji-270C-1F3FF { background-position: -500px -820px; } -.emoji-270D { background-position: -520px -820px; } -.emoji-270D-1F3FB { background-position: -540px -820px; } -.emoji-270D-1F3FC { background-position: -560px -820px; } -.emoji-270D-1F3FD { background-position: -580px -820px; } -.emoji-270D-1F3FE { background-position: -600px -820px; } -.emoji-270D-1F3FF { background-position: -620px -820px; } -.emoji-270F { background-position: -640px -820px; } -.emoji-2712 { background-position: -660px -820px; } -.emoji-2714 { background-position: -680px -820px; } -.emoji-2716 { background-position: -700px -820px; } -.emoji-271D { background-position: -720px -820px; } -.emoji-2721 { background-position: -740px -820px; } -.emoji-2728 { background-position: -760px -820px; } -.emoji-2733 { background-position: -780px -820px; } -.emoji-2734 { background-position: -800px -820px; } -.emoji-2744 { background-position: -820px -820px; } -.emoji-2747 { background-position: -840px 0; } -.emoji-274C { background-position: -840px -20px; } -.emoji-274E { background-position: -840px -40px; } -.emoji-2753 { background-position: -840px -60px; } -.emoji-2754 { background-position: -840px -80px; } -.emoji-2755 { background-position: -840px -100px; } -.emoji-2757 { background-position: -840px -120px; } -.emoji-2763 { background-position: -840px -140px; } -.emoji-2764 { background-position: -840px -160px; } -.emoji-2795 { background-position: -840px -180px; } -.emoji-2796 { background-position: -840px -200px; } -.emoji-2797 { background-position: -840px -220px; } -.emoji-27A1 { background-position: -840px -240px; } -.emoji-27B0 { background-position: -840px -260px; } -.emoji-27BF { background-position: -840px -280px; } -.emoji-2934 { background-position: -840px -300px; } -.emoji-2935 { background-position: -840px -320px; } -.emoji-2B05 { background-position: -840px -340px; } -.emoji-2B06 { background-position: -840px -360px; } -.emoji-2B07 { background-position: -840px -380px; } -.emoji-2B1B { background-position: -840px -400px; } -.emoji-2B1C { background-position: -840px -420px; } -.emoji-2B50 { background-position: -840px -440px; } -.emoji-2B55 { background-position: -840px -460px; } -.emoji-3030 { background-position: -840px -480px; } -.emoji-303D { background-position: -840px -500px; } -.emoji-3297 { background-position: -840px -520px; } -.emoji-3299 { background-position: -840px -540px; } - -.emoji-icon { - background-image: image-url('emoji.png'); - background-repeat: no-repeat; - height: 20px; - width: 20px; - - @media only screen and (-webkit-min-device-pixel-ratio: 2), - only screen and (min--moz-device-pixel-ratio: 2), - only screen and (-o-min-device-pixel-ratio: 2/1), - only screen and (min-device-pixel-ratio: 2), - only screen and (min-resolution: 192dpi), - only screen and (min-resolution: 2dppx) { - background-image: image-url('emoji@2x.png'); - background-size: 860px 840px; - } +gl-emoji { + display: inline-block; + display: inline-flex; + vertical-align: middle; + font-size: 1.5em; } diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index d2be8dc7a39..0ba00cea8b5 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -1,5 +1,4 @@ .filter-item { - margin-right: 6px; vertical-align: top; &.reset-filters { @@ -14,6 +13,20 @@ width: 132px; } } + + .filter-item:not(:last-child) { + margin-right: 6px; + } + + .sort-filter { + display: inline-block; + float: right; + } + + .dropdown-menu-sort { + left: auto; + right: 0; + } } @media (max-width: $screen-xs-max) { diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 685a4847731..5d1aba4e529 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -149,14 +149,14 @@ header { .header-logo { display: inline-block; - margin: 0 8px 0 3px; + margin: 0 7px 0 2px; position: relative; - top: 7px; + top: 10px; transition-duration: .3s; svg, img { - height: 36px; + height: 28px; } &:hover { @@ -260,24 +260,34 @@ header { font-size: 18px; .navbar-nav { + display: table; + table-layout: fixed; + width: 100%; margin: 0; - float: none !important; - - .visible-xs, - .visible-sm { - display: table-cell !important; - } + text-align: right; } .navbar-collapse { padding-left: 5px; - .nav > li { - display: table-cell; - width: 1%; + .nav > li:not(.hidden-xs) { + display: table-cell!important; + width: 25%; + + a { + margin-right: 8px; + } } } } + + .header-user-dropdown-toggle { + text-align: center; + } + + .header-user-avatar { + float: none; + } } .header-user { diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss index 29d55c44699..0a42b17c1f5 100644 --- a/app/assets/stylesheets/framework/layout.scss +++ b/app/assets/stylesheets/framework/layout.scss @@ -8,6 +8,19 @@ body { &.navless { background-color: $white-light !important; } + + &.card-content { + background-color: $gray-darker; + + .content-wrapper { + padding: 0; + + .container-fluid, + .container-limited { + background-color: $gray-darker; + } + } + } } .container { diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss index d4758d90352..a668a6c4c39 100644 --- a/app/assets/stylesheets/framework/markdown_area.scss +++ b/app/assets/stylesheets/framework/markdown_area.scss @@ -147,6 +147,9 @@ } .atwho-view { + overflow-y: auto; + overflow-x: hidden; + small.description { float: right; padding: 3px 5px; @@ -162,4 +165,8 @@ @include disableAllAnimation; } } + + ul > li { + white-space: nowrap; + } } diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 8978e284f55..40e93032f59 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -73,10 +73,6 @@ right: $gutter_collapsed_width; } } - - &.with-overlay { - padding-right: $gutter_collapsed_width; - } } .right-sidebar { diff --git a/app/assets/stylesheets/framework/tw_bootstrap.scss b/app/assets/stylesheets/framework/tw_bootstrap.scss index ea2d26dd5a0..12a86a64645 100644 --- a/app/assets/stylesheets/framework/tw_bootstrap.scss +++ b/app/assets/stylesheets/framework/tw_bootstrap.scss @@ -86,6 +86,16 @@ position: fixed; } +/* + * Fix <summary> elements on firefox + * See https://github.com/necolas/normalize.css/issues/640 + * and https://github.com/twbs/bootstrap/issues/21060 + * + */ +summary { + display: list-item; +} + @import "bootstrap/responsive-utilities"; // Labels diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index ba0af072716..832fd0a532c 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -248,7 +248,7 @@ $diff-view-modes-border: #c1c1c1; * Fonts */ $monospace_font: 'Menlo', 'Liberation Mono', 'Consolas', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace; -$regular_font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; +$regular_font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; /* * Dropdowns diff --git a/app/assets/stylesheets/framework/zen.scss b/app/assets/stylesheets/framework/zen.scss index 97ade638db6..0c226ff7598 100644 --- a/app/assets/stylesheets/framework/zen.scss +++ b/app/assets/stylesheets/framework/zen.scss @@ -20,8 +20,9 @@ outline: none; resize: none; height: 100vh; + max-height: calc(100vh - 10px); max-width: 900px; - margin: 0 auto; + margin: 0 auto 10px; } .zen-control-leave { diff --git a/app/assets/stylesheets/pages/events.scss b/app/assets/stylesheets/pages/events.scss index 5776d86983a..08398bb43a2 100644 --- a/app/assets/stylesheets/pages/events.scss +++ b/app/assets/stylesheets/pages/events.scss @@ -155,7 +155,7 @@ @media (max-width: $screen-xs-max) { .event-item { - padding-left: $gl-padding; + padding-left: 0; .event-title { white-space: normal; @@ -169,8 +169,7 @@ .event-body { margin: 0; - border-left: 2px solid $events-body-border; - padding-left: 10px; + padding-left: 0; } .event-item-timestamp { diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index d377526e655..84d21e48463 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -73,3 +73,19 @@ } } } + +.mattermost-icon svg { + width: 16px; + height: 16px; + vertical-align: text-bottom; +} + +.mattermost-team-name { + color: $gl-text-color-secondary; +} + +.mattermost-info { + display: block; + color: $gl-text-color-secondary; + margin-top: 10px; +} diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 0b0c4bc130d..f41eeb8ca45 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -3,7 +3,6 @@ * */ .mr-state-widget { - background: $gray-light; color: $gl-text-color; border: 1px solid $border-color; border-radius: 2px; @@ -29,7 +28,7 @@ background-color: $gl-success; } - .accept_merge_request { + .accept-merge-request { &.ci-pending, &.ci-running { @include btn-blue; @@ -42,6 +41,12 @@ @include btn-red; } } + + .dropdown-toggle { + .fa { + color: inherit; + } + } } .accept-control { @@ -103,12 +108,17 @@ @media (max-width: $screen-xs-max) { flex-wrap: wrap; } + + .ci-status-icon > .icon-link > svg { + width: 22px; + height: 22px; + } } .mr-widget-body, .ci_widget, .mr-widget-footer { - padding: $gl-padding; + padding: 16px; } .mr-widget-pipeline-graph { @@ -168,10 +178,6 @@ } } - p:last-child { - margin-bottom: 0; - } - .btn-grouped { margin-left: 0; margin-right: 7px; @@ -334,8 +340,61 @@ } } +.remove-message-pipes { + ul { + margin: 10px 0 0 12px; + padding: 0; + list-style: none; + border-left: 2px solid $border-color; + display: inline-block; + } + + li { + position: relative; + margin: 0; + padding: 0; + display: block; + + span { + margin-left: 15px; + max-height: 20px; + } + } + + li::before { + content: ''; + position: absolute; + border-top: 2px solid $border-color; + height: 1px; + top: 8px; + width: 8px; + } + + li:last-child { + &::before { + top: 18px; + } + + span { + display: block; + position: relative; + top: 5px; + margin-top: 5px; + } + } +} + .mr-source-target { + background-color: $gray-light; line-height: 31px; + border-style: solid; + border-width: 1px; + border-color: $border-color; + border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-bottom: none; + padding: 16px; + margin-bottom: -1px; } .panel-new-merge-request { @@ -420,6 +479,11 @@ } } +.assign-to-me-link { + padding-left: 12px; + white-space: nowrap; +} + .table-holder { .ci-table { @@ -431,6 +495,8 @@ } .merged-buttons { + margin-top: 20px; + .btn { float: left; diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index aad1a8986b0..1a983d8c9ef 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -279,7 +279,7 @@ table.u2f-registrations { } .user-callout { - margin: 24px auto 0; + margin: 0 auto; .bordered-box { border: 1px solid $border-color; @@ -287,6 +287,7 @@ table.u2f-registrations { } .landing { + margin-top: $gl-padding; margin-bottom: $gl-padding; .close { diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 07b93430442..09b85db7d45 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -494,11 +494,11 @@ a.deploy-project-label { .project-stats { font-size: 0; text-align: center; - border-bottom: 1px solid $border-color; .nav { padding-top: 12px; padding-bottom: 12px; + border-bottom: 1px solid $border-color; } .nav > li { @@ -645,30 +645,15 @@ pre.light-well { } .project-last-commit { + background-color: $gray-light; + border: 1px solid $border-color; + border-radius: $border-radius-base; + padding: 12px; + @media (min-width: $screen-sm-min) { margin-top: $gl-padding; } - &.container-fluid { - padding-top: 12px; - padding-bottom: 12px; - background-color: $gray-light; - border: 1px solid $border-color; - border-right-width: 0; - border-left-width: 0; - - @media (min-width: $screen-sm-min) { - border-right-width: 1px; - border-left-width: 1px; - } - } - - &.container-limited { - @media (min-width: 1281px) { - border-radius: $border-radius-base; - } - } - .ci-status { margin-right: $gl-padding; } diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 88ea92c5afb..543d2ece3df 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -182,7 +182,8 @@ input[type="checkbox"]:hover { display: flex; } - .search-field-holder { + .search-field-holder, + .project-filter-form { -webkit-flex: 1 0 auto; flex: 1 0 auto; position: relative; @@ -201,7 +202,8 @@ input[type="checkbox"]:hover { pointer-events: none; } - .search-text-input { + .search-text-input, + .project-filter-form-field { padding-left: $gl-padding + 15px; padding-right: $gl-padding + 15px; } diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index af9ddb9ff80..5f0aede4f5e 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -170,7 +170,11 @@ @media (max-width: $screen-sm-max) { .todos-filters { .dropdown-menu-toggle { - width: 135px; + width: 130px; + } + + .dropdown-menu-toggle-sort { + width: auto; } } } @@ -200,10 +204,6 @@ } .todos-filters { - .row-content-block { - padding-bottom: 50px; - } - .dropdown-menu-toggle { width: 100%; } diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index e4487dbcb87..8d1063fc26f 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -178,3 +178,29 @@ margin-left: $btn-side-margin; } } + +.repo-charts { + .sub-header { + margin: 20px 0; + } + + .sub-header-block.border-top { + margin-top: 20px; + padding: 0; + border-top: 1px solid $white-dark; + border-bottom: none; + } + + .commit-stats li { + font-size: 16px; + } + + .tree-ref-header { + margin-bottom: 20px; + + h4 { + margin: 0; + line-height: 36px; + } + } +} |