summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2017-03-07 16:55:03 +0800
committerLin Jen-Shin <godfat@godfat.org>2017-03-07 16:55:03 +0800
commitfb167787f2c470649195a5d623f489ec2c3a9117 (patch)
treead60222b53a11ee2b29131f57e24ba66dd823c3d /app/assets
parent7c9cff3a744a64848207bfde1aedcfe652f07dce (diff)
parent24f1ee5e9b1f4d9bc8cff581419b091756da8deb (diff)
downloadgitlab-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')
-rw-r--r--app/assets/images/emoji.pngbin1087659 -> 1218558 bytes
-rw-r--r--app/assets/images/emoji/100.pngbin0 -> 793 bytes
-rw-r--r--app/assets/images/emoji/1234.pngbin0 -> 676 bytes
-rw-r--r--app/assets/images/emoji/1F627.pngbin0 -> 821 bytes
-rw-r--r--app/assets/images/emoji/8ball.pngbin0 -> 810 bytes
-rw-r--r--app/assets/images/emoji/a.pngbin0 -> 469 bytes
-rw-r--r--app/assets/images/emoji/ab.pngbin0 -> 505 bytes
-rw-r--r--app/assets/images/emoji/abc.pngbin0 -> 646 bytes
-rw-r--r--app/assets/images/emoji/abcd.pngbin0 -> 670 bytes
-rw-r--r--app/assets/images/emoji/accept.pngbin0 -> 491 bytes
-rw-r--r--app/assets/images/emoji/aerial_tramway.pngbin0 -> 759 bytes
-rw-r--r--app/assets/images/emoji/airplane.pngbin0 -> 1152 bytes
-rw-r--r--app/assets/images/emoji/airplane_arriving.pngbin0 -> 1101 bytes
-rw-r--r--app/assets/images/emoji/airplane_departure.pngbin0 -> 1111 bytes
-rw-r--r--app/assets/images/emoji/airplane_small.pngbin0 -> 1229 bytes
-rw-r--r--app/assets/images/emoji/alarm_clock.pngbin0 -> 1044 bytes
-rw-r--r--app/assets/images/emoji/alembic.pngbin0 -> 953 bytes
-rw-r--r--app/assets/images/emoji/alien.pngbin0 -> 839 bytes
-rw-r--r--app/assets/images/emoji/ambulance.pngbin0 -> 1238 bytes
-rw-r--r--app/assets/images/emoji/amphora.pngbin0 -> 1044 bytes
-rw-r--r--app/assets/images/emoji/anchor.pngbin0 -> 779 bytes
-rw-r--r--app/assets/images/emoji/angel.pngbin0 -> 2077 bytes
-rw-r--r--app/assets/images/emoji/angel_tone1.pngbin0 -> 2088 bytes
-rw-r--r--app/assets/images/emoji/angel_tone2.pngbin0 -> 2075 bytes
-rw-r--r--app/assets/images/emoji/angel_tone3.pngbin0 -> 2078 bytes
-rw-r--r--app/assets/images/emoji/angel_tone4.pngbin0 -> 2076 bytes
-rw-r--r--app/assets/images/emoji/angel_tone5.pngbin0 -> 2078 bytes
-rw-r--r--app/assets/images/emoji/anger.pngbin0 -> 594 bytes
-rw-r--r--app/assets/images/emoji/anger_right.pngbin0 -> 551 bytes
-rw-r--r--app/assets/images/emoji/angry.pngbin0 -> 845 bytes
-rw-r--r--app/assets/images/emoji/ant.pngbin0 -> 1412 bytes
-rw-r--r--app/assets/images/emoji/apple.pngbin0 -> 655 bytes
-rw-r--r--app/assets/images/emoji/aquarius.pngbin0 -> 648 bytes
-rw-r--r--app/assets/images/emoji/aries.pngbin0 -> 711 bytes
-rw-r--r--app/assets/images/emoji/arrow_backward.pngbin0 -> 429 bytes
-rw-r--r--app/assets/images/emoji/arrow_double_down.pngbin0 -> 543 bytes
-rw-r--r--app/assets/images/emoji/arrow_double_up.pngbin0 -> 535 bytes
-rw-r--r--app/assets/images/emoji/arrow_down.pngbin0 -> 512 bytes
-rw-r--r--app/assets/images/emoji/arrow_down_small.pngbin0 -> 455 bytes
-rw-r--r--app/assets/images/emoji/arrow_forward.pngbin0 -> 429 bytes
-rw-r--r--app/assets/images/emoji/arrow_heading_down.pngbin0 -> 563 bytes
-rw-r--r--app/assets/images/emoji/arrow_heading_up.pngbin0 -> 559 bytes
-rw-r--r--app/assets/images/emoji/arrow_left.pngbin0 -> 471 bytes
-rw-r--r--app/assets/images/emoji/arrow_lower_left.pngbin0 -> 520 bytes
-rw-r--r--app/assets/images/emoji/arrow_lower_right.pngbin0 -> 526 bytes
-rw-r--r--app/assets/images/emoji/arrow_right.pngbin0 -> 468 bytes
-rw-r--r--app/assets/images/emoji/arrow_right_hook.pngbin0 -> 644 bytes
-rw-r--r--app/assets/images/emoji/arrow_up.pngbin0 -> 507 bytes
-rw-r--r--app/assets/images/emoji/arrow_up_down.pngbin0 -> 474 bytes
-rw-r--r--app/assets/images/emoji/arrow_up_small.pngbin0 -> 454 bytes
-rw-r--r--app/assets/images/emoji/arrow_upper_left.pngbin0 -> 521 bytes
-rw-r--r--app/assets/images/emoji/arrow_upper_right.pngbin0 -> 524 bytes
-rw-r--r--app/assets/images/emoji/arrows_clockwise.pngbin0 -> 519 bytes
-rw-r--r--app/assets/images/emoji/arrows_counterclockwise.pngbin0 -> 693 bytes
-rw-r--r--app/assets/images/emoji/art.pngbin0 -> 1455 bytes
-rw-r--r--app/assets/images/emoji/articulated_lorry.pngbin0 -> 1710 bytes
-rw-r--r--app/assets/images/emoji/asterisk.pngbin0 -> 627 bytes
-rw-r--r--app/assets/images/emoji/astonished.pngbin0 -> 862 bytes
-rw-r--r--app/assets/images/emoji/athletic_shoe.pngbin0 -> 1595 bytes
-rw-r--r--app/assets/images/emoji/atm.pngbin0 -> 1397 bytes
-rw-r--r--app/assets/images/emoji/atom.pngbin0 -> 912 bytes
-rw-r--r--app/assets/images/emoji/avocado.pngbin0 -> 1520 bytes
-rw-r--r--app/assets/images/emoji/b.pngbin0 -> 391 bytes
-rw-r--r--app/assets/images/emoji/baby.pngbin0 -> 1380 bytes
-rw-r--r--app/assets/images/emoji/baby_bottle.pngbin0 -> 818 bytes
-rw-r--r--app/assets/images/emoji/baby_chick.pngbin0 -> 1181 bytes
-rw-r--r--app/assets/images/emoji/baby_symbol.pngbin0 -> 665 bytes
-rw-r--r--app/assets/images/emoji/baby_tone1.pngbin0 -> 1392 bytes
-rw-r--r--app/assets/images/emoji/baby_tone2.pngbin0 -> 1392 bytes
-rw-r--r--app/assets/images/emoji/baby_tone3.pngbin0 -> 1403 bytes
-rw-r--r--app/assets/images/emoji/baby_tone4.pngbin0 -> 1413 bytes
-rw-r--r--app/assets/images/emoji/baby_tone5.pngbin0 -> 1405 bytes
-rw-r--r--app/assets/images/emoji/back.pngbin0 -> 562 bytes
-rw-r--r--app/assets/images/emoji/bacon.pngbin0 -> 2148 bytes
-rw-r--r--app/assets/images/emoji/badminton.pngbin0 -> 1253 bytes
-rw-r--r--app/assets/images/emoji/baggage_claim.pngbin0 -> 490 bytes
-rw-r--r--app/assets/images/emoji/balloon.pngbin0 -> 501 bytes
-rw-r--r--app/assets/images/emoji/ballot_box.pngbin0 -> 1355 bytes
-rw-r--r--app/assets/images/emoji/ballot_box_with_check.pngbin0 -> 639 bytes
-rw-r--r--app/assets/images/emoji/bamboo.pngbin0 -> 1946 bytes
-rw-r--r--app/assets/images/emoji/banana.pngbin0 -> 1157 bytes
-rw-r--r--app/assets/images/emoji/bangbang.pngbin0 -> 390 bytes
-rw-r--r--app/assets/images/emoji/bank.pngbin0 -> 1358 bytes
-rw-r--r--app/assets/images/emoji/bar_chart.pngbin0 -> 408 bytes
-rw-r--r--app/assets/images/emoji/barber.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/baseball.pngbin0 -> 1185 bytes
-rw-r--r--app/assets/images/emoji/basketball.pngbin0 -> 1546 bytes
-rw-r--r--app/assets/images/emoji/basketball_player.pngbin0 -> 1491 bytes
-rw-r--r--app/assets/images/emoji/basketball_player_tone1.pngbin0 -> 1492 bytes
-rw-r--r--app/assets/images/emoji/basketball_player_tone2.pngbin0 -> 1493 bytes
-rw-r--r--app/assets/images/emoji/basketball_player_tone3.pngbin0 -> 1492 bytes
-rw-r--r--app/assets/images/emoji/basketball_player_tone4.pngbin0 -> 1491 bytes
-rw-r--r--app/assets/images/emoji/basketball_player_tone5.pngbin0 -> 1474 bytes
-rw-r--r--app/assets/images/emoji/bat.pngbin0 -> 1190 bytes
-rw-r--r--app/assets/images/emoji/bath.pngbin0 -> 1238 bytes
-rw-r--r--app/assets/images/emoji/bath_tone1.pngbin0 -> 1235 bytes
-rw-r--r--app/assets/images/emoji/bath_tone2.pngbin0 -> 1231 bytes
-rw-r--r--app/assets/images/emoji/bath_tone3.pngbin0 -> 1236 bytes
-rw-r--r--app/assets/images/emoji/bath_tone4.pngbin0 -> 1252 bytes
-rw-r--r--app/assets/images/emoji/bath_tone5.pngbin0 -> 1239 bytes
-rw-r--r--app/assets/images/emoji/bathtub.pngbin0 -> 767 bytes
-rw-r--r--app/assets/images/emoji/battery.pngbin0 -> 228 bytes
-rw-r--r--app/assets/images/emoji/beach.pngbin0 -> 942 bytes
-rw-r--r--app/assets/images/emoji/beach_umbrella.pngbin0 -> 1486 bytes
-rw-r--r--app/assets/images/emoji/bear.pngbin0 -> 1023 bytes
-rw-r--r--app/assets/images/emoji/bed.pngbin0 -> 1572 bytes
-rw-r--r--app/assets/images/emoji/bee.pngbin0 -> 1378 bytes
-rw-r--r--app/assets/images/emoji/beer.pngbin0 -> 1338 bytes
-rw-r--r--app/assets/images/emoji/beers.pngbin0 -> 2100 bytes
-rw-r--r--app/assets/images/emoji/beetle.pngbin0 -> 1288 bytes
-rw-r--r--app/assets/images/emoji/beginner.pngbin0 -> 545 bytes
-rw-r--r--app/assets/images/emoji/bell.pngbin0 -> 1496 bytes
-rw-r--r--app/assets/images/emoji/bellhop.pngbin0 -> 891 bytes
-rw-r--r--app/assets/images/emoji/bento.pngbin0 -> 1127 bytes
-rw-r--r--app/assets/images/emoji/bicyclist.pngbin0 -> 1911 bytes
-rw-r--r--app/assets/images/emoji/bicyclist_tone1.pngbin0 -> 1860 bytes
-rw-r--r--app/assets/images/emoji/bicyclist_tone2.pngbin0 -> 1866 bytes
-rw-r--r--app/assets/images/emoji/bicyclist_tone3.pngbin0 -> 1851 bytes
-rw-r--r--app/assets/images/emoji/bicyclist_tone4.pngbin0 -> 1852 bytes
-rw-r--r--app/assets/images/emoji/bicyclist_tone5.pngbin0 -> 1840 bytes
-rw-r--r--app/assets/images/emoji/bike.pngbin0 -> 1505 bytes
-rw-r--r--app/assets/images/emoji/bikini.pngbin0 -> 613 bytes
-rw-r--r--app/assets/images/emoji/biohazard.pngbin0 -> 794 bytes
-rw-r--r--app/assets/images/emoji/bird.pngbin0 -> 1068 bytes
-rw-r--r--app/assets/images/emoji/birthday.pngbin0 -> 2219 bytes
-rw-r--r--app/assets/images/emoji/black_circle.pngbin0 -> 374 bytes
-rw-r--r--app/assets/images/emoji/black_heart.pngbin0 -> 435 bytes
-rw-r--r--app/assets/images/emoji/black_joker.pngbin0 -> 1091 bytes
-rw-r--r--app/assets/images/emoji/black_large_square.pngbin0 -> 110 bytes
-rw-r--r--app/assets/images/emoji/black_medium_small_square.pngbin0 -> 110 bytes
-rw-r--r--app/assets/images/emoji/black_medium_square.pngbin0 -> 108 bytes
-rw-r--r--app/assets/images/emoji/black_nib.pngbin0 -> 620 bytes
-rw-r--r--app/assets/images/emoji/black_small_square.pngbin0 -> 108 bytes
-rw-r--r--app/assets/images/emoji/black_square_button.pngbin0 -> 122 bytes
-rw-r--r--app/assets/images/emoji/blossom.pngbin0 -> 867 bytes
-rw-r--r--app/assets/images/emoji/blowfish.pngbin0 -> 1620 bytes
-rw-r--r--app/assets/images/emoji/blue_book.pngbin0 -> 1347 bytes
-rw-r--r--app/assets/images/emoji/blue_car.pngbin0 -> 1275 bytes
-rw-r--r--app/assets/images/emoji/blue_heart.pngbin0 -> 435 bytes
-rw-r--r--app/assets/images/emoji/blush.pngbin0 -> 812 bytes
-rw-r--r--app/assets/images/emoji/boar.pngbin0 -> 1366 bytes
-rw-r--r--app/assets/images/emoji/bomb.pngbin0 -> 702 bytes
-rw-r--r--app/assets/images/emoji/book.pngbin0 -> 1716 bytes
-rw-r--r--app/assets/images/emoji/bookmark.pngbin0 -> 747 bytes
-rw-r--r--app/assets/images/emoji/bookmark_tabs.pngbin0 -> 1395 bytes
-rw-r--r--app/assets/images/emoji/books.pngbin0 -> 2474 bytes
-rw-r--r--app/assets/images/emoji/boom.pngbin0 -> 1110 bytes
-rw-r--r--app/assets/images/emoji/boot.pngbin0 -> 662 bytes
-rw-r--r--app/assets/images/emoji/bouquet.pngbin0 -> 1662 bytes
-rw-r--r--app/assets/images/emoji/bow.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/bow_and_arrow.pngbin0 -> 1402 bytes
-rw-r--r--app/assets/images/emoji/bow_tone1.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/bow_tone2.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/bow_tone3.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/bow_tone4.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/bow_tone5.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/bowling.pngbin0 -> 1426 bytes
-rw-r--r--app/assets/images/emoji/boxing_glove.pngbin0 -> 1575 bytes
-rw-r--r--app/assets/images/emoji/boy.pngbin0 -> 881 bytes
-rw-r--r--app/assets/images/emoji/boy_tone1.pngbin0 -> 876 bytes
-rw-r--r--app/assets/images/emoji/boy_tone2.pngbin0 -> 876 bytes
-rw-r--r--app/assets/images/emoji/boy_tone3.pngbin0 -> 876 bytes
-rw-r--r--app/assets/images/emoji/boy_tone4.pngbin0 -> 870 bytes
-rw-r--r--app/assets/images/emoji/boy_tone5.pngbin0 -> 873 bytes
-rw-r--r--app/assets/images/emoji/bread.pngbin0 -> 1419 bytes
-rw-r--r--app/assets/images/emoji/bride_with_veil.pngbin0 -> 2452 bytes
-rw-r--r--app/assets/images/emoji/bride_with_veil_tone1.pngbin0 -> 2464 bytes
-rw-r--r--app/assets/images/emoji/bride_with_veil_tone2.pngbin0 -> 2457 bytes
-rw-r--r--app/assets/images/emoji/bride_with_veil_tone3.pngbin0 -> 2463 bytes
-rw-r--r--app/assets/images/emoji/bride_with_veil_tone4.pngbin0 -> 2463 bytes
-rw-r--r--app/assets/images/emoji/bride_with_veil_tone5.pngbin0 -> 2462 bytes
-rw-r--r--app/assets/images/emoji/bridge_at_night.pngbin0 -> 637 bytes
-rw-r--r--app/assets/images/emoji/briefcase.pngbin0 -> 1275 bytes
-rw-r--r--app/assets/images/emoji/broken_heart.pngbin0 -> 556 bytes
-rw-r--r--app/assets/images/emoji/bug.pngbin0 -> 1599 bytes
-rw-r--r--app/assets/images/emoji/bulb.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/bullettrain_front.pngbin0 -> 1450 bytes
-rw-r--r--app/assets/images/emoji/bullettrain_side.pngbin0 -> 1538 bytes
-rw-r--r--app/assets/images/emoji/burrito.pngbin0 -> 2938 bytes
-rw-r--r--app/assets/images/emoji/bus.pngbin0 -> 1086 bytes
-rw-r--r--app/assets/images/emoji/busstop.pngbin0 -> 626 bytes
-rw-r--r--app/assets/images/emoji/bust_in_silhouette.pngbin0 -> 426 bytes
-rw-r--r--app/assets/images/emoji/busts_in_silhouette.pngbin0 -> 526 bytes
-rw-r--r--app/assets/images/emoji/butterfly.pngbin0 -> 1981 bytes
-rw-r--r--app/assets/images/emoji/cactus.pngbin0 -> 628 bytes
-rw-r--r--app/assets/images/emoji/cake.pngbin0 -> 2266 bytes
-rw-r--r--app/assets/images/emoji/calendar.pngbin0 -> 2077 bytes
-rw-r--r--app/assets/images/emoji/calendar_spiral.pngbin0 -> 1491 bytes
-rw-r--r--app/assets/images/emoji/call_me.pngbin0 -> 894 bytes
-rw-r--r--app/assets/images/emoji/call_me_tone1.pngbin0 -> 893 bytes
-rw-r--r--app/assets/images/emoji/call_me_tone2.pngbin0 -> 891 bytes
-rw-r--r--app/assets/images/emoji/call_me_tone3.pngbin0 -> 891 bytes
-rw-r--r--app/assets/images/emoji/call_me_tone4.pngbin0 -> 891 bytes
-rw-r--r--app/assets/images/emoji/call_me_tone5.pngbin0 -> 893 bytes
-rw-r--r--app/assets/images/emoji/calling.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/camel.pngbin0 -> 1190 bytes
-rw-r--r--app/assets/images/emoji/camera.pngbin0 -> 1783 bytes
-rw-r--r--app/assets/images/emoji/camera_with_flash.pngbin0 -> 2097 bytes
-rw-r--r--app/assets/images/emoji/camping.pngbin0 -> 1513 bytes
-rw-r--r--app/assets/images/emoji/cancer.pngbin0 -> 729 bytes
-rw-r--r--app/assets/images/emoji/candle.pngbin0 -> 1250 bytes
-rw-r--r--app/assets/images/emoji/candy.pngbin0 -> 1054 bytes
-rw-r--r--app/assets/images/emoji/canoe.pngbin0 -> 1244 bytes
-rw-r--r--app/assets/images/emoji/capital_abcd.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/capricorn.pngbin0 -> 688 bytes
-rw-r--r--app/assets/images/emoji/card_box.pngbin0 -> 1523 bytes
-rw-r--r--app/assets/images/emoji/card_index.pngbin0 -> 1929 bytes
-rw-r--r--app/assets/images/emoji/carousel_horse.pngbin0 -> 1739 bytes
-rw-r--r--app/assets/images/emoji/carrot.pngbin0 -> 1236 bytes
-rw-r--r--app/assets/images/emoji/cartwheel.pngbin0 -> 1233 bytes
-rw-r--r--app/assets/images/emoji/cartwheel_tone1.pngbin0 -> 1234 bytes
-rw-r--r--app/assets/images/emoji/cartwheel_tone2.pngbin0 -> 1235 bytes
-rw-r--r--app/assets/images/emoji/cartwheel_tone3.pngbin0 -> 1229 bytes
-rw-r--r--app/assets/images/emoji/cartwheel_tone4.pngbin0 -> 1227 bytes
-rw-r--r--app/assets/images/emoji/cartwheel_tone5.pngbin0 -> 1214 bytes
-rw-r--r--app/assets/images/emoji/cat.pngbin0 -> 1354 bytes
-rw-r--r--app/assets/images/emoji/cat2.pngbin0 -> 1781 bytes
-rw-r--r--app/assets/images/emoji/cd.pngbin0 -> 908 bytes
-rw-r--r--app/assets/images/emoji/chains.pngbin0 -> 708 bytes
-rw-r--r--app/assets/images/emoji/champagne.pngbin0 -> 1205 bytes
-rw-r--r--app/assets/images/emoji/champagne_glass.pngbin0 -> 1984 bytes
-rw-r--r--app/assets/images/emoji/chart.pngbin0 -> 724 bytes
-rw-r--r--app/assets/images/emoji/chart_with_downwards_trend.pngbin0 -> 709 bytes
-rw-r--r--app/assets/images/emoji/chart_with_upwards_trend.pngbin0 -> 688 bytes
-rw-r--r--app/assets/images/emoji/checkered_flag.pngbin0 -> 787 bytes
-rw-r--r--app/assets/images/emoji/cheese.pngbin0 -> 1697 bytes
-rw-r--r--app/assets/images/emoji/cherries.pngbin0 -> 1211 bytes
-rw-r--r--app/assets/images/emoji/cherry_blossom.pngbin0 -> 1129 bytes
-rw-r--r--app/assets/images/emoji/chestnut.pngbin0 -> 1337 bytes
-rw-r--r--app/assets/images/emoji/chicken.pngbin0 -> 1267 bytes
-rw-r--r--app/assets/images/emoji/children_crossing.pngbin0 -> 778 bytes
-rw-r--r--app/assets/images/emoji/chipmunk.pngbin0 -> 1454 bytes
-rw-r--r--app/assets/images/emoji/chocolate_bar.pngbin0 -> 771 bytes
-rw-r--r--app/assets/images/emoji/christmas_tree.pngbin0 -> 1542 bytes
-rw-r--r--app/assets/images/emoji/church.pngbin0 -> 1298 bytes
-rw-r--r--app/assets/images/emoji/cinema.pngbin0 -> 585 bytes
-rw-r--r--app/assets/images/emoji/circus_tent.pngbin0 -> 1369 bytes
-rw-r--r--app/assets/images/emoji/city_dusk.pngbin0 -> 431 bytes
-rw-r--r--app/assets/images/emoji/city_sunset.pngbin0 -> 997 bytes
-rw-r--r--app/assets/images/emoji/cityscape.pngbin0 -> 599 bytes
-rw-r--r--app/assets/images/emoji/cl.pngbin0 -> 393 bytes
-rw-r--r--app/assets/images/emoji/clap.pngbin0 -> 1456 bytes
-rw-r--r--app/assets/images/emoji/clap_tone1.pngbin0 -> 1458 bytes
-rw-r--r--app/assets/images/emoji/clap_tone2.pngbin0 -> 1458 bytes
-rw-r--r--app/assets/images/emoji/clap_tone3.pngbin0 -> 1458 bytes
-rw-r--r--app/assets/images/emoji/clap_tone4.pngbin0 -> 1458 bytes
-rw-r--r--app/assets/images/emoji/clap_tone5.pngbin0 -> 1444 bytes
-rw-r--r--app/assets/images/emoji/clapper.pngbin0 -> 1535 bytes
-rw-r--r--app/assets/images/emoji/classical_building.pngbin0 -> 1006 bytes
-rw-r--r--app/assets/images/emoji/clipboard.pngbin0 -> 1345 bytes
-rw-r--r--app/assets/images/emoji/clock.pngbin0 -> 592 bytes
-rw-r--r--app/assets/images/emoji/clock1.pngbin0 -> 586 bytes
-rw-r--r--app/assets/images/emoji/clock10.pngbin0 -> 593 bytes
-rw-r--r--app/assets/images/emoji/clock1030.pngbin0 -> 530 bytes
-rw-r--r--app/assets/images/emoji/clock11.pngbin0 -> 590 bytes
-rw-r--r--app/assets/images/emoji/clock1130.pngbin0 -> 583 bytes
-rw-r--r--app/assets/images/emoji/clock12.pngbin0 -> 480 bytes
-rw-r--r--app/assets/images/emoji/clock1230.pngbin0 -> 579 bytes
-rw-r--r--app/assets/images/emoji/clock130.pngbin0 -> 526 bytes
-rw-r--r--app/assets/images/emoji/clock2.pngbin0 -> 591 bytes
-rw-r--r--app/assets/images/emoji/clock230.pngbin0 -> 576 bytes
-rw-r--r--app/assets/images/emoji/clock3.pngbin0 -> 482 bytes
-rw-r--r--app/assets/images/emoji/clock330.pngbin0 -> 568 bytes
-rw-r--r--app/assets/images/emoji/clock4.pngbin0 -> 592 bytes
-rw-r--r--app/assets/images/emoji/clock430.pngbin0 -> 531 bytes
-rw-r--r--app/assets/images/emoji/clock5.pngbin0 -> 585 bytes
-rw-r--r--app/assets/images/emoji/clock530.pngbin0 -> 552 bytes
-rw-r--r--app/assets/images/emoji/clock6.pngbin0 -> 466 bytes
-rw-r--r--app/assets/images/emoji/clock630.pngbin0 -> 536 bytes
-rw-r--r--app/assets/images/emoji/clock7.pngbin0 -> 581 bytes
-rw-r--r--app/assets/images/emoji/clock730.pngbin0 -> 531 bytes
-rw-r--r--app/assets/images/emoji/clock8.pngbin0 -> 590 bytes
-rw-r--r--app/assets/images/emoji/clock830.pngbin0 -> 570 bytes
-rw-r--r--app/assets/images/emoji/clock9.pngbin0 -> 484 bytes
-rw-r--r--app/assets/images/emoji/clock930.pngbin0 -> 576 bytes
-rw-r--r--app/assets/images/emoji/closed_book.pngbin0 -> 1359 bytes
-rw-r--r--app/assets/images/emoji/closed_lock_with_key.pngbin0 -> 1250 bytes
-rw-r--r--app/assets/images/emoji/closed_umbrella.pngbin0 -> 1002 bytes
-rw-r--r--app/assets/images/emoji/cloud.pngbin0 -> 626 bytes
-rw-r--r--app/assets/images/emoji/cloud_lightning.pngbin0 -> 767 bytes
-rw-r--r--app/assets/images/emoji/cloud_rain.pngbin0 -> 876 bytes
-rw-r--r--app/assets/images/emoji/cloud_snow.pngbin0 -> 823 bytes
-rw-r--r--app/assets/images/emoji/cloud_tornado.pngbin0 -> 1519 bytes
-rw-r--r--app/assets/images/emoji/clown.pngbin0 -> 1818 bytes
-rw-r--r--app/assets/images/emoji/clubs.pngbin0 -> 458 bytes
-rw-r--r--app/assets/images/emoji/cocktail.pngbin0 -> 1027 bytes
-rw-r--r--app/assets/images/emoji/coffee.pngbin0 -> 1679 bytes
-rw-r--r--app/assets/images/emoji/coffin.pngbin0 -> 2195 bytes
-rw-r--r--app/assets/images/emoji/cold_sweat.pngbin0 -> 971 bytes
-rw-r--r--app/assets/images/emoji/comet.pngbin0 -> 1819 bytes
-rw-r--r--app/assets/images/emoji/compression.pngbin0 -> 1612 bytes
-rw-r--r--app/assets/images/emoji/computer.pngbin0 -> 369 bytes
-rw-r--r--app/assets/images/emoji/confetti_ball.pngbin0 -> 1703 bytes
-rw-r--r--app/assets/images/emoji/confounded.pngbin0 -> 844 bytes
-rw-r--r--app/assets/images/emoji/confused.pngbin0 -> 647 bytes
-rw-r--r--app/assets/images/emoji/congratulations.pngbin0 -> 729 bytes
-rw-r--r--app/assets/images/emoji/construction.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/construction_site.pngbin0 -> 668 bytes
-rw-r--r--app/assets/images/emoji/construction_worker.pngbin0 -> 1126 bytes
-rw-r--r--app/assets/images/emoji/construction_worker_tone1.pngbin0 -> 1102 bytes
-rw-r--r--app/assets/images/emoji/construction_worker_tone2.pngbin0 -> 1102 bytes
-rw-r--r--app/assets/images/emoji/construction_worker_tone3.pngbin0 -> 1102 bytes
-rw-r--r--app/assets/images/emoji/construction_worker_tone4.pngbin0 -> 1095 bytes
-rw-r--r--app/assets/images/emoji/construction_worker_tone5.pngbin0 -> 1119 bytes
-rw-r--r--app/assets/images/emoji/control_knobs.pngbin0 -> 1104 bytes
-rw-r--r--app/assets/images/emoji/convenience_store.pngbin0 -> 528 bytes
-rw-r--r--app/assets/images/emoji/cookie.pngbin0 -> 1351 bytes
-rw-r--r--app/assets/images/emoji/cooking.pngbin0 -> 764 bytes
-rw-r--r--app/assets/images/emoji/cool.pngbin0 -> 396 bytes
-rw-r--r--app/assets/images/emoji/cop.pngbin0 -> 1440 bytes
-rw-r--r--app/assets/images/emoji/cop_tone1.pngbin0 -> 1421 bytes
-rw-r--r--app/assets/images/emoji/cop_tone2.pngbin0 -> 1424 bytes
-rw-r--r--app/assets/images/emoji/cop_tone3.pngbin0 -> 1419 bytes
-rw-r--r--app/assets/images/emoji/cop_tone4.pngbin0 -> 1417 bytes
-rw-r--r--app/assets/images/emoji/cop_tone5.pngbin0 -> 1433 bytes
-rw-r--r--app/assets/images/emoji/copyright.pngbin0 -> 530 bytes
-rw-r--r--app/assets/images/emoji/corn.pngbin0 -> 1547 bytes
-rw-r--r--app/assets/images/emoji/couch.pngbin0 -> 1362 bytes
-rw-r--r--app/assets/images/emoji/couple.pngbin0 -> 1537 bytes
-rw-r--r--app/assets/images/emoji/couple_mm.pngbin0 -> 1091 bytes
-rw-r--r--app/assets/images/emoji/couple_with_heart.pngbin0 -> 1285 bytes
-rw-r--r--app/assets/images/emoji/couple_ww.pngbin0 -> 1034 bytes
-rw-r--r--app/assets/images/emoji/couplekiss.pngbin0 -> 1380 bytes
-rw-r--r--app/assets/images/emoji/cow.pngbin0 -> 1640 bytes
-rw-r--r--app/assets/images/emoji/cow2.pngbin0 -> 1810 bytes
-rw-r--r--app/assets/images/emoji/cowboy.pngbin0 -> 1353 bytes
-rw-r--r--app/assets/images/emoji/crab.pngbin0 -> 1475 bytes
-rw-r--r--app/assets/images/emoji/crayon.pngbin0 -> 633 bytes
-rw-r--r--app/assets/images/emoji/credit_card.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/crescent_moon.pngbin0 -> 446 bytes
-rw-r--r--app/assets/images/emoji/cricket.pngbin0 -> 1060 bytes
-rw-r--r--app/assets/images/emoji/crocodile.pngbin0 -> 2408 bytes
-rw-r--r--app/assets/images/emoji/croissant.pngbin0 -> 1313 bytes
-rw-r--r--app/assets/images/emoji/cross.pngbin0 -> 408 bytes
-rw-r--r--app/assets/images/emoji/crossed_flags.pngbin0 -> 1239 bytes
-rw-r--r--app/assets/images/emoji/crossed_swords.pngbin0 -> 1591 bytes
-rw-r--r--app/assets/images/emoji/crown.pngbin0 -> 1534 bytes
-rw-r--r--app/assets/images/emoji/cruise_ship.pngbin0 -> 2272 bytes
-rw-r--r--app/assets/images/emoji/cry.pngbin0 -> 1123 bytes
-rw-r--r--app/assets/images/emoji/crying_cat_face.pngbin0 -> 1875 bytes
-rw-r--r--app/assets/images/emoji/crystal_ball.pngbin0 -> 1913 bytes
-rw-r--r--app/assets/images/emoji/cucumber.pngbin0 -> 1357 bytes
-rw-r--r--app/assets/images/emoji/cupid.pngbin0 -> 846 bytes
-rw-r--r--app/assets/images/emoji/curly_loop.pngbin0 -> 545 bytes
-rw-r--r--app/assets/images/emoji/currency_exchange.pngbin0 -> 576 bytes
-rw-r--r--app/assets/images/emoji/curry.pngbin0 -> 1754 bytes
-rw-r--r--app/assets/images/emoji/custard.pngbin0 -> 1273 bytes
-rw-r--r--app/assets/images/emoji/customs.pngbin0 -> 648 bytes
-rw-r--r--app/assets/images/emoji/cyclone.pngbin0 -> 797 bytes
-rw-r--r--app/assets/images/emoji/dagger.pngbin0 -> 916 bytes
-rw-r--r--app/assets/images/emoji/dancer.pngbin0 -> 1405 bytes
-rw-r--r--app/assets/images/emoji/dancer_tone1.pngbin0 -> 1420 bytes
-rw-r--r--app/assets/images/emoji/dancer_tone2.pngbin0 -> 1423 bytes
-rw-r--r--app/assets/images/emoji/dancer_tone3.pngbin0 -> 1429 bytes
-rw-r--r--app/assets/images/emoji/dancer_tone4.pngbin0 -> 1428 bytes
-rw-r--r--app/assets/images/emoji/dancer_tone5.pngbin0 -> 1418 bytes
-rw-r--r--app/assets/images/emoji/dancers.pngbin0 -> 1872 bytes
-rw-r--r--app/assets/images/emoji/dango.pngbin0 -> 802 bytes
-rw-r--r--app/assets/images/emoji/dark_sunglasses.pngbin0 -> 829 bytes
-rw-r--r--app/assets/images/emoji/dart.pngbin0 -> 1374 bytes
-rw-r--r--app/assets/images/emoji/dash.pngbin0 -> 840 bytes
-rw-r--r--app/assets/images/emoji/date.pngbin0 -> 788 bytes
-rw-r--r--app/assets/images/emoji/deciduous_tree.pngbin0 -> 1267 bytes
-rw-r--r--app/assets/images/emoji/deer.pngbin0 -> 1606 bytes
-rw-r--r--app/assets/images/emoji/department_store.pngbin0 -> 673 bytes
-rw-r--r--app/assets/images/emoji/desert.pngbin0 -> 1443 bytes
-rw-r--r--app/assets/images/emoji/desktop.pngbin0 -> 311 bytes
-rw-r--r--app/assets/images/emoji/diamond_shape_with_a_dot_inside.pngbin0 -> 693 bytes
-rw-r--r--app/assets/images/emoji/diamonds.pngbin0 -> 247 bytes
-rw-r--r--app/assets/images/emoji/disappointed.pngbin0 -> 757 bytes
-rw-r--r--app/assets/images/emoji/disappointed_relieved.pngbin0 -> 835 bytes
-rw-r--r--app/assets/images/emoji/dividers.pngbin0 -> 810 bytes
-rw-r--r--app/assets/images/emoji/dizzy.pngbin0 -> 795 bytes
-rw-r--r--app/assets/images/emoji/dizzy_face.pngbin0 -> 710 bytes
-rw-r--r--app/assets/images/emoji/do_not_litter.pngbin0 -> 1010 bytes
-rw-r--r--app/assets/images/emoji/dog.pngbin0 -> 1674 bytes
-rw-r--r--app/assets/images/emoji/dog2.pngbin0 -> 2085 bytes
-rw-r--r--app/assets/images/emoji/dollar.pngbin0 -> 405 bytes
-rw-r--r--app/assets/images/emoji/dolls.pngbin0 -> 2249 bytes
-rw-r--r--app/assets/images/emoji/dolphin.pngbin0 -> 1697 bytes
-rw-r--r--app/assets/images/emoji/door.pngbin0 -> 1105 bytes
-rw-r--r--app/assets/images/emoji/doughnut.pngbin0 -> 1322 bytes
-rw-r--r--app/assets/images/emoji/dove.pngbin0 -> 967 bytes
-rw-r--r--app/assets/images/emoji/dragon.pngbin0 -> 1574 bytes
-rw-r--r--app/assets/images/emoji/dragon_face.pngbin0 -> 1769 bytes
-rw-r--r--app/assets/images/emoji/dress.pngbin0 -> 1001 bytes
-rw-r--r--app/assets/images/emoji/dromedary_camel.pngbin0 -> 1515 bytes
-rw-r--r--app/assets/images/emoji/drooling_face.pngbin0 -> 1049 bytes
-rw-r--r--app/assets/images/emoji/droplet.pngbin0 -> 411 bytes
-rw-r--r--app/assets/images/emoji/drum.pngbin0 -> 1870 bytes
-rw-r--r--app/assets/images/emoji/duck.pngbin0 -> 1729 bytes
-rw-r--r--app/assets/images/emoji/dvd.pngbin0 -> 933 bytes
-rw-r--r--app/assets/images/emoji/e-mail.pngbin0 -> 1196 bytes
-rw-r--r--app/assets/images/emoji/eagle.pngbin0 -> 2222 bytes
-rw-r--r--app/assets/images/emoji/ear.pngbin0 -> 860 bytes
-rw-r--r--app/assets/images/emoji/ear_of_rice.pngbin0 -> 1422 bytes
-rw-r--r--app/assets/images/emoji/ear_tone1.pngbin0 -> 860 bytes
-rw-r--r--app/assets/images/emoji/ear_tone2.pngbin0 -> 860 bytes
-rw-r--r--app/assets/images/emoji/ear_tone3.pngbin0 -> 860 bytes
-rw-r--r--app/assets/images/emoji/ear_tone4.pngbin0 -> 860 bytes
-rw-r--r--app/assets/images/emoji/ear_tone5.pngbin0 -> 860 bytes
-rw-r--r--app/assets/images/emoji/earth_africa.pngbin0 -> 978 bytes
-rw-r--r--app/assets/images/emoji/earth_americas.pngbin0 -> 1031 bytes
-rw-r--r--app/assets/images/emoji/earth_asia.pngbin0 -> 966 bytes
-rw-r--r--app/assets/images/emoji/egg.pngbin0 -> 710 bytes
-rw-r--r--app/assets/images/emoji/eggplant.pngbin0 -> 773 bytes
-rw-r--r--app/assets/images/emoji/eight.pngbin0 -> 608 bytes
-rw-r--r--app/assets/images/emoji/eight_pointed_black_star.pngbin0 -> 493 bytes
-rw-r--r--app/assets/images/emoji/eight_spoked_asterisk.pngbin0 -> 493 bytes
-rw-r--r--app/assets/images/emoji/eject.pngbin0 -> 548 bytes
-rw-r--r--app/assets/images/emoji/electric_plug.pngbin0 -> 548 bytes
-rw-r--r--app/assets/images/emoji/elephant.pngbin0 -> 1293 bytes
-rw-r--r--app/assets/images/emoji/end.pngbin0 -> 393 bytes
-rw-r--r--app/assets/images/emoji/envelope.pngbin0 -> 916 bytes
-rw-r--r--app/assets/images/emoji/envelope_with_arrow.pngbin0 -> 1062 bytes
-rw-r--r--app/assets/images/emoji/euro.pngbin0 -> 460 bytes
-rw-r--r--app/assets/images/emoji/european_castle.pngbin0 -> 965 bytes
-rw-r--r--app/assets/images/emoji/european_post_office.pngbin0 -> 551 bytes
-rw-r--r--app/assets/images/emoji/evergreen_tree.pngbin0 -> 719 bytes
-rw-r--r--app/assets/images/emoji/exclamation.pngbin0 -> 354 bytes
-rw-r--r--app/assets/images/emoji/expressionless.pngbin0 -> 438 bytes
-rw-r--r--app/assets/images/emoji/eye.pngbin0 -> 664 bytes
-rw-r--r--app/assets/images/emoji/eye_in_speech_bubble.pngbin0 -> 698 bytes
-rw-r--r--app/assets/images/emoji/eyeglasses.pngbin0 -> 577 bytes
-rw-r--r--app/assets/images/emoji/eyes.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/face_palm.pngbin0 -> 1523 bytes
-rw-r--r--app/assets/images/emoji/face_palm_tone1.pngbin0 -> 1563 bytes
-rw-r--r--app/assets/images/emoji/face_palm_tone2.pngbin0 -> 1547 bytes
-rw-r--r--app/assets/images/emoji/face_palm_tone3.pngbin0 -> 1550 bytes
-rw-r--r--app/assets/images/emoji/face_palm_tone4.pngbin0 -> 1553 bytes
-rw-r--r--app/assets/images/emoji/face_palm_tone5.pngbin0 -> 1532 bytes
-rw-r--r--app/assets/images/emoji/factory.pngbin0 -> 936 bytes
-rw-r--r--app/assets/images/emoji/fallen_leaf.pngbin0 -> 951 bytes
-rw-r--r--app/assets/images/emoji/family.pngbin0 -> 1433 bytes
-rw-r--r--app/assets/images/emoji/family_mmb.pngbin0 -> 1206 bytes
-rw-r--r--app/assets/images/emoji/family_mmbb.pngbin0 -> 1349 bytes
-rw-r--r--app/assets/images/emoji/family_mmg.pngbin0 -> 1361 bytes
-rw-r--r--app/assets/images/emoji/family_mmgb.pngbin0 -> 1626 bytes
-rw-r--r--app/assets/images/emoji/family_mmgg.pngbin0 -> 1448 bytes
-rw-r--r--app/assets/images/emoji/family_mwbb.pngbin0 -> 1638 bytes
-rw-r--r--app/assets/images/emoji/family_mwg.pngbin0 -> 1554 bytes
-rw-r--r--app/assets/images/emoji/family_mwgb.pngbin0 -> 1837 bytes
-rw-r--r--app/assets/images/emoji/family_mwgg.pngbin0 -> 1738 bytes
-rw-r--r--app/assets/images/emoji/family_wwb.pngbin0 -> 1155 bytes
-rw-r--r--app/assets/images/emoji/family_wwbb.pngbin0 -> 1289 bytes
-rw-r--r--app/assets/images/emoji/family_wwg.pngbin0 -> 1286 bytes
-rw-r--r--app/assets/images/emoji/family_wwgb.pngbin0 -> 1550 bytes
-rw-r--r--app/assets/images/emoji/family_wwgg.pngbin0 -> 1374 bytes
-rw-r--r--app/assets/images/emoji/fast_forward.pngbin0 -> 523 bytes
-rw-r--r--app/assets/images/emoji/fax.pngbin0 -> 1188 bytes
-rw-r--r--app/assets/images/emoji/fearful.pngbin0 -> 1002 bytes
-rw-r--r--app/assets/images/emoji/feet.pngbin0 -> 603 bytes
-rw-r--r--app/assets/images/emoji/fencer.pngbin0 -> 1342 bytes
-rw-r--r--app/assets/images/emoji/ferris_wheel.pngbin0 -> 2185 bytes
-rw-r--r--app/assets/images/emoji/ferry.pngbin0 -> 528 bytes
-rw-r--r--app/assets/images/emoji/field_hockey.pngbin0 -> 947 bytes
-rw-r--r--app/assets/images/emoji/file_cabinet.pngbin0 -> 1420 bytes
-rw-r--r--app/assets/images/emoji/file_folder.pngbin0 -> 1445 bytes
-rw-r--r--app/assets/images/emoji/film_frames.pngbin0 -> 560 bytes
-rw-r--r--app/assets/images/emoji/fingers_crossed.pngbin0 -> 1050 bytes
-rw-r--r--app/assets/images/emoji/fingers_crossed_tone1.pngbin0 -> 1047 bytes
-rw-r--r--app/assets/images/emoji/fingers_crossed_tone2.pngbin0 -> 1050 bytes
-rw-r--r--app/assets/images/emoji/fingers_crossed_tone3.pngbin0 -> 1050 bytes
-rw-r--r--app/assets/images/emoji/fingers_crossed_tone4.pngbin0 -> 1046 bytes
-rw-r--r--app/assets/images/emoji/fingers_crossed_tone5.pngbin0 -> 1050 bytes
-rw-r--r--app/assets/images/emoji/fire.pngbin0 -> 1020 bytes
-rw-r--r--app/assets/images/emoji/fire_engine.pngbin0 -> 1656 bytes
-rw-r--r--app/assets/images/emoji/fireworks.pngbin0 -> 1364 bytes
-rw-r--r--app/assets/images/emoji/first_place.pngbin0 -> 1419 bytes
-rw-r--r--app/assets/images/emoji/first_quarter_moon.pngbin0 -> 1152 bytes
-rw-r--r--app/assets/images/emoji/first_quarter_moon_with_face.pngbin0 -> 1068 bytes
-rw-r--r--app/assets/images/emoji/fish.pngbin0 -> 1080 bytes
-rw-r--r--app/assets/images/emoji/fish_cake.pngbin0 -> 1245 bytes
-rw-r--r--app/assets/images/emoji/fishing_pole_and_fish.pngbin0 -> 1442 bytes
-rw-r--r--app/assets/images/emoji/fist.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/fist_tone1.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/fist_tone2.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/fist_tone3.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/fist_tone4.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/fist_tone5.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/five.pngbin0 -> 577 bytes
-rw-r--r--app/assets/images/emoji/flag_ac.pngbin0 -> 1934 bytes
-rw-r--r--app/assets/images/emoji/flag_ad.pngbin0 -> 1285 bytes
-rw-r--r--app/assets/images/emoji/flag_ae.pngbin0 -> 544 bytes
-rw-r--r--app/assets/images/emoji/flag_af.pngbin0 -> 942 bytes
-rw-r--r--app/assets/images/emoji/flag_ag.pngbin0 -> 913 bytes
-rw-r--r--app/assets/images/emoji/flag_ai.pngbin0 -> 1056 bytes
-rw-r--r--app/assets/images/emoji/flag_al.pngbin0 -> 905 bytes
-rw-r--r--app/assets/images/emoji/flag_am.pngbin0 -> 514 bytes
-rw-r--r--app/assets/images/emoji/flag_ao.pngbin0 -> 997 bytes
-rw-r--r--app/assets/images/emoji/flag_aq.pngbin0 -> 657 bytes
-rw-r--r--app/assets/images/emoji/flag_ar.pngbin0 -> 975 bytes
-rw-r--r--app/assets/images/emoji/flag_as.pngbin0 -> 1489 bytes
-rw-r--r--app/assets/images/emoji/flag_at.pngbin0 -> 430 bytes
-rw-r--r--app/assets/images/emoji/flag_au.pngbin0 -> 962 bytes
-rw-r--r--app/assets/images/emoji/flag_aw.pngbin0 -> 709 bytes
-rw-r--r--app/assets/images/emoji/flag_ax.pngbin0 -> 496 bytes
-rw-r--r--app/assets/images/emoji/flag_az.pngbin0 -> 709 bytes
-rw-r--r--app/assets/images/emoji/flag_ba.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/flag_bb.pngbin0 -> 789 bytes
-rw-r--r--app/assets/images/emoji/flag_bd.pngbin0 -> 490 bytes
-rw-r--r--app/assets/images/emoji/flag_be.pngbin0 -> 444 bytes
-rw-r--r--app/assets/images/emoji/flag_bf.pngbin0 -> 717 bytes
-rw-r--r--app/assets/images/emoji/flag_bg.pngbin0 -> 513 bytes
-rw-r--r--app/assets/images/emoji/flag_bh.pngbin0 -> 593 bytes
-rw-r--r--app/assets/images/emoji/flag_bi.pngbin0 -> 795 bytes
-rw-r--r--app/assets/images/emoji/flag_bj.pngbin0 -> 554 bytes
-rw-r--r--app/assets/images/emoji/flag_bl.pngbin0 -> 1691 bytes
-rw-r--r--app/assets/images/emoji/flag_black.pngbin0 -> 702 bytes
-rw-r--r--app/assets/images/emoji/flag_bm.pngbin0 -> 1374 bytes
-rw-r--r--app/assets/images/emoji/flag_bn.pngbin0 -> 1355 bytes
-rw-r--r--app/assets/images/emoji/flag_bo.pngbin0 -> 1132 bytes
-rw-r--r--app/assets/images/emoji/flag_bq.pngbin0 -> 1144 bytes
-rw-r--r--app/assets/images/emoji/flag_br.pngbin0 -> 819 bytes
-rw-r--r--app/assets/images/emoji/flag_bs.pngbin0 -> 448 bytes
-rw-r--r--app/assets/images/emoji/flag_bt.pngbin0 -> 1213 bytes
-rw-r--r--app/assets/images/emoji/flag_bv.pngbin0 -> 495 bytes
-rw-r--r--app/assets/images/emoji/flag_bw.pngbin0 -> 391 bytes
-rw-r--r--app/assets/images/emoji/flag_by.pngbin0 -> 1120 bytes
-rw-r--r--app/assets/images/emoji/flag_bz.pngbin0 -> 1595 bytes
-rw-r--r--app/assets/images/emoji/flag_ca.pngbin0 -> 755 bytes
-rw-r--r--app/assets/images/emoji/flag_cc.pngbin0 -> 851 bytes
-rw-r--r--app/assets/images/emoji/flag_cd.pngbin0 -> 707 bytes
-rw-r--r--app/assets/images/emoji/flag_cf.pngbin0 -> 673 bytes
-rw-r--r--app/assets/images/emoji/flag_cg.pngbin0 -> 586 bytes
-rw-r--r--app/assets/images/emoji/flag_ch.pngbin0 -> 390 bytes
-rw-r--r--app/assets/images/emoji/flag_ci.pngbin0 -> 440 bytes
-rw-r--r--app/assets/images/emoji/flag_ck.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/flag_cl.pngbin0 -> 748 bytes
-rw-r--r--app/assets/images/emoji/flag_cm.pngbin0 -> 627 bytes
-rw-r--r--app/assets/images/emoji/flag_cn.pngbin0 -> 676 bytes
-rw-r--r--app/assets/images/emoji/flag_co.pngbin0 -> 524 bytes
-rw-r--r--app/assets/images/emoji/flag_cp.pngbin0 -> 443 bytes
-rw-r--r--app/assets/images/emoji/flag_cr.pngbin0 -> 419 bytes
-rw-r--r--app/assets/images/emoji/flag_cu.pngbin0 -> 586 bytes
-rw-r--r--app/assets/images/emoji/flag_cv.pngbin0 -> 642 bytes
-rw-r--r--app/assets/images/emoji/flag_cw.pngbin0 -> 665 bytes
-rw-r--r--app/assets/images/emoji/flag_cx.pngbin0 -> 1142 bytes
-rw-r--r--app/assets/images/emoji/flag_cy.pngbin0 -> 830 bytes
-rw-r--r--app/assets/images/emoji/flag_cz.pngbin0 -> 600 bytes
-rw-r--r--app/assets/images/emoji/flag_de.pngbin0 -> 502 bytes
-rw-r--r--app/assets/images/emoji/flag_dg.pngbin0 -> 1911 bytes
-rw-r--r--app/assets/images/emoji/flag_dj.pngbin0 -> 753 bytes
-rw-r--r--app/assets/images/emoji/flag_dk.pngbin0 -> 450 bytes
-rw-r--r--app/assets/images/emoji/flag_dm.pngbin0 -> 1075 bytes
-rw-r--r--app/assets/images/emoji/flag_do.pngbin0 -> 1135 bytes
-rw-r--r--app/assets/images/emoji/flag_dz.pngbin0 -> 734 bytes
-rw-r--r--app/assets/images/emoji/flag_ea.pngbin0 -> 1337 bytes
-rw-r--r--app/assets/images/emoji/flag_ec.pngbin0 -> 1431 bytes
-rw-r--r--app/assets/images/emoji/flag_ee.pngbin0 -> 512 bytes
-rw-r--r--app/assets/images/emoji/flag_eg.pngbin0 -> 818 bytes
-rw-r--r--app/assets/images/emoji/flag_eh.pngbin0 -> 742 bytes
-rw-r--r--app/assets/images/emoji/flag_er.pngbin0 -> 1218 bytes
-rw-r--r--app/assets/images/emoji/flag_es.pngbin0 -> 1337 bytes
-rw-r--r--app/assets/images/emoji/flag_et.pngbin0 -> 947 bytes
-rw-r--r--app/assets/images/emoji/flag_eu.pngbin0 -> 760 bytes
-rw-r--r--app/assets/images/emoji/flag_fi.pngbin0 -> 487 bytes
-rw-r--r--app/assets/images/emoji/flag_fj.pngbin0 -> 1381 bytes
-rw-r--r--app/assets/images/emoji/flag_fk.pngbin0 -> 1558 bytes
-rw-r--r--app/assets/images/emoji/flag_fm.pngbin0 -> 554 bytes
-rw-r--r--app/assets/images/emoji/flag_fo.pngbin0 -> 495 bytes
-rw-r--r--app/assets/images/emoji/flag_fr.pngbin0 -> 443 bytes
-rw-r--r--app/assets/images/emoji/flag_ga.pngbin0 -> 512 bytes
-rw-r--r--app/assets/images/emoji/flag_gb.pngbin0 -> 919 bytes
-rw-r--r--app/assets/images/emoji/flag_gd.pngbin0 -> 1017 bytes
-rw-r--r--app/assets/images/emoji/flag_ge.pngbin0 -> 583 bytes
-rw-r--r--app/assets/images/emoji/flag_gf.pngbin0 -> 865 bytes
-rw-r--r--app/assets/images/emoji/flag_gg.pngbin0 -> 521 bytes
-rw-r--r--app/assets/images/emoji/flag_gh.pngbin0 -> 723 bytes
-rw-r--r--app/assets/images/emoji/flag_gi.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/flag_gl.pngbin0 -> 700 bytes
-rw-r--r--app/assets/images/emoji/flag_gm.pngbin0 -> 501 bytes
-rw-r--r--app/assets/images/emoji/flag_gn.pngbin0 -> 434 bytes
-rw-r--r--app/assets/images/emoji/flag_gp.pngbin0 -> 1587 bytes
-rw-r--r--app/assets/images/emoji/flag_gq.pngbin0 -> 1132 bytes
-rw-r--r--app/assets/images/emoji/flag_gr.pngbin0 -> 549 bytes
-rw-r--r--app/assets/images/emoji/flag_gs.pngbin0 -> 2115 bytes
-rw-r--r--app/assets/images/emoji/flag_gt.pngbin0 -> 1087 bytes
-rw-r--r--app/assets/images/emoji/flag_gu.pngbin0 -> 1045 bytes
-rw-r--r--app/assets/images/emoji/flag_gw.pngbin0 -> 705 bytes
-rw-r--r--app/assets/images/emoji/flag_gy.pngbin0 -> 690 bytes
-rw-r--r--app/assets/images/emoji/flag_hk.pngbin0 -> 759 bytes
-rw-r--r--app/assets/images/emoji/flag_hm.pngbin0 -> 1036 bytes
-rw-r--r--app/assets/images/emoji/flag_hn.pngbin0 -> 513 bytes
-rw-r--r--app/assets/images/emoji/flag_hr.pngbin0 -> 1411 bytes
-rw-r--r--app/assets/images/emoji/flag_ht.pngbin0 -> 1205 bytes
-rw-r--r--app/assets/images/emoji/flag_hu.pngbin0 -> 513 bytes
-rw-r--r--app/assets/images/emoji/flag_ic.pngbin0 -> 1330 bytes
-rw-r--r--app/assets/images/emoji/flag_id.pngbin0 -> 498 bytes
-rw-r--r--app/assets/images/emoji/flag_ie.pngbin0 -> 478 bytes
-rw-r--r--app/assets/images/emoji/flag_il.pngbin0 -> 658 bytes
-rw-r--r--app/assets/images/emoji/flag_im.pngbin0 -> 976 bytes
-rw-r--r--app/assets/images/emoji/flag_in.pngbin0 -> 773 bytes
-rw-r--r--app/assets/images/emoji/flag_io.pngbin0 -> 1911 bytes
-rw-r--r--app/assets/images/emoji/flag_iq.pngbin0 -> 811 bytes
-rw-r--r--app/assets/images/emoji/flag_ir.pngbin0 -> 1036 bytes
-rw-r--r--app/assets/images/emoji/flag_is.pngbin0 -> 491 bytes
-rw-r--r--app/assets/images/emoji/flag_it.pngbin0 -> 472 bytes
-rw-r--r--app/assets/images/emoji/flag_je.pngbin0 -> 956 bytes
-rw-r--r--app/assets/images/emoji/flag_jm.pngbin0 -> 837 bytes
-rw-r--r--app/assets/images/emoji/flag_jo.pngbin0 -> 740 bytes
-rw-r--r--app/assets/images/emoji/flag_jp.pngbin0 -> 455 bytes
-rw-r--r--app/assets/images/emoji/flag_ke.pngbin0 -> 1160 bytes
-rw-r--r--app/assets/images/emoji/flag_kg.pngbin0 -> 1080 bytes
-rw-r--r--app/assets/images/emoji/flag_kh.pngbin0 -> 872 bytes
-rw-r--r--app/assets/images/emoji/flag_ki.pngbin0 -> 1369 bytes
-rw-r--r--app/assets/images/emoji/flag_km.pngbin0 -> 783 bytes
-rw-r--r--app/assets/images/emoji/flag_kn.pngbin0 -> 1316 bytes
-rw-r--r--app/assets/images/emoji/flag_kp.pngbin0 -> 696 bytes
-rw-r--r--app/assets/images/emoji/flag_kr.pngbin0 -> 967 bytes
-rw-r--r--app/assets/images/emoji/flag_kw.pngbin0 -> 560 bytes
-rw-r--r--app/assets/images/emoji/flag_ky.pngbin0 -> 1671 bytes
-rw-r--r--app/assets/images/emoji/flag_kz.pngbin0 -> 1136 bytes
-rw-r--r--app/assets/images/emoji/flag_la.pngbin0 -> 479 bytes
-rw-r--r--app/assets/images/emoji/flag_lb.pngbin0 -> 740 bytes
-rw-r--r--app/assets/images/emoji/flag_lc.pngbin0 -> 561 bytes
-rw-r--r--app/assets/images/emoji/flag_li.pngbin0 -> 946 bytes
-rw-r--r--app/assets/images/emoji/flag_lk.pngbin0 -> 974 bytes
-rw-r--r--app/assets/images/emoji/flag_lr.pngbin0 -> 772 bytes
-rw-r--r--app/assets/images/emoji/flag_ls.pngbin0 -> 775 bytes
-rw-r--r--app/assets/images/emoji/flag_lt.pngbin0 -> 510 bytes
-rw-r--r--app/assets/images/emoji/flag_lu.pngbin0 -> 512 bytes
-rw-r--r--app/assets/images/emoji/flag_lv.pngbin0 -> 388 bytes
-rw-r--r--app/assets/images/emoji/flag_ly.pngbin0 -> 685 bytes
-rw-r--r--app/assets/images/emoji/flag_ma.pngbin0 -> 626 bytes
-rw-r--r--app/assets/images/emoji/flag_mc.pngbin0 -> 528 bytes
-rw-r--r--app/assets/images/emoji/flag_md.pngbin0 -> 1170 bytes
-rw-r--r--app/assets/images/emoji/flag_me.pngbin0 -> 1074 bytes
-rw-r--r--app/assets/images/emoji/flag_mf.pngbin0 -> 443 bytes
-rw-r--r--app/assets/images/emoji/flag_mg.pngbin0 -> 556 bytes
-rw-r--r--app/assets/images/emoji/flag_mh.pngbin0 -> 1138 bytes
-rw-r--r--app/assets/images/emoji/flag_mk.pngbin0 -> 1023 bytes
-rw-r--r--app/assets/images/emoji/flag_ml.pngbin0 -> 440 bytes
-rw-r--r--app/assets/images/emoji/flag_mm.pngbin0 -> 937 bytes
-rw-r--r--app/assets/images/emoji/flag_mn.pngbin0 -> 698 bytes
-rw-r--r--app/assets/images/emoji/flag_mo.pngbin0 -> 792 bytes
-rw-r--r--app/assets/images/emoji/flag_mp.pngbin0 -> 1797 bytes
-rw-r--r--app/assets/images/emoji/flag_mq.pngbin0 -> 780 bytes
-rw-r--r--app/assets/images/emoji/flag_mr.pngbin0 -> 657 bytes
-rw-r--r--app/assets/images/emoji/flag_ms.pngbin0 -> 1477 bytes
-rw-r--r--app/assets/images/emoji/flag_mt.pngbin0 -> 799 bytes
-rw-r--r--app/assets/images/emoji/flag_mu.pngbin0 -> 544 bytes
-rw-r--r--app/assets/images/emoji/flag_mv.pngbin0 -> 598 bytes
-rw-r--r--app/assets/images/emoji/flag_mw.pngbin0 -> 825 bytes
-rw-r--r--app/assets/images/emoji/flag_mx.pngbin0 -> 951 bytes
-rw-r--r--app/assets/images/emoji/flag_my.pngbin0 -> 775 bytes
-rw-r--r--app/assets/images/emoji/flag_mz.pngbin0 -> 1159 bytes
-rw-r--r--app/assets/images/emoji/flag_na.pngbin0 -> 1249 bytes
-rw-r--r--app/assets/images/emoji/flag_nc.pngbin0 -> 1148 bytes
-rw-r--r--app/assets/images/emoji/flag_ne.pngbin0 -> 593 bytes
-rw-r--r--app/assets/images/emoji/flag_nf.pngbin0 -> 877 bytes
-rw-r--r--app/assets/images/emoji/flag_ng.pngbin0 -> 438 bytes
-rw-r--r--app/assets/images/emoji/flag_ni.pngbin0 -> 823 bytes
-rw-r--r--app/assets/images/emoji/flag_nl.pngbin0 -> 499 bytes
-rw-r--r--app/assets/images/emoji/flag_no.pngbin0 -> 484 bytes
-rw-r--r--app/assets/images/emoji/flag_np.pngbin0 -> 802 bytes
-rw-r--r--app/assets/images/emoji/flag_nr.pngbin0 -> 529 bytes
-rw-r--r--app/assets/images/emoji/flag_nu.pngbin0 -> 1128 bytes
-rw-r--r--app/assets/images/emoji/flag_nz.pngbin0 -> 1099 bytes
-rw-r--r--app/assets/images/emoji/flag_om.pngbin0 -> 754 bytes
-rw-r--r--app/assets/images/emoji/flag_pa.pngbin0 -> 830 bytes
-rw-r--r--app/assets/images/emoji/flag_pe.pngbin0 -> 439 bytes
-rw-r--r--app/assets/images/emoji/flag_pf.pngbin0 -> 1091 bytes
-rw-r--r--app/assets/images/emoji/flag_pg.pngbin0 -> 1076 bytes
-rw-r--r--app/assets/images/emoji/flag_ph.pngbin0 -> 867 bytes
-rw-r--r--app/assets/images/emoji/flag_pk.pngbin0 -> 753 bytes
-rw-r--r--app/assets/images/emoji/flag_pl.pngbin0 -> 522 bytes
-rw-r--r--app/assets/images/emoji/flag_pm.pngbin0 -> 2314 bytes
-rw-r--r--app/assets/images/emoji/flag_pn.pngbin0 -> 1895 bytes
-rw-r--r--app/assets/images/emoji/flag_pr.pngbin0 -> 605 bytes
-rw-r--r--app/assets/images/emoji/flag_ps.pngbin0 -> 574 bytes
-rw-r--r--app/assets/images/emoji/flag_pt.pngbin0 -> 1055 bytes
-rw-r--r--app/assets/images/emoji/flag_pw.pngbin0 -> 475 bytes
-rw-r--r--app/assets/images/emoji/flag_py.pngbin0 -> 1085 bytes
-rw-r--r--app/assets/images/emoji/flag_qa.pngbin0 -> 657 bytes
-rw-r--r--app/assets/images/emoji/flag_re.pngbin0 -> 837 bytes
-rw-r--r--app/assets/images/emoji/flag_ro.pngbin0 -> 441 bytes
-rw-r--r--app/assets/images/emoji/flag_rs.pngbin0 -> 1237 bytes
-rw-r--r--app/assets/images/emoji/flag_ru.pngbin0 -> 496 bytes
-rw-r--r--app/assets/images/emoji/flag_rw.pngbin0 -> 940 bytes
-rw-r--r--app/assets/images/emoji/flag_sa.pngbin0 -> 781 bytes
-rw-r--r--app/assets/images/emoji/flag_sb.pngbin0 -> 1102 bytes
-rw-r--r--app/assets/images/emoji/flag_sc.pngbin0 -> 1073 bytes
-rw-r--r--app/assets/images/emoji/flag_sd.pngbin0 -> 578 bytes
-rw-r--r--app/assets/images/emoji/flag_se.pngbin0 -> 455 bytes
-rw-r--r--app/assets/images/emoji/flag_sg.pngbin0 -> 730 bytes
-rw-r--r--app/assets/images/emoji/flag_sh.pngbin0 -> 1369 bytes
-rw-r--r--app/assets/images/emoji/flag_si.pngbin0 -> 1030 bytes
-rw-r--r--app/assets/images/emoji/flag_sj.pngbin0 -> 495 bytes
-rw-r--r--app/assets/images/emoji/flag_sk.pngbin0 -> 780 bytes
-rw-r--r--app/assets/images/emoji/flag_sl.pngbin0 -> 510 bytes
-rw-r--r--app/assets/images/emoji/flag_sm.pngbin0 -> 2000 bytes
-rw-r--r--app/assets/images/emoji/flag_sn.pngbin0 -> 621 bytes
-rw-r--r--app/assets/images/emoji/flag_so.pngbin0 -> 609 bytes
-rw-r--r--app/assets/images/emoji/flag_sr.pngbin0 -> 650 bytes
-rw-r--r--app/assets/images/emoji/flag_ss.pngbin0 -> 722 bytes
-rw-r--r--app/assets/images/emoji/flag_st.pngbin0 -> 562 bytes
-rw-r--r--app/assets/images/emoji/flag_sv.pngbin0 -> 1125 bytes
-rw-r--r--app/assets/images/emoji/flag_sx.pngbin0 -> 1195 bytes
-rw-r--r--app/assets/images/emoji/flag_sy.pngbin0 -> 696 bytes
-rw-r--r--app/assets/images/emoji/flag_sz.pngbin0 -> 1102 bytes
-rw-r--r--app/assets/images/emoji/flag_ta.pngbin0 -> 1907 bytes
-rw-r--r--app/assets/images/emoji/flag_tc.pngbin0 -> 1538 bytes
-rw-r--r--app/assets/images/emoji/flag_td.pngbin0 -> 443 bytes
-rw-r--r--app/assets/images/emoji/flag_tf.pngbin0 -> 857 bytes
-rw-r--r--app/assets/images/emoji/flag_tg.pngbin0 -> 790 bytes
-rw-r--r--app/assets/images/emoji/flag_th.pngbin0 -> 421 bytes
-rw-r--r--app/assets/images/emoji/flag_tj.pngbin0 -> 906 bytes
-rw-r--r--app/assets/images/emoji/flag_tk.pngbin0 -> 835 bytes
-rw-r--r--app/assets/images/emoji/flag_tl.pngbin0 -> 849 bytes
-rw-r--r--app/assets/images/emoji/flag_tm.pngbin0 -> 1178 bytes
-rw-r--r--app/assets/images/emoji/flag_tn.pngbin0 -> 625 bytes
-rw-r--r--app/assets/images/emoji/flag_to.pngbin0 -> 553 bytes
-rw-r--r--app/assets/images/emoji/flag_tr.pngbin0 -> 576 bytes
-rw-r--r--app/assets/images/emoji/flag_tt.pngbin0 -> 604 bytes
-rw-r--r--app/assets/images/emoji/flag_tv.pngbin0 -> 1120 bytes
-rw-r--r--app/assets/images/emoji/flag_tw.pngbin0 -> 761 bytes
-rw-r--r--app/assets/images/emoji/flag_tz.pngbin0 -> 1061 bytes
-rw-r--r--app/assets/images/emoji/flag_ua.pngbin0 -> 528 bytes
-rw-r--r--app/assets/images/emoji/flag_ug.pngbin0 -> 887 bytes
-rw-r--r--app/assets/images/emoji/flag_um.pngbin0 -> 776 bytes
-rw-r--r--app/assets/images/emoji/flag_us.pngbin0 -> 776 bytes
-rw-r--r--app/assets/images/emoji/flag_uy.pngbin0 -> 966 bytes
-rw-r--r--app/assets/images/emoji/flag_uz.pngbin0 -> 750 bytes
-rw-r--r--app/assets/images/emoji/flag_va.pngbin0 -> 1331 bytes
-rw-r--r--app/assets/images/emoji/flag_vc.pngbin0 -> 897 bytes
-rw-r--r--app/assets/images/emoji/flag_ve.pngbin0 -> 748 bytes
-rw-r--r--app/assets/images/emoji/flag_vg.pngbin0 -> 1789 bytes
-rw-r--r--app/assets/images/emoji/flag_vi.pngbin0 -> 1378 bytes
-rw-r--r--app/assets/images/emoji/flag_vn.pngbin0 -> 583 bytes
-rw-r--r--app/assets/images/emoji/flag_vu.pngbin0 -> 844 bytes
-rw-r--r--app/assets/images/emoji/flag_wf.pngbin0 -> 443 bytes
-rw-r--r--app/assets/images/emoji/flag_white.pngbin0 -> 699 bytes
-rw-r--r--app/assets/images/emoji/flag_ws.pngbin0 -> 634 bytes
-rw-r--r--app/assets/images/emoji/flag_xk.pngbin0 -> 722 bytes
-rw-r--r--app/assets/images/emoji/flag_ye.pngbin0 -> 507 bytes
-rw-r--r--app/assets/images/emoji/flag_yt.pngbin0 -> 1623 bytes
-rw-r--r--app/assets/images/emoji/flag_za.pngbin0 -> 676 bytes
-rw-r--r--app/assets/images/emoji/flag_zm.pngbin0 -> 881 bytes
-rw-r--r--app/assets/images/emoji/flag_zw.pngbin0 -> 993 bytes
-rw-r--r--app/assets/images/emoji/flags.pngbin0 -> 1722 bytes
-rw-r--r--app/assets/images/emoji/flashlight.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/fleur-de-lis.pngbin0 -> 632 bytes
-rw-r--r--app/assets/images/emoji/floppy_disk.pngbin0 -> 258 bytes
-rw-r--r--app/assets/images/emoji/flower_playing_cards.pngbin0 -> 449 bytes
-rw-r--r--app/assets/images/emoji/flushed.pngbin0 -> 1127 bytes
-rw-r--r--app/assets/images/emoji/fog.pngbin0 -> 713 bytes
-rw-r--r--app/assets/images/emoji/foggy.pngbin0 -> 1069 bytes
-rw-r--r--app/assets/images/emoji/football.pngbin0 -> 956 bytes
-rw-r--r--app/assets/images/emoji/footprints.pngbin0 -> 621 bytes
-rw-r--r--app/assets/images/emoji/fork_and_knife.pngbin0 -> 668 bytes
-rw-r--r--app/assets/images/emoji/fork_knife_plate.pngbin0 -> 976 bytes
-rw-r--r--app/assets/images/emoji/fountain.pngbin0 -> 1768 bytes
-rw-r--r--app/assets/images/emoji/four.pngbin0 -> 497 bytes
-rw-r--r--app/assets/images/emoji/four_leaf_clover.pngbin0 -> 1156 bytes
-rw-r--r--app/assets/images/emoji/fox.pngbin0 -> 1556 bytes
-rw-r--r--app/assets/images/emoji/frame_photo.pngbin0 -> 514 bytes
-rw-r--r--app/assets/images/emoji/free.pngbin0 -> 370 bytes
-rw-r--r--app/assets/images/emoji/french_bread.pngbin0 -> 1551 bytes
-rw-r--r--app/assets/images/emoji/fried_shrimp.pngbin0 -> 1241 bytes
-rw-r--r--app/assets/images/emoji/fries.pngbin0 -> 1873 bytes
-rw-r--r--app/assets/images/emoji/frog.pngbin0 -> 897 bytes
-rw-r--r--app/assets/images/emoji/frowning.pngbin0 -> 633 bytes
-rw-r--r--app/assets/images/emoji/frowning2.pngbin0 -> 589 bytes
-rw-r--r--app/assets/images/emoji/fuelpump.pngbin0 -> 864 bytes
-rw-r--r--app/assets/images/emoji/full_moon.pngbin0 -> 841 bytes
-rw-r--r--app/assets/images/emoji/full_moon_with_face.pngbin0 -> 1186 bytes
-rw-r--r--app/assets/images/emoji/game_die.pngbin0 -> 1136 bytes
-rw-r--r--app/assets/images/emoji/gear.pngbin0 -> 747 bytes
-rw-r--r--app/assets/images/emoji/gem.pngbin0 -> 715 bytes
-rw-r--r--app/assets/images/emoji/gemini.pngbin0 -> 547 bytes
-rw-r--r--app/assets/images/emoji/ghost.pngbin0 -> 1465 bytes
-rw-r--r--app/assets/images/emoji/gift.pngbin0 -> 1966 bytes
-rw-r--r--app/assets/images/emoji/gift_heart.pngbin0 -> 1141 bytes
-rw-r--r--app/assets/images/emoji/girl.pngbin0 -> 1261 bytes
-rw-r--r--app/assets/images/emoji/girl_tone1.pngbin0 -> 1259 bytes
-rw-r--r--app/assets/images/emoji/girl_tone2.pngbin0 -> 1255 bytes
-rw-r--r--app/assets/images/emoji/girl_tone3.pngbin0 -> 1255 bytes
-rw-r--r--app/assets/images/emoji/girl_tone4.pngbin0 -> 1241 bytes
-rw-r--r--app/assets/images/emoji/girl_tone5.pngbin0 -> 1245 bytes
-rw-r--r--app/assets/images/emoji/globe_with_meridians.pngbin0 -> 796 bytes
-rw-r--r--app/assets/images/emoji/goal.pngbin0 -> 1242 bytes
-rw-r--r--app/assets/images/emoji/goat.pngbin0 -> 981 bytes
-rw-r--r--app/assets/images/emoji/golf.pngbin0 -> 823 bytes
-rw-r--r--app/assets/images/emoji/golfer.pngbin0 -> 1189 bytes
-rw-r--r--app/assets/images/emoji/gorilla.pngbin0 -> 1090 bytes
-rw-r--r--app/assets/images/emoji/grapes.pngbin0 -> 1552 bytes
-rw-r--r--app/assets/images/emoji/green_apple.pngbin0 -> 656 bytes
-rw-r--r--app/assets/images/emoji/green_book.pngbin0 -> 1366 bytes
-rw-r--r--app/assets/images/emoji/green_heart.pngbin0 -> 435 bytes
-rw-r--r--app/assets/images/emoji/grey_exclamation.pngbin0 -> 354 bytes
-rw-r--r--app/assets/images/emoji/grey_question.pngbin0 -> 449 bytes
-rw-r--r--app/assets/images/emoji/grimacing.pngbin0 -> 694 bytes
-rw-r--r--app/assets/images/emoji/grin.pngbin0 -> 767 bytes
-rw-r--r--app/assets/images/emoji/grinning.pngbin0 -> 810 bytes
-rw-r--r--app/assets/images/emoji/guardsman.pngbin0 -> 1140 bytes
-rw-r--r--app/assets/images/emoji/guardsman_tone1.pngbin0 -> 1122 bytes
-rw-r--r--app/assets/images/emoji/guardsman_tone2.pngbin0 -> 1160 bytes
-rw-r--r--app/assets/images/emoji/guardsman_tone3.pngbin0 -> 1160 bytes
-rw-r--r--app/assets/images/emoji/guardsman_tone4.pngbin0 -> 1157 bytes
-rw-r--r--app/assets/images/emoji/guardsman_tone5.pngbin0 -> 1165 bytes
-rw-r--r--app/assets/images/emoji/guitar.pngbin0 -> 1056 bytes
-rw-r--r--app/assets/images/emoji/gun.pngbin0 -> 1859 bytes
-rw-r--r--app/assets/images/emoji/haircut.pngbin0 -> 1935 bytes
-rw-r--r--app/assets/images/emoji/haircut_tone1.pngbin0 -> 1945 bytes
-rw-r--r--app/assets/images/emoji/haircut_tone2.pngbin0 -> 1935 bytes
-rw-r--r--app/assets/images/emoji/haircut_tone3.pngbin0 -> 1923 bytes
-rw-r--r--app/assets/images/emoji/haircut_tone4.pngbin0 -> 1904 bytes
-rw-r--r--app/assets/images/emoji/haircut_tone5.pngbin0 -> 1920 bytes
-rw-r--r--app/assets/images/emoji/hamburger.pngbin0 -> 1973 bytes
-rw-r--r--app/assets/images/emoji/hammer.pngbin0 -> 834 bytes
-rw-r--r--app/assets/images/emoji/hammer_pick.pngbin0 -> 1068 bytes
-rw-r--r--app/assets/images/emoji/hamster.pngbin0 -> 1279 bytes
-rw-r--r--app/assets/images/emoji/hand_splayed.pngbin0 -> 1081 bytes
-rw-r--r--app/assets/images/emoji/hand_splayed_tone1.pngbin0 -> 1081 bytes
-rw-r--r--app/assets/images/emoji/hand_splayed_tone2.pngbin0 -> 1081 bytes
-rw-r--r--app/assets/images/emoji/hand_splayed_tone3.pngbin0 -> 1081 bytes
-rw-r--r--app/assets/images/emoji/hand_splayed_tone4.pngbin0 -> 1081 bytes
-rw-r--r--app/assets/images/emoji/hand_splayed_tone5.pngbin0 -> 1081 bytes
-rw-r--r--app/assets/images/emoji/handbag.pngbin0 -> 1285 bytes
-rw-r--r--app/assets/images/emoji/handball.pngbin0 -> 1634 bytes
-rw-r--r--app/assets/images/emoji/handball_tone1.pngbin0 -> 1645 bytes
-rw-r--r--app/assets/images/emoji/handball_tone2.pngbin0 -> 1628 bytes
-rw-r--r--app/assets/images/emoji/handball_tone3.pngbin0 -> 1639 bytes
-rw-r--r--app/assets/images/emoji/handball_tone4.pngbin0 -> 1634 bytes
-rw-r--r--app/assets/images/emoji/handball_tone5.pngbin0 -> 1606 bytes
-rw-r--r--app/assets/images/emoji/handshake.pngbin0 -> 1366 bytes
-rw-r--r--app/assets/images/emoji/handshake_tone1.pngbin0 -> 1381 bytes
-rw-r--r--app/assets/images/emoji/handshake_tone2.pngbin0 -> 1381 bytes
-rw-r--r--app/assets/images/emoji/handshake_tone3.pngbin0 -> 1381 bytes
-rw-r--r--app/assets/images/emoji/handshake_tone4.pngbin0 -> 1381 bytes
-rw-r--r--app/assets/images/emoji/handshake_tone5.pngbin0 -> 1381 bytes
-rw-r--r--app/assets/images/emoji/hash.pngbin0 -> 604 bytes
-rw-r--r--app/assets/images/emoji/hatched_chick.pngbin0 -> 1174 bytes
-rw-r--r--app/assets/images/emoji/hatching_chick.pngbin0 -> 1598 bytes
-rw-r--r--app/assets/images/emoji/head_bandage.pngbin0 -> 1199 bytes
-rw-r--r--app/assets/images/emoji/headphones.pngbin0 -> 1202 bytes
-rw-r--r--app/assets/images/emoji/hear_no_evil.pngbin0 -> 1210 bytes
-rw-r--r--app/assets/images/emoji/heart.pngbin0 -> 435 bytes
-rw-r--r--app/assets/images/emoji/heart_decoration.pngbin0 -> 557 bytes
-rw-r--r--app/assets/images/emoji/heart_exclamation.pngbin0 -> 471 bytes
-rw-r--r--app/assets/images/emoji/heart_eyes.pngbin0 -> 1069 bytes
-rw-r--r--app/assets/images/emoji/heart_eyes_cat.pngbin0 -> 1512 bytes
-rw-r--r--app/assets/images/emoji/heartbeat.pngbin0 -> 699 bytes
-rw-r--r--app/assets/images/emoji/heartpulse.pngbin0 -> 675 bytes
-rw-r--r--app/assets/images/emoji/hearts.pngbin0 -> 449 bytes
-rw-r--r--app/assets/images/emoji/heavy_check_mark.pngbin0 -> 438 bytes
-rw-r--r--app/assets/images/emoji/heavy_division_sign.pngbin0 -> 204 bytes
-rw-r--r--app/assets/images/emoji/heavy_dollar_sign.pngbin0 -> 429 bytes
-rw-r--r--app/assets/images/emoji/heavy_minus_sign.pngbin0 -> 108 bytes
-rw-r--r--app/assets/images/emoji/heavy_multiplication_x.pngbin0 -> 298 bytes
-rw-r--r--app/assets/images/emoji/heavy_plus_sign.pngbin0 -> 115 bytes
-rw-r--r--app/assets/images/emoji/helicopter.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/helmet_with_cross.pngbin0 -> 1014 bytes
-rw-r--r--app/assets/images/emoji/herb.pngbin0 -> 886 bytes
-rw-r--r--app/assets/images/emoji/hibiscus.pngbin0 -> 1815 bytes
-rw-r--r--app/assets/images/emoji/high_brightness.pngbin0 -> 474 bytes
-rw-r--r--app/assets/images/emoji/high_heel.pngbin0 -> 1008 bytes
-rw-r--r--app/assets/images/emoji/hockey.pngbin0 -> 1010 bytes
-rw-r--r--app/assets/images/emoji/hole.pngbin0 -> 1390 bytes
-rw-r--r--app/assets/images/emoji/homes.pngbin0 -> 981 bytes
-rw-r--r--app/assets/images/emoji/honey_pot.pngbin0 -> 1217 bytes
-rw-r--r--app/assets/images/emoji/horse.pngbin0 -> 1694 bytes
-rw-r--r--app/assets/images/emoji/horse_racing.pngbin0 -> 2096 bytes
-rw-r--r--app/assets/images/emoji/horse_racing_tone1.pngbin0 -> 2099 bytes
-rw-r--r--app/assets/images/emoji/horse_racing_tone2.pngbin0 -> 2103 bytes
-rw-r--r--app/assets/images/emoji/horse_racing_tone3.pngbin0 -> 2090 bytes
-rw-r--r--app/assets/images/emoji/horse_racing_tone4.pngbin0 -> 2090 bytes
-rw-r--r--app/assets/images/emoji/horse_racing_tone5.pngbin0 -> 2085 bytes
-rw-r--r--app/assets/images/emoji/hospital.pngbin0 -> 530 bytes
-rw-r--r--app/assets/images/emoji/hot_pepper.pngbin0 -> 677 bytes
-rw-r--r--app/assets/images/emoji/hotdog.pngbin0 -> 1770 bytes
-rw-r--r--app/assets/images/emoji/hotel.pngbin0 -> 1322 bytes
-rw-r--r--app/assets/images/emoji/hotsprings.pngbin0 -> 733 bytes
-rw-r--r--app/assets/images/emoji/hourglass.pngbin0 -> 800 bytes
-rw-r--r--app/assets/images/emoji/hourglass_flowing_sand.pngbin0 -> 847 bytes
-rw-r--r--app/assets/images/emoji/house.pngbin0 -> 863 bytes
-rw-r--r--app/assets/images/emoji/house_abandoned.pngbin0 -> 1606 bytes
-rw-r--r--app/assets/images/emoji/house_with_garden.pngbin0 -> 1613 bytes
-rw-r--r--app/assets/images/emoji/hugging.pngbin0 -> 1425 bytes
-rw-r--r--app/assets/images/emoji/hushed.pngbin0 -> 634 bytes
-rw-r--r--app/assets/images/emoji/ice_cream.pngbin0 -> 1779 bytes
-rw-r--r--app/assets/images/emoji/ice_skate.pngbin0 -> 1574 bytes
-rw-r--r--app/assets/images/emoji/icecream.pngbin0 -> 1496 bytes
-rw-r--r--app/assets/images/emoji/id.pngbin0 -> 348 bytes
-rw-r--r--app/assets/images/emoji/ideograph_advantage.pngbin0 -> 716 bytes
-rw-r--r--app/assets/images/emoji/imp.pngbin0 -> 1988 bytes
-rw-r--r--app/assets/images/emoji/inbox_tray.pngbin0 -> 1029 bytes
-rw-r--r--app/assets/images/emoji/incoming_envelope.pngbin0 -> 1129 bytes
-rw-r--r--app/assets/images/emoji/information_desk_person.pngbin0 -> 1580 bytes
-rw-r--r--app/assets/images/emoji/information_desk_person_tone1.pngbin0 -> 1597 bytes
-rw-r--r--app/assets/images/emoji/information_desk_person_tone2.pngbin0 -> 1590 bytes
-rw-r--r--app/assets/images/emoji/information_desk_person_tone3.pngbin0 -> 1580 bytes
-rw-r--r--app/assets/images/emoji/information_desk_person_tone4.pngbin0 -> 1572 bytes
-rw-r--r--app/assets/images/emoji/information_desk_person_tone5.pngbin0 -> 1588 bytes
-rw-r--r--app/assets/images/emoji/information_source.pngbin0 -> 506 bytes
-rw-r--r--app/assets/images/emoji/innocent.pngbin0 -> 935 bytes
-rw-r--r--app/assets/images/emoji/interrobang.pngbin0 -> 601 bytes
-rw-r--r--app/assets/images/emoji/iphone.pngbin0 -> 695 bytes
-rw-r--r--app/assets/images/emoji/island.pngbin0 -> 1273 bytes
-rw-r--r--app/assets/images/emoji/izakaya_lantern.pngbin0 -> 1227 bytes
-rw-r--r--app/assets/images/emoji/jack_o_lantern.pngbin0 -> 2289 bytes
-rw-r--r--app/assets/images/emoji/japan.pngbin0 -> 539 bytes
-rw-r--r--app/assets/images/emoji/japanese_castle.pngbin0 -> 1404 bytes
-rw-r--r--app/assets/images/emoji/japanese_goblin.pngbin0 -> 1561 bytes
-rw-r--r--app/assets/images/emoji/japanese_ogre.pngbin0 -> 1864 bytes
-rw-r--r--app/assets/images/emoji/jeans.pngbin0 -> 1158 bytes
-rw-r--r--app/assets/images/emoji/joy.pngbin0 -> 1136 bytes
-rw-r--r--app/assets/images/emoji/joy_cat.pngbin0 -> 1633 bytes
-rw-r--r--app/assets/images/emoji/joystick.pngbin0 -> 1039 bytes
-rw-r--r--app/assets/images/emoji/juggling.pngbin0 -> 1165 bytes
-rw-r--r--app/assets/images/emoji/juggling_tone1.pngbin0 -> 1171 bytes
-rw-r--r--app/assets/images/emoji/juggling_tone2.pngbin0 -> 1160 bytes
-rw-r--r--app/assets/images/emoji/juggling_tone3.pngbin0 -> 1170 bytes
-rw-r--r--app/assets/images/emoji/juggling_tone4.pngbin0 -> 1167 bytes
-rw-r--r--app/assets/images/emoji/juggling_tone5.pngbin0 -> 1161 bytes
-rw-r--r--app/assets/images/emoji/kaaba.pngbin0 -> 1251 bytes
-rw-r--r--app/assets/images/emoji/key.pngbin0 -> 770 bytes
-rw-r--r--app/assets/images/emoji/key2.pngbin0 -> 593 bytes
-rw-r--r--app/assets/images/emoji/keyboard.pngbin0 -> 429 bytes
-rw-r--r--app/assets/images/emoji/kimono.pngbin0 -> 1527 bytes
-rw-r--r--app/assets/images/emoji/kiss.pngbin0 -> 842 bytes
-rw-r--r--app/assets/images/emoji/kiss_mm.pngbin0 -> 1269 bytes
-rw-r--r--app/assets/images/emoji/kiss_ww.pngbin0 -> 1149 bytes
-rw-r--r--app/assets/images/emoji/kissing.pngbin0 -> 738 bytes
-rw-r--r--app/assets/images/emoji/kissing_cat.pngbin0 -> 1468 bytes
-rw-r--r--app/assets/images/emoji/kissing_closed_eyes.pngbin0 -> 888 bytes
-rw-r--r--app/assets/images/emoji/kissing_heart.pngbin0 -> 843 bytes
-rw-r--r--app/assets/images/emoji/kissing_smiling_eyes.pngbin0 -> 648 bytes
-rw-r--r--app/assets/images/emoji/kiwi.pngbin0 -> 1892 bytes
-rw-r--r--app/assets/images/emoji/knife.pngbin0 -> 616 bytes
-rw-r--r--app/assets/images/emoji/koala.pngbin0 -> 1428 bytes
-rw-r--r--app/assets/images/emoji/koko.pngbin0 -> 266 bytes
-rw-r--r--app/assets/images/emoji/label.pngbin0 -> 669 bytes
-rw-r--r--app/assets/images/emoji/large_blue_circle.pngbin0 -> 371 bytes
-rw-r--r--app/assets/images/emoji/large_blue_diamond.pngbin0 -> 245 bytes
-rw-r--r--app/assets/images/emoji/large_orange_diamond.pngbin0 -> 248 bytes
-rw-r--r--app/assets/images/emoji/last_quarter_moon.pngbin0 -> 1180 bytes
-rw-r--r--app/assets/images/emoji/last_quarter_moon_with_face.pngbin0 -> 1030 bytes
-rw-r--r--app/assets/images/emoji/laughing.pngbin0 -> 901 bytes
-rw-r--r--app/assets/images/emoji/leaves.pngbin0 -> 993 bytes
-rw-r--r--app/assets/images/emoji/ledger.pngbin0 -> 1528 bytes
-rw-r--r--app/assets/images/emoji/left_facing_fist.pngbin0 -> 972 bytes
-rw-r--r--app/assets/images/emoji/left_facing_fist_tone1.pngbin0 -> 960 bytes
-rw-r--r--app/assets/images/emoji/left_facing_fist_tone2.pngbin0 -> 972 bytes
-rw-r--r--app/assets/images/emoji/left_facing_fist_tone3.pngbin0 -> 960 bytes
-rw-r--r--app/assets/images/emoji/left_facing_fist_tone4.pngbin0 -> 960 bytes
-rw-r--r--app/assets/images/emoji/left_facing_fist_tone5.pngbin0 -> 976 bytes
-rw-r--r--app/assets/images/emoji/left_luggage.pngbin0 -> 576 bytes
-rw-r--r--app/assets/images/emoji/left_right_arrow.pngbin0 -> 495 bytes
-rw-r--r--app/assets/images/emoji/leftwards_arrow_with_hook.pngbin0 -> 643 bytes
-rw-r--r--app/assets/images/emoji/lemon.pngbin0 -> 1033 bytes
-rw-r--r--app/assets/images/emoji/leo.pngbin0 -> 745 bytes
-rw-r--r--app/assets/images/emoji/leopard.pngbin0 -> 2222 bytes
-rw-r--r--app/assets/images/emoji/level_slider.pngbin0 -> 454 bytes
-rw-r--r--app/assets/images/emoji/levitate.pngbin0 -> 914 bytes
-rw-r--r--app/assets/images/emoji/libra.pngbin0 -> 657 bytes
-rw-r--r--app/assets/images/emoji/lifter.pngbin0 -> 1356 bytes
-rw-r--r--app/assets/images/emoji/lifter_tone1.pngbin0 -> 1346 bytes
-rw-r--r--app/assets/images/emoji/lifter_tone2.pngbin0 -> 1347 bytes
-rw-r--r--app/assets/images/emoji/lifter_tone3.pngbin0 -> 1339 bytes
-rw-r--r--app/assets/images/emoji/lifter_tone4.pngbin0 -> 1343 bytes
-rw-r--r--app/assets/images/emoji/lifter_tone5.pngbin0 -> 1337 bytes
-rw-r--r--app/assets/images/emoji/light_rail.pngbin0 -> 902 bytes
-rw-r--r--app/assets/images/emoji/link.pngbin0 -> 477 bytes
-rw-r--r--app/assets/images/emoji/lion_face.pngbin0 -> 1728 bytes
-rw-r--r--app/assets/images/emoji/lips.pngbin0 -> 599 bytes
-rw-r--r--app/assets/images/emoji/lipstick.pngbin0 -> 549 bytes
-rw-r--r--app/assets/images/emoji/lizard.pngbin0 -> 1709 bytes
-rw-r--r--app/assets/images/emoji/lock.pngbin0 -> 986 bytes
-rw-r--r--app/assets/images/emoji/lock_with_ink_pen.pngbin0 -> 1123 bytes
-rw-r--r--app/assets/images/emoji/lollipop.pngbin0 -> 2164 bytes
-rw-r--r--app/assets/images/emoji/loop.pngbin0 -> 550 bytes
-rw-r--r--app/assets/images/emoji/loud_sound.pngbin0 -> 977 bytes
-rw-r--r--app/assets/images/emoji/loudspeaker.pngbin0 -> 1316 bytes
-rw-r--r--app/assets/images/emoji/love_hotel.pngbin0 -> 372 bytes
-rw-r--r--app/assets/images/emoji/love_letter.pngbin0 -> 923 bytes
-rw-r--r--app/assets/images/emoji/low_brightness.pngbin0 -> 431 bytes
-rw-r--r--app/assets/images/emoji/lying_face.pngbin0 -> 1103 bytes
-rw-r--r--app/assets/images/emoji/m.pngbin0 -> 500 bytes
-rw-r--r--app/assets/images/emoji/mag.pngbin0 -> 1240 bytes
-rw-r--r--app/assets/images/emoji/mag_right.pngbin0 -> 1251 bytes
-rw-r--r--app/assets/images/emoji/mahjong.pngbin0 -> 951 bytes
-rw-r--r--app/assets/images/emoji/mailbox.pngbin0 -> 1166 bytes
-rw-r--r--app/assets/images/emoji/mailbox_closed.pngbin0 -> 1192 bytes
-rw-r--r--app/assets/images/emoji/mailbox_with_mail.pngbin0 -> 1307 bytes
-rw-r--r--app/assets/images/emoji/mailbox_with_no_mail.pngbin0 -> 960 bytes
-rw-r--r--app/assets/images/emoji/man.pngbin0 -> 1092 bytes
-rw-r--r--app/assets/images/emoji/man_dancing.pngbin0 -> 1400 bytes
-rw-r--r--app/assets/images/emoji/man_dancing_tone1.pngbin0 -> 1404 bytes
-rw-r--r--app/assets/images/emoji/man_dancing_tone2.pngbin0 -> 1402 bytes
-rw-r--r--app/assets/images/emoji/man_dancing_tone3.pngbin0 -> 1409 bytes
-rw-r--r--app/assets/images/emoji/man_dancing_tone4.pngbin0 -> 1421 bytes
-rw-r--r--app/assets/images/emoji/man_dancing_tone5.pngbin0 -> 1418 bytes
-rw-r--r--app/assets/images/emoji/man_in_tuxedo.pngbin0 -> 1307 bytes
-rw-r--r--app/assets/images/emoji/man_in_tuxedo_tone1.pngbin0 -> 1307 bytes
-rw-r--r--app/assets/images/emoji/man_in_tuxedo_tone2.pngbin0 -> 1307 bytes
-rw-r--r--app/assets/images/emoji/man_in_tuxedo_tone3.pngbin0 -> 1307 bytes
-rw-r--r--app/assets/images/emoji/man_in_tuxedo_tone4.pngbin0 -> 1307 bytes
-rw-r--r--app/assets/images/emoji/man_in_tuxedo_tone5.pngbin0 -> 1302 bytes
-rw-r--r--app/assets/images/emoji/man_tone1.pngbin0 -> 1069 bytes
-rw-r--r--app/assets/images/emoji/man_tone2.pngbin0 -> 1069 bytes
-rw-r--r--app/assets/images/emoji/man_tone3.pngbin0 -> 1069 bytes
-rw-r--r--app/assets/images/emoji/man_tone4.pngbin0 -> 1069 bytes
-rw-r--r--app/assets/images/emoji/man_tone5.pngbin0 -> 1087 bytes
-rw-r--r--app/assets/images/emoji/man_with_gua_pi_mao.pngbin0 -> 1339 bytes
-rw-r--r--app/assets/images/emoji/man_with_gua_pi_mao_tone1.pngbin0 -> 1328 bytes
-rw-r--r--app/assets/images/emoji/man_with_gua_pi_mao_tone2.pngbin0 -> 1332 bytes
-rw-r--r--app/assets/images/emoji/man_with_gua_pi_mao_tone3.pngbin0 -> 1329 bytes
-rw-r--r--app/assets/images/emoji/man_with_gua_pi_mao_tone4.pngbin0 -> 1325 bytes
-rw-r--r--app/assets/images/emoji/man_with_gua_pi_mao_tone5.pngbin0 -> 1337 bytes
-rw-r--r--app/assets/images/emoji/man_with_turban.pngbin0 -> 1618 bytes
-rw-r--r--app/assets/images/emoji/man_with_turban_tone1.pngbin0 -> 1584 bytes
-rw-r--r--app/assets/images/emoji/man_with_turban_tone2.pngbin0 -> 1588 bytes
-rw-r--r--app/assets/images/emoji/man_with_turban_tone3.pngbin0 -> 1584 bytes
-rw-r--r--app/assets/images/emoji/man_with_turban_tone4.pngbin0 -> 1583 bytes
-rw-r--r--app/assets/images/emoji/man_with_turban_tone5.pngbin0 -> 1605 bytes
-rw-r--r--app/assets/images/emoji/mans_shoe.pngbin0 -> 1649 bytes
-rw-r--r--app/assets/images/emoji/map.pngbin0 -> 2352 bytes
-rw-r--r--app/assets/images/emoji/maple_leaf.pngbin0 -> 1117 bytes
-rw-r--r--app/assets/images/emoji/martial_arts_uniform.pngbin0 -> 1412 bytes
-rw-r--r--app/assets/images/emoji/mask.pngbin0 -> 1322 bytes
-rw-r--r--app/assets/images/emoji/massage.pngbin0 -> 1571 bytes
-rw-r--r--app/assets/images/emoji/massage_tone1.pngbin0 -> 1578 bytes
-rw-r--r--app/assets/images/emoji/massage_tone2.pngbin0 -> 1565 bytes
-rw-r--r--app/assets/images/emoji/massage_tone3.pngbin0 -> 1553 bytes
-rw-r--r--app/assets/images/emoji/massage_tone4.pngbin0 -> 1546 bytes
-rw-r--r--app/assets/images/emoji/massage_tone5.pngbin0 -> 1557 bytes
-rw-r--r--app/assets/images/emoji/meat_on_bone.pngbin0 -> 1465 bytes
-rw-r--r--app/assets/images/emoji/medal.pngbin0 -> 1700 bytes
-rw-r--r--app/assets/images/emoji/mega.pngbin0 -> 1751 bytes
-rw-r--r--app/assets/images/emoji/melon.pngbin0 -> 2005 bytes
-rw-r--r--app/assets/images/emoji/menorah.pngbin0 -> 1279 bytes
-rw-r--r--app/assets/images/emoji/mens.pngbin0 -> 561 bytes
-rw-r--r--app/assets/images/emoji/metal.pngbin0 -> 894 bytes
-rw-r--r--app/assets/images/emoji/metal_tone1.pngbin0 -> 894 bytes
-rw-r--r--app/assets/images/emoji/metal_tone2.pngbin0 -> 888 bytes
-rw-r--r--app/assets/images/emoji/metal_tone3.pngbin0 -> 894 bytes
-rw-r--r--app/assets/images/emoji/metal_tone4.pngbin0 -> 888 bytes
-rw-r--r--app/assets/images/emoji/metal_tone5.pngbin0 -> 894 bytes
-rw-r--r--app/assets/images/emoji/metro.pngbin0 -> 1020 bytes
-rw-r--r--app/assets/images/emoji/microphone.pngbin0 -> 1165 bytes
-rw-r--r--app/assets/images/emoji/microphone2.pngbin0 -> 839 bytes
-rw-r--r--app/assets/images/emoji/microscope.pngbin0 -> 1113 bytes
-rw-r--r--app/assets/images/emoji/middle_finger.pngbin0 -> 893 bytes
-rw-r--r--app/assets/images/emoji/middle_finger_tone1.pngbin0 -> 892 bytes
-rw-r--r--app/assets/images/emoji/middle_finger_tone2.pngbin0 -> 892 bytes
-rw-r--r--app/assets/images/emoji/middle_finger_tone3.pngbin0 -> 892 bytes
-rw-r--r--app/assets/images/emoji/middle_finger_tone4.pngbin0 -> 892 bytes
-rw-r--r--app/assets/images/emoji/middle_finger_tone5.pngbin0 -> 892 bytes
-rw-r--r--app/assets/images/emoji/military_medal.pngbin0 -> 949 bytes
-rw-r--r--app/assets/images/emoji/milk.pngbin0 -> 1224 bytes
-rw-r--r--app/assets/images/emoji/milky_way.pngbin0 -> 622 bytes
-rw-r--r--app/assets/images/emoji/minibus.pngbin0 -> 1256 bytes
-rw-r--r--app/assets/images/emoji/minidisc.pngbin0 -> 522 bytes
-rw-r--r--app/assets/images/emoji/mobile_phone_off.pngbin0 -> 621 bytes
-rw-r--r--app/assets/images/emoji/money_mouth.pngbin0 -> 967 bytes
-rw-r--r--app/assets/images/emoji/money_with_wings.pngbin0 -> 2327 bytes
-rw-r--r--app/assets/images/emoji/moneybag.pngbin0 -> 2310 bytes
-rw-r--r--app/assets/images/emoji/monkey.pngbin0 -> 1348 bytes
-rw-r--r--app/assets/images/emoji/monkey_face.pngbin0 -> 1022 bytes
-rw-r--r--app/assets/images/emoji/monorail.pngbin0 -> 1068 bytes
-rw-r--r--app/assets/images/emoji/mortar_board.pngbin0 -> 710 bytes
-rw-r--r--app/assets/images/emoji/mosque.pngbin0 -> 984 bytes
-rw-r--r--app/assets/images/emoji/motor_scooter.pngbin0 -> 1207 bytes
-rw-r--r--app/assets/images/emoji/motorboat.pngbin0 -> 990 bytes
-rw-r--r--app/assets/images/emoji/motorcycle.pngbin0 -> 2081 bytes
-rw-r--r--app/assets/images/emoji/motorway.pngbin0 -> 1102 bytes
-rw-r--r--app/assets/images/emoji/mount_fuji.pngbin0 -> 881 bytes
-rw-r--r--app/assets/images/emoji/mountain.pngbin0 -> 1409 bytes
-rw-r--r--app/assets/images/emoji/mountain_bicyclist.pngbin0 -> 2288 bytes
-rw-r--r--app/assets/images/emoji/mountain_bicyclist_tone1.pngbin0 -> 2294 bytes
-rw-r--r--app/assets/images/emoji/mountain_bicyclist_tone2.pngbin0 -> 2298 bytes
-rw-r--r--app/assets/images/emoji/mountain_bicyclist_tone3.pngbin0 -> 2284 bytes
-rw-r--r--app/assets/images/emoji/mountain_bicyclist_tone4.pngbin0 -> 2288 bytes
-rw-r--r--app/assets/images/emoji/mountain_bicyclist_tone5.pngbin0 -> 2281 bytes
-rw-r--r--app/assets/images/emoji/mountain_cableway.pngbin0 -> 811 bytes
-rw-r--r--app/assets/images/emoji/mountain_railway.pngbin0 -> 1317 bytes
-rw-r--r--app/assets/images/emoji/mountain_snow.pngbin0 -> 1193 bytes
-rw-r--r--app/assets/images/emoji/mouse.pngbin0 -> 1245 bytes
-rw-r--r--app/assets/images/emoji/mouse2.pngbin0 -> 1324 bytes
-rw-r--r--app/assets/images/emoji/mouse_three_button.pngbin0 -> 934 bytes
-rw-r--r--app/assets/images/emoji/movie_camera.pngbin0 -> 576 bytes
-rw-r--r--app/assets/images/emoji/moyai.pngbin0 -> 1593 bytes
-rw-r--r--app/assets/images/emoji/mrs_claus.pngbin0 -> 2206 bytes
-rw-r--r--app/assets/images/emoji/mrs_claus_tone1.pngbin0 -> 1999 bytes
-rw-r--r--app/assets/images/emoji/mrs_claus_tone2.pngbin0 -> 2006 bytes
-rw-r--r--app/assets/images/emoji/mrs_claus_tone3.pngbin0 -> 2017 bytes
-rw-r--r--app/assets/images/emoji/mrs_claus_tone4.pngbin0 -> 2016 bytes
-rw-r--r--app/assets/images/emoji/mrs_claus_tone5.pngbin0 -> 2016 bytes
-rw-r--r--app/assets/images/emoji/muscle.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/muscle_tone1.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/muscle_tone2.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/muscle_tone3.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/muscle_tone4.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/muscle_tone5.pngbin0 -> 1012 bytes
-rw-r--r--app/assets/images/emoji/mushroom.pngbin0 -> 1024 bytes
-rw-r--r--app/assets/images/emoji/musical_keyboard.pngbin0 -> 1695 bytes
-rw-r--r--app/assets/images/emoji/musical_note.pngbin0 -> 419 bytes
-rw-r--r--app/assets/images/emoji/musical_score.pngbin0 -> 1289 bytes
-rw-r--r--app/assets/images/emoji/mute.pngbin0 -> 823 bytes
-rw-r--r--app/assets/images/emoji/nail_care.pngbin0 -> 1639 bytes
-rw-r--r--app/assets/images/emoji/nail_care_tone1.pngbin0 -> 1712 bytes
-rw-r--r--app/assets/images/emoji/nail_care_tone2.pngbin0 -> 1711 bytes
-rw-r--r--app/assets/images/emoji/nail_care_tone3.pngbin0 -> 1727 bytes
-rw-r--r--app/assets/images/emoji/nail_care_tone4.pngbin0 -> 1728 bytes
-rw-r--r--app/assets/images/emoji/nail_care_tone5.pngbin0 -> 1716 bytes
-rw-r--r--app/assets/images/emoji/name_badge.pngbin0 -> 632 bytes
-rw-r--r--app/assets/images/emoji/nauseated_face.pngbin0 -> 965 bytes
-rw-r--r--app/assets/images/emoji/necktie.pngbin0 -> 995 bytes
-rw-r--r--app/assets/images/emoji/negative_squared_cross_mark.pngbin0 -> 370 bytes
-rw-r--r--app/assets/images/emoji/nerd.pngbin0 -> 975 bytes
-rw-r--r--app/assets/images/emoji/neutral_face.pngbin0 -> 517 bytes
-rw-r--r--app/assets/images/emoji/new.pngbin0 -> 486 bytes
-rw-r--r--app/assets/images/emoji/new_moon.pngbin0 -> 829 bytes
-rw-r--r--app/assets/images/emoji/new_moon_with_face.pngbin0 -> 975 bytes
-rw-r--r--app/assets/images/emoji/newspaper.pngbin0 -> 1178 bytes
-rw-r--r--app/assets/images/emoji/newspaper2.pngbin0 -> 1046 bytes
-rw-r--r--app/assets/images/emoji/ng.pngbin0 -> 445 bytes
-rw-r--r--app/assets/images/emoji/night_with_stars.pngbin0 -> 835 bytes
-rw-r--r--app/assets/images/emoji/nine.pngbin0 -> 607 bytes
-rw-r--r--app/assets/images/emoji/no_bell.pngbin0 -> 823 bytes
-rw-r--r--app/assets/images/emoji/no_bicycles.pngbin0 -> 998 bytes
-rw-r--r--app/assets/images/emoji/no_entry.pngbin0 -> 377 bytes
-rw-r--r--app/assets/images/emoji/no_entry_sign.pngbin0 -> 555 bytes
-rw-r--r--app/assets/images/emoji/no_good.pngbin0 -> 1750 bytes
-rw-r--r--app/assets/images/emoji/no_good_tone1.pngbin0 -> 1767 bytes
-rw-r--r--app/assets/images/emoji/no_good_tone2.pngbin0 -> 1756 bytes
-rw-r--r--app/assets/images/emoji/no_good_tone3.pngbin0 -> 1766 bytes
-rw-r--r--app/assets/images/emoji/no_good_tone4.pngbin0 -> 1782 bytes
-rw-r--r--app/assets/images/emoji/no_good_tone5.pngbin0 -> 1784 bytes
-rw-r--r--app/assets/images/emoji/no_mobile_phones.pngbin0 -> 790 bytes
-rw-r--r--app/assets/images/emoji/no_mouth.pngbin0 -> 465 bytes
-rw-r--r--app/assets/images/emoji/no_pedestrians.pngbin0 -> 875 bytes
-rw-r--r--app/assets/images/emoji/no_smoking.pngbin0 -> 1136 bytes
-rw-r--r--app/assets/images/emoji/non-potable_water.pngbin0 -> 827 bytes
-rw-r--r--app/assets/images/emoji/nose.pngbin0 -> 703 bytes
-rw-r--r--app/assets/images/emoji/nose_tone1.pngbin0 -> 703 bytes
-rw-r--r--app/assets/images/emoji/nose_tone2.pngbin0 -> 703 bytes
-rw-r--r--app/assets/images/emoji/nose_tone3.pngbin0 -> 703 bytes
-rw-r--r--app/assets/images/emoji/nose_tone4.pngbin0 -> 703 bytes
-rw-r--r--app/assets/images/emoji/nose_tone5.pngbin0 -> 703 bytes
-rw-r--r--app/assets/images/emoji/notebook.pngbin0 -> 1215 bytes
-rw-r--r--app/assets/images/emoji/notebook_with_decorative_cover.pngbin0 -> 1782 bytes
-rw-r--r--app/assets/images/emoji/notepad_spiral.pngbin0 -> 1377 bytes
-rw-r--r--app/assets/images/emoji/notes.pngbin0 -> 501 bytes
-rw-r--r--app/assets/images/emoji/nut_and_bolt.pngbin0 -> 899 bytes
-rw-r--r--app/assets/images/emoji/o.pngbin0 -> 475 bytes
-rw-r--r--app/assets/images/emoji/o2.pngbin0 -> 425 bytes
-rw-r--r--app/assets/images/emoji/ocean.pngbin0 -> 1018 bytes
-rw-r--r--app/assets/images/emoji/octagonal_sign.pngbin0 -> 260 bytes
-rw-r--r--app/assets/images/emoji/octopus.pngbin0 -> 1188 bytes
-rw-r--r--app/assets/images/emoji/oden.pngbin0 -> 794 bytes
-rw-r--r--app/assets/images/emoji/office.pngbin0 -> 524 bytes
-rw-r--r--app/assets/images/emoji/oil.pngbin0 -> 674 bytes
-rw-r--r--app/assets/images/emoji/ok.pngbin0 -> 511 bytes
-rw-r--r--app/assets/images/emoji/ok_hand.pngbin0 -> 979 bytes
-rw-r--r--app/assets/images/emoji/ok_hand_tone1.pngbin0 -> 979 bytes
-rw-r--r--app/assets/images/emoji/ok_hand_tone2.pngbin0 -> 979 bytes
-rw-r--r--app/assets/images/emoji/ok_hand_tone3.pngbin0 -> 979 bytes
-rw-r--r--app/assets/images/emoji/ok_hand_tone4.pngbin0 -> 979 bytes
-rw-r--r--app/assets/images/emoji/ok_hand_tone5.pngbin0 -> 979 bytes
-rw-r--r--app/assets/images/emoji/ok_woman.pngbin0 -> 1696 bytes
-rw-r--r--app/assets/images/emoji/ok_woman_tone1.pngbin0 -> 1696 bytes
-rw-r--r--app/assets/images/emoji/ok_woman_tone2.pngbin0 -> 1694 bytes
-rw-r--r--app/assets/images/emoji/ok_woman_tone3.pngbin0 -> 1675 bytes
-rw-r--r--app/assets/images/emoji/ok_woman_tone4.pngbin0 -> 1684 bytes
-rw-r--r--app/assets/images/emoji/ok_woman_tone5.pngbin0 -> 1696 bytes
-rw-r--r--app/assets/images/emoji/older_man.pngbin0 -> 1253 bytes
-rw-r--r--app/assets/images/emoji/older_man_tone1.pngbin0 -> 1253 bytes
-rw-r--r--app/assets/images/emoji/older_man_tone2.pngbin0 -> 1253 bytes
-rw-r--r--app/assets/images/emoji/older_man_tone3.pngbin0 -> 1253 bytes
-rw-r--r--app/assets/images/emoji/older_man_tone4.pngbin0 -> 1254 bytes
-rw-r--r--app/assets/images/emoji/older_man_tone5.pngbin0 -> 1254 bytes
-rw-r--r--app/assets/images/emoji/older_woman.pngbin0 -> 1472 bytes
-rw-r--r--app/assets/images/emoji/older_woman_tone1.pngbin0 -> 1562 bytes
-rw-r--r--app/assets/images/emoji/older_woman_tone2.pngbin0 -> 1564 bytes
-rw-r--r--app/assets/images/emoji/older_woman_tone3.pngbin0 -> 1555 bytes
-rw-r--r--app/assets/images/emoji/older_woman_tone4.pngbin0 -> 1562 bytes
-rw-r--r--app/assets/images/emoji/older_woman_tone5.pngbin0 -> 1544 bytes
-rw-r--r--app/assets/images/emoji/om_symbol.pngbin0 -> 773 bytes
-rw-r--r--app/assets/images/emoji/on.pngbin0 -> 459 bytes
-rw-r--r--app/assets/images/emoji/oncoming_automobile.pngbin0 -> 1238 bytes
-rw-r--r--app/assets/images/emoji/oncoming_bus.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/oncoming_police_car.pngbin0 -> 1547 bytes
-rw-r--r--app/assets/images/emoji/oncoming_taxi.pngbin0 -> 1405 bytes
-rw-r--r--app/assets/images/emoji/one.pngbin0 -> 442 bytes
-rw-r--r--app/assets/images/emoji/open_file_folder.pngbin0 -> 755 bytes
-rw-r--r--app/assets/images/emoji/open_hands.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/open_hands_tone1.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/open_hands_tone2.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/open_hands_tone3.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/open_hands_tone4.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/open_hands_tone5.pngbin0 -> 1053 bytes
-rw-r--r--app/assets/images/emoji/open_mouth.pngbin0 -> 575 bytes
-rw-r--r--app/assets/images/emoji/ophiuchus.pngbin0 -> 723 bytes
-rw-r--r--app/assets/images/emoji/orange_book.pngbin0 -> 1329 bytes
-rw-r--r--app/assets/images/emoji/orthodox_cross.pngbin0 -> 239 bytes
-rw-r--r--app/assets/images/emoji/outbox_tray.pngbin0 -> 1002 bytes
-rw-r--r--app/assets/images/emoji/owl.pngbin0 -> 2045 bytes
-rw-r--r--app/assets/images/emoji/ox.pngbin0 -> 1436 bytes
-rw-r--r--app/assets/images/emoji/package.pngbin0 -> 950 bytes
-rw-r--r--app/assets/images/emoji/page_facing_up.pngbin0 -> 1110 bytes
-rw-r--r--app/assets/images/emoji/page_with_curl.pngbin0 -> 1157 bytes
-rw-r--r--app/assets/images/emoji/pager.pngbin0 -> 553 bytes
-rw-r--r--app/assets/images/emoji/paintbrush.pngbin0 -> 950 bytes
-rw-r--r--app/assets/images/emoji/palm_tree.pngbin0 -> 1450 bytes
-rw-r--r--app/assets/images/emoji/pancakes.pngbin0 -> 3661 bytes
-rw-r--r--app/assets/images/emoji/panda_face.pngbin0 -> 1478 bytes
-rw-r--r--app/assets/images/emoji/paperclip.pngbin0 -> 439 bytes
-rw-r--r--app/assets/images/emoji/paperclips.pngbin0 -> 642 bytes
-rw-r--r--app/assets/images/emoji/park.pngbin0 -> 929 bytes
-rw-r--r--app/assets/images/emoji/parking.pngbin0 -> 385 bytes
-rw-r--r--app/assets/images/emoji/part_alternation_mark.pngbin0 -> 521 bytes
-rw-r--r--app/assets/images/emoji/partly_sunny.pngbin0 -> 977 bytes
-rw-r--r--app/assets/images/emoji/passport_control.pngbin0 -> 683 bytes
-rw-r--r--app/assets/images/emoji/pause_button.pngbin0 -> 395 bytes
-rw-r--r--app/assets/images/emoji/peace.pngbin0 -> 933 bytes
-rw-r--r--app/assets/images/emoji/peach.pngbin0 -> 1189 bytes
-rw-r--r--app/assets/images/emoji/peanuts.pngbin0 -> 3266 bytes
-rw-r--r--app/assets/images/emoji/pear.pngbin0 -> 747 bytes
-rw-r--r--app/assets/images/emoji/pen_ballpoint.pngbin0 -> 696 bytes
-rw-r--r--app/assets/images/emoji/pen_fountain.pngbin0 -> 623 bytes
-rw-r--r--app/assets/images/emoji/pencil.pngbin0 -> 1624 bytes
-rw-r--r--app/assets/images/emoji/pencil2.pngbin0 -> 654 bytes
-rw-r--r--app/assets/images/emoji/penguin.pngbin0 -> 1034 bytes
-rw-r--r--app/assets/images/emoji/pensive.pngbin0 -> 718 bytes
-rw-r--r--app/assets/images/emoji/performing_arts.pngbin0 -> 1971 bytes
-rw-r--r--app/assets/images/emoji/persevere.pngbin0 -> 891 bytes
-rw-r--r--app/assets/images/emoji/person_frowning.pngbin0 -> 1148 bytes
-rw-r--r--app/assets/images/emoji/person_frowning_tone1.pngbin0 -> 1141 bytes
-rw-r--r--app/assets/images/emoji/person_frowning_tone2.pngbin0 -> 1141 bytes
-rw-r--r--app/assets/images/emoji/person_frowning_tone3.pngbin0 -> 1141 bytes
-rw-r--r--app/assets/images/emoji/person_frowning_tone4.pngbin0 -> 1109 bytes
-rw-r--r--app/assets/images/emoji/person_frowning_tone5.pngbin0 -> 1114 bytes
-rw-r--r--app/assets/images/emoji/person_with_blond_hair.pngbin0 -> 1205 bytes
-rw-r--r--app/assets/images/emoji/person_with_blond_hair_tone1.pngbin0 -> 1181 bytes
-rw-r--r--app/assets/images/emoji/person_with_blond_hair_tone2.pngbin0 -> 1181 bytes
-rw-r--r--app/assets/images/emoji/person_with_blond_hair_tone3.pngbin0 -> 1181 bytes
-rw-r--r--app/assets/images/emoji/person_with_blond_hair_tone4.pngbin0 -> 1189 bytes
-rw-r--r--app/assets/images/emoji/person_with_blond_hair_tone5.pngbin0 -> 1214 bytes
-rw-r--r--app/assets/images/emoji/person_with_pouting_face.pngbin0 -> 1297 bytes
-rw-r--r--app/assets/images/emoji/person_with_pouting_face_tone1.pngbin0 -> 1309 bytes
-rw-r--r--app/assets/images/emoji/person_with_pouting_face_tone2.pngbin0 -> 1292 bytes
-rw-r--r--app/assets/images/emoji/person_with_pouting_face_tone3.pngbin0 -> 1305 bytes
-rw-r--r--app/assets/images/emoji/person_with_pouting_face_tone4.pngbin0 -> 1296 bytes
-rw-r--r--app/assets/images/emoji/person_with_pouting_face_tone5.pngbin0 -> 1303 bytes
-rw-r--r--app/assets/images/emoji/pick.pngbin0 -> 1023 bytes
-rw-r--r--app/assets/images/emoji/pig.pngbin0 -> 1138 bytes
-rw-r--r--app/assets/images/emoji/pig2.pngbin0 -> 1548 bytes
-rw-r--r--app/assets/images/emoji/pig_nose.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/pill.pngbin0 -> 442 bytes
-rw-r--r--app/assets/images/emoji/pineapple.pngbin0 -> 1642 bytes
-rw-r--r--app/assets/images/emoji/ping_pong.pngbin0 -> 823 bytes
-rw-r--r--app/assets/images/emoji/pisces.pngbin0 -> 678 bytes
-rw-r--r--app/assets/images/emoji/pizza.pngbin0 -> 2008 bytes
-rw-r--r--app/assets/images/emoji/place_of_worship.pngbin0 -> 487 bytes
-rw-r--r--app/assets/images/emoji/play_pause.pngbin0 -> 509 bytes
-rw-r--r--app/assets/images/emoji/point_down.pngbin0 -> 853 bytes
-rw-r--r--app/assets/images/emoji/point_down_tone1.pngbin0 -> 856 bytes
-rw-r--r--app/assets/images/emoji/point_down_tone2.pngbin0 -> 856 bytes
-rw-r--r--app/assets/images/emoji/point_down_tone3.pngbin0 -> 858 bytes
-rw-r--r--app/assets/images/emoji/point_down_tone4.pngbin0 -> 856 bytes
-rw-r--r--app/assets/images/emoji/point_down_tone5.pngbin0 -> 856 bytes
-rw-r--r--app/assets/images/emoji/point_left.pngbin0 -> 825 bytes
-rw-r--r--app/assets/images/emoji/point_left_tone1.pngbin0 -> 832 bytes
-rw-r--r--app/assets/images/emoji/point_left_tone2.pngbin0 -> 830 bytes
-rw-r--r--app/assets/images/emoji/point_left_tone3.pngbin0 -> 830 bytes
-rw-r--r--app/assets/images/emoji/point_left_tone4.pngbin0 -> 830 bytes
-rw-r--r--app/assets/images/emoji/point_left_tone5.pngbin0 -> 832 bytes
-rw-r--r--app/assets/images/emoji/point_right.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/point_right_tone1.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/point_right_tone2.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/point_right_tone3.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/point_right_tone4.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/point_right_tone5.pngbin0 -> 805 bytes
-rw-r--r--app/assets/images/emoji/point_up.pngbin0 -> 819 bytes
-rw-r--r--app/assets/images/emoji/point_up_2.pngbin0 -> 822 bytes
-rw-r--r--app/assets/images/emoji/point_up_2_tone1.pngbin0 -> 822 bytes
-rw-r--r--app/assets/images/emoji/point_up_2_tone2.pngbin0 -> 822 bytes
-rw-r--r--app/assets/images/emoji/point_up_2_tone3.pngbin0 -> 871 bytes
-rw-r--r--app/assets/images/emoji/point_up_2_tone4.pngbin0 -> 822 bytes
-rw-r--r--app/assets/images/emoji/point_up_2_tone5.pngbin0 -> 822 bytes
-rw-r--r--app/assets/images/emoji/point_up_tone1.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/point_up_tone2.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/point_up_tone3.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/point_up_tone4.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/point_up_tone5.pngbin0 -> 820 bytes
-rw-r--r--app/assets/images/emoji/police_car.pngbin0 -> 1431 bytes
-rw-r--r--app/assets/images/emoji/poodle.pngbin0 -> 1531 bytes
-rw-r--r--app/assets/images/emoji/poop.pngbin0 -> 1273 bytes
-rw-r--r--app/assets/images/emoji/popcorn.pngbin0 -> 1843 bytes
-rw-r--r--app/assets/images/emoji/post_office.pngbin0 -> 676 bytes
-rw-r--r--app/assets/images/emoji/postal_horn.pngbin0 -> 809 bytes
-rw-r--r--app/assets/images/emoji/postbox.pngbin0 -> 1077 bytes
-rw-r--r--app/assets/images/emoji/potable_water.pngbin0 -> 633 bytes
-rw-r--r--app/assets/images/emoji/potato.pngbin0 -> 1246 bytes
-rw-r--r--app/assets/images/emoji/pouch.pngbin0 -> 1259 bytes
-rw-r--r--app/assets/images/emoji/poultry_leg.pngbin0 -> 925 bytes
-rw-r--r--app/assets/images/emoji/pound.pngbin0 -> 452 bytes
-rw-r--r--app/assets/images/emoji/pouting_cat.pngbin0 -> 1675 bytes
-rw-r--r--app/assets/images/emoji/pray.pngbin0 -> 1122 bytes
-rw-r--r--app/assets/images/emoji/pray_tone1.pngbin0 -> 1131 bytes
-rw-r--r--app/assets/images/emoji/pray_tone2.pngbin0 -> 1134 bytes
-rw-r--r--app/assets/images/emoji/pray_tone3.pngbin0 -> 1137 bytes
-rw-r--r--app/assets/images/emoji/pray_tone4.pngbin0 -> 1126 bytes
-rw-r--r--app/assets/images/emoji/pray_tone5.pngbin0 -> 1117 bytes
-rw-r--r--app/assets/images/emoji/prayer_beads.pngbin0 -> 1059 bytes
-rw-r--r--app/assets/images/emoji/pregnant_woman.pngbin0 -> 1252 bytes
-rw-r--r--app/assets/images/emoji/pregnant_woman_tone1.pngbin0 -> 1255 bytes
-rw-r--r--app/assets/images/emoji/pregnant_woman_tone2.pngbin0 -> 1246 bytes
-rw-r--r--app/assets/images/emoji/pregnant_woman_tone3.pngbin0 -> 1237 bytes
-rw-r--r--app/assets/images/emoji/pregnant_woman_tone4.pngbin0 -> 1246 bytes
-rw-r--r--app/assets/images/emoji/pregnant_woman_tone5.pngbin0 -> 1235 bytes
-rw-r--r--app/assets/images/emoji/prince.pngbin0 -> 1616 bytes
-rw-r--r--app/assets/images/emoji/prince_tone1.pngbin0 -> 1618 bytes
-rw-r--r--app/assets/images/emoji/prince_tone2.pngbin0 -> 1621 bytes
-rw-r--r--app/assets/images/emoji/prince_tone3.pngbin0 -> 1619 bytes
-rw-r--r--app/assets/images/emoji/prince_tone4.pngbin0 -> 1619 bytes
-rw-r--r--app/assets/images/emoji/prince_tone5.pngbin0 -> 1616 bytes
-rw-r--r--app/assets/images/emoji/princess.pngbin0 -> 1812 bytes
-rw-r--r--app/assets/images/emoji/princess_tone1.pngbin0 -> 1812 bytes
-rw-r--r--app/assets/images/emoji/princess_tone2.pngbin0 -> 1805 bytes
-rw-r--r--app/assets/images/emoji/princess_tone3.pngbin0 -> 1805 bytes
-rw-r--r--app/assets/images/emoji/princess_tone4.pngbin0 -> 1813 bytes
-rw-r--r--app/assets/images/emoji/princess_tone5.pngbin0 -> 1812 bytes
-rw-r--r--app/assets/images/emoji/printer.pngbin0 -> 926 bytes
-rw-r--r--app/assets/images/emoji/projector.pngbin0 -> 943 bytes
-rw-r--r--app/assets/images/emoji/punch.pngbin0 -> 838 bytes
-rw-r--r--app/assets/images/emoji/punch_tone1.pngbin0 -> 838 bytes
-rw-r--r--app/assets/images/emoji/punch_tone2.pngbin0 -> 838 bytes
-rw-r--r--app/assets/images/emoji/punch_tone3.pngbin0 -> 838 bytes
-rw-r--r--app/assets/images/emoji/punch_tone4.pngbin0 -> 838 bytes
-rw-r--r--app/assets/images/emoji/punch_tone5.pngbin0 -> 838 bytes
-rw-r--r--app/assets/images/emoji/purple_heart.pngbin0 -> 435 bytes
-rw-r--r--app/assets/images/emoji/purse.pngbin0 -> 1558 bytes
-rw-r--r--app/assets/images/emoji/pushpin.pngbin0 -> 640 bytes
-rw-r--r--app/assets/images/emoji/put_litter_in_its_place.pngbin0 -> 650 bytes
-rw-r--r--app/assets/images/emoji/question.pngbin0 -> 449 bytes
-rw-r--r--app/assets/images/emoji/rabbit.pngbin0 -> 1660 bytes
-rw-r--r--app/assets/images/emoji/rabbit2.pngbin0 -> 1805 bytes
-rw-r--r--app/assets/images/emoji/race_car.pngbin0 -> 2140 bytes
-rw-r--r--app/assets/images/emoji/racehorse.pngbin0 -> 1401 bytes
-rw-r--r--app/assets/images/emoji/radio.pngbin0 -> 851 bytes
-rw-r--r--app/assets/images/emoji/radio_button.pngbin0 -> 674 bytes
-rw-r--r--app/assets/images/emoji/radioactive.pngbin0 -> 858 bytes
-rw-r--r--app/assets/images/emoji/rage.pngbin0 -> 845 bytes
-rw-r--r--app/assets/images/emoji/railway_car.pngbin0 -> 847 bytes
-rw-r--r--app/assets/images/emoji/railway_track.pngbin0 -> 1550 bytes
-rw-r--r--app/assets/images/emoji/rainbow.pngbin0 -> 1299 bytes
-rw-r--r--app/assets/images/emoji/raised_back_of_hand.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/raised_back_of_hand_tone1.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/raised_back_of_hand_tone2.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/raised_back_of_hand_tone3.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/raised_back_of_hand_tone4.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/raised_back_of_hand_tone5.pngbin0 -> 848 bytes
-rw-r--r--app/assets/images/emoji/raised_hand.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/raised_hand_tone1.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/raised_hand_tone2.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/raised_hand_tone3.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/raised_hand_tone4.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/raised_hand_tone5.pngbin0 -> 791 bytes
-rw-r--r--app/assets/images/emoji/raised_hands.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/raised_hands_tone1.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/raised_hands_tone2.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/raised_hands_tone3.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/raised_hands_tone4.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/raised_hands_tone5.pngbin0 -> 1098 bytes
-rw-r--r--app/assets/images/emoji/raising_hand.pngbin0 -> 1664 bytes
-rw-r--r--app/assets/images/emoji/raising_hand_tone1.pngbin0 -> 1678 bytes
-rw-r--r--app/assets/images/emoji/raising_hand_tone2.pngbin0 -> 1665 bytes
-rw-r--r--app/assets/images/emoji/raising_hand_tone3.pngbin0 -> 1657 bytes
-rw-r--r--app/assets/images/emoji/raising_hand_tone4.pngbin0 -> 1657 bytes
-rw-r--r--app/assets/images/emoji/raising_hand_tone5.pngbin0 -> 1661 bytes
-rw-r--r--app/assets/images/emoji/ram.pngbin0 -> 1951 bytes
-rw-r--r--app/assets/images/emoji/ramen.pngbin0 -> 1992 bytes
-rw-r--r--app/assets/images/emoji/rat.pngbin0 -> 1193 bytes
-rw-r--r--app/assets/images/emoji/record_button.pngbin0 -> 475 bytes
-rw-r--r--app/assets/images/emoji/recycle.pngbin0 -> 914 bytes
-rw-r--r--app/assets/images/emoji/red_car.pngbin0 -> 1065 bytes
-rw-r--r--app/assets/images/emoji/red_circle.pngbin0 -> 374 bytes
-rw-r--r--app/assets/images/emoji/registered.pngbin0 -> 547 bytes
-rw-r--r--app/assets/images/emoji/relaxed.pngbin0 -> 636 bytes
-rw-r--r--app/assets/images/emoji/relieved.pngbin0 -> 785 bytes
-rw-r--r--app/assets/images/emoji/reminder_ribbon.pngbin0 -> 921 bytes
-rw-r--r--app/assets/images/emoji/repeat.pngbin0 -> 644 bytes
-rw-r--r--app/assets/images/emoji/repeat_one.pngbin0 -> 688 bytes
-rw-r--r--app/assets/images/emoji/restroom.pngbin0 -> 676 bytes
-rw-r--r--app/assets/images/emoji/revolving_hearts.pngbin0 -> 920 bytes
-rw-r--r--app/assets/images/emoji/rewind.pngbin0 -> 523 bytes
-rw-r--r--app/assets/images/emoji/rhino.pngbin0 -> 1558 bytes
-rw-r--r--app/assets/images/emoji/ribbon.pngbin0 -> 968 bytes
-rw-r--r--app/assets/images/emoji/rice.pngbin0 -> 1195 bytes
-rw-r--r--app/assets/images/emoji/rice_ball.pngbin0 -> 1091 bytes
-rw-r--r--app/assets/images/emoji/rice_cracker.pngbin0 -> 1443 bytes
-rw-r--r--app/assets/images/emoji/rice_scene.pngbin0 -> 1349 bytes
-rw-r--r--app/assets/images/emoji/right_facing_fist.pngbin0 -> 975 bytes
-rw-r--r--app/assets/images/emoji/right_facing_fist_tone1.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/right_facing_fist_tone2.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/right_facing_fist_tone3.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/right_facing_fist_tone4.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/right_facing_fist_tone5.pngbin0 -> 964 bytes
-rw-r--r--app/assets/images/emoji/ring.pngbin0 -> 1113 bytes
-rw-r--r--app/assets/images/emoji/robot.pngbin0 -> 1228 bytes
-rw-r--r--app/assets/images/emoji/rocket.pngbin0 -> 1639 bytes
-rw-r--r--app/assets/images/emoji/rofl.pngbin0 -> 1760 bytes
-rw-r--r--app/assets/images/emoji/roller_coaster.pngbin0 -> 1723 bytes
-rw-r--r--app/assets/images/emoji/rolling_eyes.pngbin0 -> 743 bytes
-rw-r--r--app/assets/images/emoji/rooster.pngbin0 -> 1333 bytes
-rw-r--r--app/assets/images/emoji/rose.pngbin0 -> 1182 bytes
-rw-r--r--app/assets/images/emoji/rosette.pngbin0 -> 1023 bytes
-rw-r--r--app/assets/images/emoji/rotating_light.pngbin0 -> 1969 bytes
-rw-r--r--app/assets/images/emoji/round_pushpin.pngbin0 -> 455 bytes
-rw-r--r--app/assets/images/emoji/rowboat.pngbin0 -> 1963 bytes
-rw-r--r--app/assets/images/emoji/rowboat_tone1.pngbin0 -> 1971 bytes
-rw-r--r--app/assets/images/emoji/rowboat_tone2.pngbin0 -> 1972 bytes
-rw-r--r--app/assets/images/emoji/rowboat_tone3.pngbin0 -> 1967 bytes
-rw-r--r--app/assets/images/emoji/rowboat_tone4.pngbin0 -> 1974 bytes
-rw-r--r--app/assets/images/emoji/rowboat_tone5.pngbin0 -> 1971 bytes
-rw-r--r--app/assets/images/emoji/rugby_football.pngbin0 -> 1618 bytes
-rw-r--r--app/assets/images/emoji/runner.pngbin0 -> 1161 bytes
-rw-r--r--app/assets/images/emoji/runner_tone1.pngbin0 -> 1163 bytes
-rw-r--r--app/assets/images/emoji/runner_tone2.pngbin0 -> 1162 bytes
-rw-r--r--app/assets/images/emoji/runner_tone3.pngbin0 -> 1151 bytes
-rw-r--r--app/assets/images/emoji/runner_tone4.pngbin0 -> 1156 bytes
-rw-r--r--app/assets/images/emoji/runner_tone5.pngbin0 -> 1145 bytes
-rw-r--r--app/assets/images/emoji/running_shirt_with_sash.pngbin0 -> 784 bytes
-rw-r--r--app/assets/images/emoji/sa.pngbin0 -> 420 bytes
-rw-r--r--app/assets/images/emoji/sagittarius.pngbin0 -> 602 bytes
-rw-r--r--app/assets/images/emoji/sailboat.pngbin0 -> 1274 bytes
-rw-r--r--app/assets/images/emoji/sake.pngbin0 -> 826 bytes
-rw-r--r--app/assets/images/emoji/salad.pngbin0 -> 2398 bytes
-rw-r--r--app/assets/images/emoji/sandal.pngbin0 -> 1180 bytes
-rw-r--r--app/assets/images/emoji/santa.pngbin0 -> 1585 bytes
-rw-r--r--app/assets/images/emoji/santa_tone1.pngbin0 -> 1585 bytes
-rw-r--r--app/assets/images/emoji/santa_tone2.pngbin0 -> 1578 bytes
-rw-r--r--app/assets/images/emoji/santa_tone3.pngbin0 -> 1578 bytes
-rw-r--r--app/assets/images/emoji/santa_tone4.pngbin0 -> 1578 bytes
-rw-r--r--app/assets/images/emoji/santa_tone5.pngbin0 -> 1578 bytes
-rw-r--r--app/assets/images/emoji/satellite.pngbin0 -> 1173 bytes
-rw-r--r--app/assets/images/emoji/satellite_orbital.pngbin0 -> 762 bytes
-rw-r--r--app/assets/images/emoji/saxophone.pngbin0 -> 1442 bytes
-rw-r--r--app/assets/images/emoji/scales.pngbin0 -> 1181 bytes
-rw-r--r--app/assets/images/emoji/school.pngbin0 -> 1234 bytes
-rw-r--r--app/assets/images/emoji/school_satchel.pngbin0 -> 1490 bytes
-rw-r--r--app/assets/images/emoji/scissors.pngbin0 -> 937 bytes
-rw-r--r--app/assets/images/emoji/scooter.pngbin0 -> 1228 bytes
-rw-r--r--app/assets/images/emoji/scorpion.pngbin0 -> 1503 bytes
-rw-r--r--app/assets/images/emoji/scorpius.pngbin0 -> 612 bytes
-rw-r--r--app/assets/images/emoji/scream.pngbin0 -> 1583 bytes
-rw-r--r--app/assets/images/emoji/scream_cat.pngbin0 -> 2120 bytes
-rw-r--r--app/assets/images/emoji/scroll.pngbin0 -> 989 bytes
-rw-r--r--app/assets/images/emoji/seat.pngbin0 -> 884 bytes
-rw-r--r--app/assets/images/emoji/second_place.pngbin0 -> 1511 bytes
-rw-r--r--app/assets/images/emoji/secret.pngbin0 -> 857 bytes
-rw-r--r--app/assets/images/emoji/see_no_evil.pngbin0 -> 1227 bytes
-rw-r--r--app/assets/images/emoji/seedling.pngbin0 -> 749 bytes
-rw-r--r--app/assets/images/emoji/selfie.pngbin0 -> 1160 bytes
-rw-r--r--app/assets/images/emoji/selfie_tone1.pngbin0 -> 1166 bytes
-rw-r--r--app/assets/images/emoji/selfie_tone2.pngbin0 -> 1167 bytes
-rw-r--r--app/assets/images/emoji/selfie_tone3.pngbin0 -> 1154 bytes
-rw-r--r--app/assets/images/emoji/selfie_tone4.pngbin0 -> 1153 bytes
-rw-r--r--app/assets/images/emoji/selfie_tone5.pngbin0 -> 1148 bytes
-rw-r--r--app/assets/images/emoji/seven.pngbin0 -> 522 bytes
-rw-r--r--app/assets/images/emoji/shallow_pan_of_food.pngbin0 -> 1738 bytes
-rw-r--r--app/assets/images/emoji/shamrock.pngbin0 -> 1023 bytes
-rw-r--r--app/assets/images/emoji/shark.pngbin0 -> 1811 bytes
-rw-r--r--app/assets/images/emoji/shaved_ice.pngbin0 -> 997 bytes
-rw-r--r--app/assets/images/emoji/sheep.pngbin0 -> 1372 bytes
-rw-r--r--app/assets/images/emoji/shell.pngbin0 -> 1497 bytes
-rw-r--r--app/assets/images/emoji/shield.pngbin0 -> 1602 bytes
-rw-r--r--app/assets/images/emoji/shinto_shrine.pngbin0 -> 579 bytes
-rw-r--r--app/assets/images/emoji/ship.pngbin0 -> 1405 bytes
-rw-r--r--app/assets/images/emoji/shirt.pngbin0 -> 670 bytes
-rw-r--r--app/assets/images/emoji/shopping_bags.pngbin0 -> 1234 bytes
-rw-r--r--app/assets/images/emoji/shopping_cart.pngbin0 -> 1072 bytes
-rw-r--r--app/assets/images/emoji/shower.pngbin0 -> 2537 bytes
-rw-r--r--app/assets/images/emoji/shrimp.pngbin0 -> 1376 bytes
-rw-r--r--app/assets/images/emoji/shrug.pngbin0 -> 1671 bytes
-rw-r--r--app/assets/images/emoji/shrug_tone1.pngbin0 -> 1676 bytes
-rw-r--r--app/assets/images/emoji/shrug_tone2.pngbin0 -> 1671 bytes
-rw-r--r--app/assets/images/emoji/shrug_tone3.pngbin0 -> 1675 bytes
-rw-r--r--app/assets/images/emoji/shrug_tone4.pngbin0 -> 1641 bytes
-rw-r--r--app/assets/images/emoji/shrug_tone5.pngbin0 -> 1634 bytes
-rw-r--r--app/assets/images/emoji/signal_strength.pngbin0 -> 445 bytes
-rw-r--r--app/assets/images/emoji/six.pngbin0 -> 612 bytes
-rw-r--r--app/assets/images/emoji/six_pointed_star.pngbin0 -> 540 bytes
-rw-r--r--app/assets/images/emoji/ski.pngbin0 -> 1762 bytes
-rw-r--r--app/assets/images/emoji/skier.pngbin0 -> 1539 bytes
-rw-r--r--app/assets/images/emoji/skull.pngbin0 -> 628 bytes
-rw-r--r--app/assets/images/emoji/skull_crossbones.pngbin0 -> 726 bytes
-rw-r--r--app/assets/images/emoji/sleeping.pngbin0 -> 1075 bytes
-rw-r--r--app/assets/images/emoji/sleeping_accommodation.pngbin0 -> 926 bytes
-rw-r--r--app/assets/images/emoji/sleepy.pngbin0 -> 1185 bytes
-rw-r--r--app/assets/images/emoji/slight_frown.pngbin0 -> 580 bytes
-rw-r--r--app/assets/images/emoji/slight_smile.pngbin0 -> 600 bytes
-rw-r--r--app/assets/images/emoji/slot_machine.pngbin0 -> 1648 bytes
-rw-r--r--app/assets/images/emoji/small_blue_diamond.pngbin0 -> 191 bytes
-rw-r--r--app/assets/images/emoji/small_orange_diamond.pngbin0 -> 194 bytes
-rw-r--r--app/assets/images/emoji/small_red_triangle.pngbin0 -> 273 bytes
-rw-r--r--app/assets/images/emoji/small_red_triangle_down.pngbin0 -> 291 bytes
-rw-r--r--app/assets/images/emoji/smile.pngbin0 -> 737 bytes
-rw-r--r--app/assets/images/emoji/smile_cat.pngbin0 -> 1405 bytes
-rw-r--r--app/assets/images/emoji/smiley.pngbin0 -> 686 bytes
-rw-r--r--app/assets/images/emoji/smiley_cat.pngbin0 -> 1669 bytes
-rw-r--r--app/assets/images/emoji/smiling_imp.pngbin0 -> 1078 bytes
-rw-r--r--app/assets/images/emoji/smirk.pngbin0 -> 775 bytes
-rw-r--r--app/assets/images/emoji/smirk_cat.pngbin0 -> 1663 bytes
-rw-r--r--app/assets/images/emoji/smoking.pngbin0 -> 417 bytes
-rw-r--r--app/assets/images/emoji/snail.pngbin0 -> 1731 bytes
-rw-r--r--app/assets/images/emoji/snake.pngbin0 -> 1575 bytes
-rw-r--r--app/assets/images/emoji/sneezing_face.pngbin0 -> 1289 bytes
-rw-r--r--app/assets/images/emoji/snowboarder.pngbin0 -> 2020 bytes
-rw-r--r--app/assets/images/emoji/snowflake.pngbin0 -> 691 bytes
-rw-r--r--app/assets/images/emoji/snowman.pngbin0 -> 1481 bytes
-rw-r--r--app/assets/images/emoji/snowman2.pngbin0 -> 2176 bytes
-rw-r--r--app/assets/images/emoji/sob.pngbin0 -> 1236 bytes
-rw-r--r--app/assets/images/emoji/soccer.pngbin0 -> 1034 bytes
-rw-r--r--app/assets/images/emoji/soon.pngbin0 -> 483 bytes
-rw-r--r--app/assets/images/emoji/sos.pngbin0 -> 604 bytes
-rw-r--r--app/assets/images/emoji/sound.pngbin0 -> 690 bytes
-rw-r--r--app/assets/images/emoji/space_invader.pngbin0 -> 1325 bytes
-rw-r--r--app/assets/images/emoji/spades.pngbin0 -> 454 bytes
-rw-r--r--app/assets/images/emoji/spaghetti.pngbin0 -> 1796 bytes
-rw-r--r--app/assets/images/emoji/sparkle.pngbin0 -> 663 bytes
-rw-r--r--app/assets/images/emoji/sparkler.pngbin0 -> 910 bytes
-rw-r--r--app/assets/images/emoji/sparkles.pngbin0 -> 651 bytes
-rw-r--r--app/assets/images/emoji/sparkling_heart.pngbin0 -> 821 bytes
-rw-r--r--app/assets/images/emoji/speak_no_evil.pngbin0 -> 1497 bytes
-rw-r--r--app/assets/images/emoji/speaker.pngbin0 -> 575 bytes
-rw-r--r--app/assets/images/emoji/speaking_head.pngbin0 -> 531 bytes
-rw-r--r--app/assets/images/emoji/speech_balloon.pngbin0 -> 384 bytes
-rw-r--r--app/assets/images/emoji/speedboat.pngbin0 -> 1255 bytes
-rw-r--r--app/assets/images/emoji/spider.pngbin0 -> 1724 bytes
-rw-r--r--app/assets/images/emoji/spider_web.pngbin0 -> 929 bytes
-rw-r--r--app/assets/images/emoji/spoon.pngbin0 -> 700 bytes
-rw-r--r--app/assets/images/emoji/spy.pngbin0 -> 1650 bytes
-rw-r--r--app/assets/images/emoji/spy_tone1.pngbin0 -> 1639 bytes
-rw-r--r--app/assets/images/emoji/spy_tone2.pngbin0 -> 1632 bytes
-rw-r--r--app/assets/images/emoji/spy_tone3.pngbin0 -> 1645 bytes
-rw-r--r--app/assets/images/emoji/spy_tone4.pngbin0 -> 1639 bytes
-rw-r--r--app/assets/images/emoji/spy_tone5.pngbin0 -> 1639 bytes
-rw-r--r--app/assets/images/emoji/squid.pngbin0 -> 1394 bytes
-rw-r--r--app/assets/images/emoji/stadium.pngbin0 -> 1515 bytes
-rw-r--r--app/assets/images/emoji/star.pngbin0 -> 456 bytes
-rw-r--r--app/assets/images/emoji/star2.pngbin0 -> 732 bytes
-rw-r--r--app/assets/images/emoji/star_and_crescent.pngbin0 -> 490 bytes
-rw-r--r--app/assets/images/emoji/star_of_david.pngbin0 -> 491 bytes
-rw-r--r--app/assets/images/emoji/stars.pngbin0 -> 1048 bytes
-rw-r--r--app/assets/images/emoji/station.pngbin0 -> 1336 bytes
-rw-r--r--app/assets/images/emoji/statue_of_liberty.pngbin0 -> 1145 bytes
-rw-r--r--app/assets/images/emoji/steam_locomotive.pngbin0 -> 1736 bytes
-rw-r--r--app/assets/images/emoji/stew.pngbin0 -> 1960 bytes
-rw-r--r--app/assets/images/emoji/stop_button.pngbin0 -> 385 bytes
-rw-r--r--app/assets/images/emoji/stopwatch.pngbin0 -> 1329 bytes
-rw-r--r--app/assets/images/emoji/straight_ruler.pngbin0 -> 1406 bytes
-rw-r--r--app/assets/images/emoji/strawberry.pngbin0 -> 1206 bytes
-rw-r--r--app/assets/images/emoji/stuck_out_tongue.pngbin0 -> 752 bytes
-rw-r--r--app/assets/images/emoji/stuck_out_tongue_closed_eyes.pngbin0 -> 867 bytes
-rw-r--r--app/assets/images/emoji/stuck_out_tongue_winking_eye.pngbin0 -> 1061 bytes
-rw-r--r--app/assets/images/emoji/stuffed_flatbread.pngbin0 -> 2160 bytes
-rw-r--r--app/assets/images/emoji/sun_with_face.pngbin0 -> 741 bytes
-rw-r--r--app/assets/images/emoji/sunflower.pngbin0 -> 1915 bytes
-rw-r--r--app/assets/images/emoji/sunglasses.pngbin0 -> 824 bytes
-rw-r--r--app/assets/images/emoji/sunny.pngbin0 -> 746 bytes
-rw-r--r--app/assets/images/emoji/sunrise.pngbin0 -> 812 bytes
-rw-r--r--app/assets/images/emoji/sunrise_over_mountains.pngbin0 -> 1576 bytes
-rw-r--r--app/assets/images/emoji/surfer.pngbin0 -> 1777 bytes
-rw-r--r--app/assets/images/emoji/surfer_tone1.pngbin0 -> 1781 bytes
-rw-r--r--app/assets/images/emoji/surfer_tone2.pngbin0 -> 1769 bytes
-rw-r--r--app/assets/images/emoji/surfer_tone3.pngbin0 -> 1777 bytes
-rw-r--r--app/assets/images/emoji/surfer_tone4.pngbin0 -> 1784 bytes
-rw-r--r--app/assets/images/emoji/surfer_tone5.pngbin0 -> 1782 bytes
-rw-r--r--app/assets/images/emoji/sushi.pngbin0 -> 2101 bytes
-rw-r--r--app/assets/images/emoji/suspension_railway.pngbin0 -> 927 bytes
-rw-r--r--app/assets/images/emoji/sweat.pngbin0 -> 861 bytes
-rw-r--r--app/assets/images/emoji/sweat_drops.pngbin0 -> 549 bytes
-rw-r--r--app/assets/images/emoji/sweat_smile.pngbin0 -> 851 bytes
-rw-r--r--app/assets/images/emoji/sweet_potato.pngbin0 -> 951 bytes
-rw-r--r--app/assets/images/emoji/swimmer.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/swimmer_tone1.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/swimmer_tone2.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/swimmer_tone3.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/swimmer_tone4.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/swimmer_tone5.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/symbols.pngbin0 -> 746 bytes
-rw-r--r--app/assets/images/emoji/synagogue.pngbin0 -> 1309 bytes
-rw-r--r--app/assets/images/emoji/syringe.pngbin0 -> 737 bytes
-rw-r--r--app/assets/images/emoji/taco.pngbin0 -> 3045 bytes
-rw-r--r--app/assets/images/emoji/tada.pngbin0 -> 1778 bytes
-rw-r--r--app/assets/images/emoji/tanabata_tree.pngbin0 -> 1479 bytes
-rw-r--r--app/assets/images/emoji/tangerine.pngbin0 -> 1184 bytes
-rw-r--r--app/assets/images/emoji/taurus.pngbin0 -> 701 bytes
-rw-r--r--app/assets/images/emoji/taxi.pngbin0 -> 1230 bytes
-rw-r--r--app/assets/images/emoji/tea.pngbin0 -> 1297 bytes
-rw-r--r--app/assets/images/emoji/telephone.pngbin0 -> 1760 bytes
-rw-r--r--app/assets/images/emoji/telephone_receiver.pngbin0 -> 941 bytes
-rw-r--r--app/assets/images/emoji/telescope.pngbin0 -> 1256 bytes
-rw-r--r--app/assets/images/emoji/ten.pngbin0 -> 621 bytes
-rw-r--r--app/assets/images/emoji/tennis.pngbin0 -> 1561 bytes
-rw-r--r--app/assets/images/emoji/tent.pngbin0 -> 1684 bytes
-rw-r--r--app/assets/images/emoji/thermometer.pngbin0 -> 759 bytes
-rw-r--r--app/assets/images/emoji/thermometer_face.pngbin0 -> 1503 bytes
-rw-r--r--app/assets/images/emoji/thinking.pngbin0 -> 1345 bytes
-rw-r--r--app/assets/images/emoji/third_place.pngbin0 -> 1529 bytes
-rw-r--r--app/assets/images/emoji/thought_balloon.pngbin0 -> 489 bytes
-rw-r--r--app/assets/images/emoji/three.pngbin0 -> 602 bytes
-rw-r--r--app/assets/images/emoji/thumbsdown.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/thumbsdown_tone1.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/thumbsdown_tone2.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/thumbsdown_tone3.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/thumbsdown_tone4.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/thumbsdown_tone5.pngbin0 -> 815 bytes
-rw-r--r--app/assets/images/emoji/thumbsup.pngbin0 -> 814 bytes
-rw-r--r--app/assets/images/emoji/thumbsup_tone1.pngbin0 -> 814 bytes
-rw-r--r--app/assets/images/emoji/thumbsup_tone2.pngbin0 -> 814 bytes
-rw-r--r--app/assets/images/emoji/thumbsup_tone3.pngbin0 -> 814 bytes
-rw-r--r--app/assets/images/emoji/thumbsup_tone4.pngbin0 -> 814 bytes
-rw-r--r--app/assets/images/emoji/thumbsup_tone5.pngbin0 -> 814 bytes
-rw-r--r--app/assets/images/emoji/thunder_cloud_rain.pngbin0 -> 1020 bytes
-rw-r--r--app/assets/images/emoji/ticket.pngbin0 -> 763 bytes
-rw-r--r--app/assets/images/emoji/tickets.pngbin0 -> 1750 bytes
-rw-r--r--app/assets/images/emoji/tiger.pngbin0 -> 2104 bytes
-rw-r--r--app/assets/images/emoji/tiger2.pngbin0 -> 2623 bytes
-rw-r--r--app/assets/images/emoji/timer.pngbin0 -> 1897 bytes
-rw-r--r--app/assets/images/emoji/tired_face.pngbin0 -> 1126 bytes
-rw-r--r--app/assets/images/emoji/tm.pngbin0 -> 300 bytes
-rw-r--r--app/assets/images/emoji/toilet.pngbin0 -> 726 bytes
-rw-r--r--app/assets/images/emoji/tokyo_tower.pngbin0 -> 765 bytes
-rw-r--r--app/assets/images/emoji/tomato.pngbin0 -> 1055 bytes
-rw-r--r--app/assets/images/emoji/tone1.pngbin0 -> 372 bytes
-rw-r--r--app/assets/images/emoji/tone2.pngbin0 -> 372 bytes
-rw-r--r--app/assets/images/emoji/tone3.pngbin0 -> 375 bytes
-rw-r--r--app/assets/images/emoji/tone4.pngbin0 -> 374 bytes
-rw-r--r--app/assets/images/emoji/tone5.pngbin0 -> 374 bytes
-rw-r--r--app/assets/images/emoji/tongue.pngbin0 -> 599 bytes
-rw-r--r--app/assets/images/emoji/tools.pngbin0 -> 1225 bytes
-rw-r--r--app/assets/images/emoji/top.pngbin0 -> 389 bytes
-rw-r--r--app/assets/images/emoji/tophat.pngbin0 -> 845 bytes
-rw-r--r--app/assets/images/emoji/track_next.pngbin0 -> 551 bytes
-rw-r--r--app/assets/images/emoji/track_previous.pngbin0 -> 549 bytes
-rw-r--r--app/assets/images/emoji/trackball.pngbin0 -> 892 bytes
-rw-r--r--app/assets/images/emoji/tractor.pngbin0 -> 1192 bytes
-rw-r--r--app/assets/images/emoji/traffic_light.pngbin0 -> 590 bytes
-rw-r--r--app/assets/images/emoji/train.pngbin0 -> 1031 bytes
-rw-r--r--app/assets/images/emoji/train2.pngbin0 -> 1499 bytes
-rw-r--r--app/assets/images/emoji/tram.pngbin0 -> 1065 bytes
-rw-r--r--app/assets/images/emoji/triangular_flag_on_post.pngbin0 -> 415 bytes
-rw-r--r--app/assets/images/emoji/triangular_ruler.pngbin0 -> 369 bytes
-rw-r--r--app/assets/images/emoji/trident.pngbin0 -> 668 bytes
-rw-r--r--app/assets/images/emoji/triumph.pngbin0 -> 1529 bytes
-rw-r--r--app/assets/images/emoji/trolleybus.pngbin0 -> 1168 bytes
-rw-r--r--app/assets/images/emoji/trophy.pngbin0 -> 863 bytes
-rw-r--r--app/assets/images/emoji/tropical_drink.pngbin0 -> 1428 bytes
-rw-r--r--app/assets/images/emoji/tropical_fish.pngbin0 -> 1676 bytes
-rw-r--r--app/assets/images/emoji/truck.pngbin0 -> 1366 bytes
-rw-r--r--app/assets/images/emoji/trumpet.pngbin0 -> 1281 bytes
-rw-r--r--app/assets/images/emoji/tulip.pngbin0 -> 1065 bytes
-rw-r--r--app/assets/images/emoji/tumbler_glass.pngbin0 -> 2312 bytes
-rw-r--r--app/assets/images/emoji/turkey.pngbin0 -> 1240 bytes
-rw-r--r--app/assets/images/emoji/turtle.pngbin0 -> 1515 bytes
-rw-r--r--app/assets/images/emoji/tv.pngbin0 -> 776 bytes
-rw-r--r--app/assets/images/emoji/twisted_rightwards_arrows.pngbin0 -> 574 bytes
-rw-r--r--app/assets/images/emoji/two.pngbin0 -> 567 bytes
-rw-r--r--app/assets/images/emoji/two_hearts.pngbin0 -> 493 bytes
-rw-r--r--app/assets/images/emoji/two_men_holding_hands.pngbin0 -> 1347 bytes
-rw-r--r--app/assets/images/emoji/two_women_holding_hands.pngbin0 -> 1544 bytes
-rw-r--r--app/assets/images/emoji/u5272.pngbin0 -> 411 bytes
-rw-r--r--app/assets/images/emoji/u5408.pngbin0 -> 484 bytes
-rw-r--r--app/assets/images/emoji/u55b6.pngbin0 -> 460 bytes
-rw-r--r--app/assets/images/emoji/u6307.pngbin0 -> 504 bytes
-rw-r--r--app/assets/images/emoji/u6708.pngbin0 -> 409 bytes
-rw-r--r--app/assets/images/emoji/u6709.pngbin0 -> 434 bytes
-rw-r--r--app/assets/images/emoji/u6e80.pngbin0 -> 564 bytes
-rw-r--r--app/assets/images/emoji/u7121.pngbin0 -> 534 bytes
-rw-r--r--app/assets/images/emoji/u7533.pngbin0 -> 306 bytes
-rw-r--r--app/assets/images/emoji/u7981.pngbin0 -> 584 bytes
-rw-r--r--app/assets/images/emoji/u7a7a.pngbin0 -> 456 bytes
-rw-r--r--app/assets/images/emoji/umbrella.pngbin0 -> 1229 bytes
-rw-r--r--app/assets/images/emoji/umbrella2.pngbin0 -> 897 bytes
-rw-r--r--app/assets/images/emoji/unamused.pngbin0 -> 632 bytes
-rw-r--r--app/assets/images/emoji/underage.pngbin0 -> 863 bytes
-rw-r--r--app/assets/images/emoji/unicorn.pngbin0 -> 2107 bytes
-rw-r--r--app/assets/images/emoji/unlock.pngbin0 -> 856 bytes
-rw-r--r--app/assets/images/emoji/up.pngbin0 -> 405 bytes
-rw-r--r--app/assets/images/emoji/upside_down.pngbin0 -> 602 bytes
-rw-r--r--app/assets/images/emoji/urn.pngbin0 -> 742 bytes
-rw-r--r--app/assets/images/emoji/v.pngbin0 -> 1009 bytes
-rw-r--r--app/assets/images/emoji/v_tone1.pngbin0 -> 1009 bytes
-rw-r--r--app/assets/images/emoji/v_tone2.pngbin0 -> 1009 bytes
-rw-r--r--app/assets/images/emoji/v_tone3.pngbin0 -> 1009 bytes
-rw-r--r--app/assets/images/emoji/v_tone4.pngbin0 -> 1009 bytes
-rw-r--r--app/assets/images/emoji/v_tone5.pngbin0 -> 1009 bytes
-rw-r--r--app/assets/images/emoji/vertical_traffic_light.pngbin0 -> 752 bytes
-rw-r--r--app/assets/images/emoji/vhs.pngbin0 -> 632 bytes
-rw-r--r--app/assets/images/emoji/vibration_mode.pngbin0 -> 683 bytes
-rw-r--r--app/assets/images/emoji/video_camera.pngbin0 -> 1611 bytes
-rw-r--r--app/assets/images/emoji/video_game.pngbin0 -> 765 bytes
-rw-r--r--app/assets/images/emoji/violin.pngbin0 -> 1156 bytes
-rw-r--r--app/assets/images/emoji/virgo.pngbin0 -> 618 bytes
-rw-r--r--app/assets/images/emoji/volcano.pngbin0 -> 1257 bytes
-rw-r--r--app/assets/images/emoji/volleyball.pngbin0 -> 1202 bytes
-rw-r--r--app/assets/images/emoji/vs.pngbin0 -> 604 bytes
-rw-r--r--app/assets/images/emoji/vulcan.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/vulcan_tone1.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/vulcan_tone2.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/vulcan_tone3.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/vulcan_tone4.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/vulcan_tone5.pngbin0 -> 1083 bytes
-rw-r--r--app/assets/images/emoji/walking.pngbin0 -> 1082 bytes
-rw-r--r--app/assets/images/emoji/walking_tone1.pngbin0 -> 1084 bytes
-rw-r--r--app/assets/images/emoji/walking_tone2.pngbin0 -> 1084 bytes
-rw-r--r--app/assets/images/emoji/walking_tone3.pngbin0 -> 1066 bytes
-rw-r--r--app/assets/images/emoji/walking_tone4.pngbin0 -> 1075 bytes
-rw-r--r--app/assets/images/emoji/walking_tone5.pngbin0 -> 1065 bytes
-rw-r--r--app/assets/images/emoji/waning_crescent_moon.pngbin0 -> 1213 bytes
-rw-r--r--app/assets/images/emoji/waning_gibbous_moon.pngbin0 -> 1208 bytes
-rw-r--r--app/assets/images/emoji/warning.pngbin0 -> 565 bytes
-rw-r--r--app/assets/images/emoji/wastebasket.pngbin0 -> 2414 bytes
-rw-r--r--app/assets/images/emoji/watch.pngbin0 -> 785 bytes
-rw-r--r--app/assets/images/emoji/water_buffalo.pngbin0 -> 1536 bytes
-rw-r--r--app/assets/images/emoji/water_polo.pngbin0 -> 1755 bytes
-rw-r--r--app/assets/images/emoji/water_polo_tone1.pngbin0 -> 1758 bytes
-rw-r--r--app/assets/images/emoji/water_polo_tone2.pngbin0 -> 1756 bytes
-rw-r--r--app/assets/images/emoji/water_polo_tone3.pngbin0 -> 1760 bytes
-rw-r--r--app/assets/images/emoji/water_polo_tone4.pngbin0 -> 1749 bytes
-rw-r--r--app/assets/images/emoji/water_polo_tone5.pngbin0 -> 1748 bytes
-rw-r--r--app/assets/images/emoji/watermelon.pngbin0 -> 1275 bytes
-rw-r--r--app/assets/images/emoji/wave.pngbin0 -> 1300 bytes
-rw-r--r--app/assets/images/emoji/wave_tone1.pngbin0 -> 1300 bytes
-rw-r--r--app/assets/images/emoji/wave_tone2.pngbin0 -> 1300 bytes
-rw-r--r--app/assets/images/emoji/wave_tone3.pngbin0 -> 1295 bytes
-rw-r--r--app/assets/images/emoji/wave_tone4.pngbin0 -> 1300 bytes
-rw-r--r--app/assets/images/emoji/wave_tone5.pngbin0 -> 1300 bytes
-rw-r--r--app/assets/images/emoji/wavy_dash.pngbin0 -> 359 bytes
-rw-r--r--app/assets/images/emoji/waxing_crescent_moon.pngbin0 -> 1199 bytes
-rw-r--r--app/assets/images/emoji/waxing_gibbous_moon.pngbin0 -> 1229 bytes
-rw-r--r--app/assets/images/emoji/wc.pngbin0 -> 752 bytes
-rw-r--r--app/assets/images/emoji/weary.pngbin0 -> 871 bytes
-rw-r--r--app/assets/images/emoji/wedding.pngbin0 -> 1260 bytes
-rw-r--r--app/assets/images/emoji/whale.pngbin0 -> 1572 bytes
-rw-r--r--app/assets/images/emoji/whale2.pngbin0 -> 1196 bytes
-rw-r--r--app/assets/images/emoji/wheel_of_dharma.pngbin0 -> 666 bytes
-rw-r--r--app/assets/images/emoji/wheelchair.pngbin0 -> 683 bytes
-rw-r--r--app/assets/images/emoji/white_check_mark.pngbin0 -> 547 bytes
-rw-r--r--app/assets/images/emoji/white_circle.pngbin0 -> 351 bytes
-rw-r--r--app/assets/images/emoji/white_flower.pngbin0 -> 941 bytes
-rw-r--r--app/assets/images/emoji/white_large_square.pngbin0 -> 110 bytes
-rw-r--r--app/assets/images/emoji/white_medium_small_square.pngbin0 -> 110 bytes
-rw-r--r--app/assets/images/emoji/white_medium_square.pngbin0 -> 108 bytes
-rw-r--r--app/assets/images/emoji/white_small_square.pngbin0 -> 108 bytes
-rw-r--r--app/assets/images/emoji/white_square_button.pngbin0 -> 122 bytes
-rw-r--r--app/assets/images/emoji/white_sun_cloud.pngbin0 -> 968 bytes
-rw-r--r--app/assets/images/emoji/white_sun_rain_cloud.pngbin0 -> 1161 bytes
-rw-r--r--app/assets/images/emoji/white_sun_small_cloud.pngbin0 -> 989 bytes
-rw-r--r--app/assets/images/emoji/wilted_rose.pngbin0 -> 1349 bytes
-rw-r--r--app/assets/images/emoji/wind_blowing_face.pngbin0 -> 1827 bytes
-rw-r--r--app/assets/images/emoji/wind_chime.pngbin0 -> 1046 bytes
-rw-r--r--app/assets/images/emoji/wine_glass.pngbin0 -> 655 bytes
-rw-r--r--app/assets/images/emoji/wink.pngbin0 -> 746 bytes
-rw-r--r--app/assets/images/emoji/wolf.pngbin0 -> 1528 bytes
-rw-r--r--app/assets/images/emoji/woman.pngbin0 -> 1212 bytes
-rw-r--r--app/assets/images/emoji/woman_tone1.pngbin0 -> 1212 bytes
-rw-r--r--app/assets/images/emoji/woman_tone2.pngbin0 -> 1212 bytes
-rw-r--r--app/assets/images/emoji/woman_tone3.pngbin0 -> 1202 bytes
-rw-r--r--app/assets/images/emoji/woman_tone4.pngbin0 -> 1195 bytes
-rw-r--r--app/assets/images/emoji/woman_tone5.pngbin0 -> 1202 bytes
-rw-r--r--app/assets/images/emoji/womans_clothes.pngbin0 -> 1042 bytes
-rw-r--r--app/assets/images/emoji/womans_hat.pngbin0 -> 1553 bytes
-rw-r--r--app/assets/images/emoji/womens.pngbin0 -> 577 bytes
-rw-r--r--app/assets/images/emoji/worried.pngbin0 -> 715 bytes
-rw-r--r--app/assets/images/emoji/wrench.pngbin0 -> 418 bytes
-rw-r--r--app/assets/images/emoji/wrestlers.pngbin0 -> 2556 bytes
-rw-r--r--app/assets/images/emoji/wrestlers_tone1.pngbin0 -> 2563 bytes
-rw-r--r--app/assets/images/emoji/wrestlers_tone2.pngbin0 -> 2553 bytes
-rw-r--r--app/assets/images/emoji/wrestlers_tone3.pngbin0 -> 2541 bytes
-rw-r--r--app/assets/images/emoji/wrestlers_tone4.pngbin0 -> 2553 bytes
-rw-r--r--app/assets/images/emoji/wrestlers_tone5.pngbin0 -> 2542 bytes
-rw-r--r--app/assets/images/emoji/writing_hand.pngbin0 -> 1001 bytes
-rw-r--r--app/assets/images/emoji/writing_hand_tone1.pngbin0 -> 988 bytes
-rw-r--r--app/assets/images/emoji/writing_hand_tone2.pngbin0 -> 987 bytes
-rw-r--r--app/assets/images/emoji/writing_hand_tone3.pngbin0 -> 977 bytes
-rw-r--r--app/assets/images/emoji/writing_hand_tone4.pngbin0 -> 973 bytes
-rw-r--r--app/assets/images/emoji/writing_hand_tone5.pngbin0 -> 970 bytes
-rw-r--r--app/assets/images/emoji/x.pngbin0 -> 298 bytes
-rw-r--r--app/assets/images/emoji/yellow_heart.pngbin0 -> 435 bytes
-rw-r--r--app/assets/images/emoji/yen.pngbin0 -> 421 bytes
-rw-r--r--app/assets/images/emoji/yin_yang.pngbin0 -> 776 bytes
-rw-r--r--app/assets/images/emoji/yum.pngbin0 -> 896 bytes
-rw-r--r--app/assets/images/emoji/zap.pngbin0 -> 413 bytes
-rw-r--r--app/assets/images/emoji/zero.pngbin0 -> 560 bytes
-rw-r--r--app/assets/images/emoji/zipper_mouth.pngbin0 -> 722 bytes
-rw-r--r--app/assets/images/emoji/zzz.pngbin0 -> 540 bytes
-rw-r--r--app/assets/images/emoji@2x.pngbin2652225 -> 2976505 bytes
-rw-r--r--app/assets/javascripts/abuse_reports.js (renamed from app/assets/javascripts/abuse_reports.js.es6)0
-rw-r--r--app/assets/javascripts/activities.js (renamed from app/assets/javascripts/activities.js.es6)0
-rw-r--r--app/assets/javascripts/application.js401
-rw-r--r--app/assets/javascripts/awards_handler.js876
-rw-r--r--app/assets/javascripts/behaviors/bind_in_out.js47
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji.js217
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji/spread_string.js50
-rw-r--r--app/assets/javascripts/behaviors/gl_emoji/unicode_support_map.js154
-rw-r--r--app/assets/javascripts/behaviors/toggler_behavior.js3
-rw-r--r--app/assets/javascripts/blob/blob_ci_yaml.js (renamed from app/assets/javascripts/blob/blob_ci_yaml.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_dockerfile_selector.js (renamed from app/assets/javascripts/blob/blob_dockerfile_selector.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_dockerfile_selectors.js (renamed from app/assets/javascripts/blob/blob_dockerfile_selectors.js.es6)0
-rw-r--r--app/assets/javascripts/blob/blob_license_selectors.js (renamed from app/assets/javascripts/blob/blob_license_selectors.js.es6)0
-rw-r--r--app/assets/javascripts/blob/template_selector.js (renamed from app/assets/javascripts/blob/template_selector.js.es6)0
-rw-r--r--app/assets/javascripts/boards/boards_bundle.js (renamed from app/assets/javascripts/boards/boards_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board.js (renamed from app/assets/javascripts/boards/components/board.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.js (renamed from app/assets/javascripts/boards/components/board_blank_state.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_delete.js (renamed from app/assets/javascripts/boards/components/board_delete.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_list.js (renamed from app/assets/javascripts/boards/components/board_list.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js (renamed from app/assets/javascripts/boards/components/board_sidebar.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.js (renamed from app/assets/javascripts/boards/components/issue_card_inner.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/empty_state.js (renamed from app/assets/javascripts/boards/components/modal/empty_state.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters.js (renamed from app/assets/javascripts/boards/components/modal/filters.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/label.js (renamed from app/assets/javascripts/boards/components/modal/filters/label.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/milestone.js (renamed from app/assets/javascripts/boards/components/modal/filters/milestone.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/filters/user.js (renamed from app/assets/javascripts/boards/components/modal/filters/user.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/footer.js (renamed from app/assets/javascripts/boards/components/modal/footer.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/header.js (renamed from app/assets/javascripts/boards/components/modal/header.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/index.js (renamed from app/assets/javascripts/boards/components/modal/index.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/list.js (renamed from app/assets/javascripts/boards/components/modal/list.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/lists_dropdown.js (renamed from app/assets/javascripts/boards/components/modal/lists_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/modal/tabs.js (renamed from app/assets/javascripts/boards/components/modal/tabs.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/new_list_dropdown.js (renamed from app/assets/javascripts/boards/components/new_list_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/boards/components/sidebar/remove_issue.js (renamed from app/assets/javascripts/boards/components/sidebar/remove_issue.js.es6)0
-rw-r--r--app/assets/javascripts/boards/filters/due_date_filters.js (renamed from app/assets/javascripts/boards/filters/due_date_filters.js.es6)0
-rw-r--r--app/assets/javascripts/boards/mixins/modal_mixins.js (renamed from app/assets/javascripts/boards/mixins/modal_mixins.js.es6)0
-rw-r--r--app/assets/javascripts/boards/mixins/sortable_default_options.js (renamed from app/assets/javascripts/boards/mixins/sortable_default_options.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/issue.js (renamed from app/assets/javascripts/boards/models/issue.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/label.js (renamed from app/assets/javascripts/boards/models/label.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/list.js (renamed from app/assets/javascripts/boards/models/list.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/milestone.js (renamed from app/assets/javascripts/boards/models/milestone.js.es6)0
-rw-r--r--app/assets/javascripts/boards/models/user.js (renamed from app/assets/javascripts/boards/models/user.js.es6)0
-rw-r--r--app/assets/javascripts/boards/services/board_service.js (renamed from app/assets/javascripts/boards/services/board_service.js.es6)0
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js (renamed from app/assets/javascripts/boards/stores/boards_store.js.es6)0
-rw-r--r--app/assets/javascripts/boards/stores/modal_store.js (renamed from app/assets/javascripts/boards/stores/modal_store.js.es6)0
-rw-r--r--app/assets/javascripts/build_variables.js (renamed from app/assets/javascripts/build_variables.js.es6)0
-rw-r--r--app/assets/javascripts/ci_lint_editor.js (renamed from app/assets/javascripts/ci_lint_editor.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_bundle.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_service.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_service.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_store.js (renamed from app/assets/javascripts/commit/pipelines/pipelines_store.js.es6)0
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.js104
-rw-r--r--app/assets/javascripts/commit/pipelines/pipelines_table.js.es6112
-rw-r--r--app/assets/javascripts/commons/bootstrap.js10
-rw-r--r--app/assets/javascripts/commons/index.js2
-rw-r--r--app/assets/javascripts/commons/jquery.js11
-rw-r--r--app/assets/javascripts/compare_autocomplete.js (renamed from app/assets/javascripts/compare_autocomplete.js.es6)0
-rw-r--r--app/assets/javascripts/copy_as_gfm.js364
-rw-r--r--app/assets/javascripts/copy_as_gfm.js.es6361
-rw-r--r--app/assets/javascripts/create_label.js (renamed from app/assets/javascripts/create_label.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_code_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_code_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_issue_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_issue_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_plan_component.js56
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_plan_component.js.es650
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_production_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_production_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_review_component.js (renamed from app/assets/javascripts/cycle_analytics/components/stage_review_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_staging_component.js48
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_staging_component.js.es644
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_test_component.js49
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_test_component.js.es644
-rw-r--r--app/assets/javascripts/cycle_analytics/components/total_time_component.js (renamed from app/assets/javascripts/cycle_analytics/components/total_time_component.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js135
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6138
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_service.js (renamed from app/assets/javascripts/cycle_analytics/cycle_analytics_service.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/cycle_analytics_store.js (renamed from app/assets/javascripts/cycle_analytics/cycle_analytics_store.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/default_event_objects.js (renamed from app/assets/javascripts/cycle_analytics/default_event_objects.js.es6)0
-rw-r--r--app/assets/javascripts/cycle_analytics/svg/icon_branch.js.es67
-rw-r--r--app/assets/javascripts/cycle_analytics/svg/icon_branch.svg1
-rw-r--r--app/assets/javascripts/cycle_analytics/svg/icon_build_status.js.es67
-rw-r--r--app/assets/javascripts/cycle_analytics/svg/icon_build_status.svg1
-rw-r--r--app/assets/javascripts/cycle_analytics/svg/icon_commit.js.es67
-rw-r--r--app/assets/javascripts/cycle_analytics/svg/icon_commit.svg1
-rw-r--r--app/assets/javascripts/diff.js130
-rw-r--r--app/assets/javascripts/diff.js.es6126
-rw-r--r--app/assets/javascripts/diff_notes/components/comment_resolve_btn.js (renamed from app/assets/javascripts/diff_notes/components/comment_resolve_btn.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/jump_to_discussion.js (renamed from app/assets/javascripts/diff_notes/components/jump_to_discussion.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_btn.js (renamed from app/assets/javascripts/diff_notes/components/resolve_btn.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_count.js (renamed from app/assets/javascripts/diff_notes/components/resolve_count.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js (renamed from app/assets/javascripts/diff_notes/components/resolve_discussion_btn.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/diff_notes_bundle.js (renamed from app/assets/javascripts/diff_notes/diff_notes_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/mixins/discussion.js (renamed from app/assets/javascripts/diff_notes/mixins/discussion.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/models/discussion.js (renamed from app/assets/javascripts/diff_notes/models/discussion.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/models/note.js (renamed from app/assets/javascripts/diff_notes/models/note.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/services/resolve.js (renamed from app/assets/javascripts/diff_notes/services/resolve.js.es6)0
-rw-r--r--app/assets/javascripts/diff_notes/stores/comments.js (renamed from app/assets/javascripts/diff_notes/stores/comments.js.es6)0
-rw-r--r--app/assets/javascripts/dispatcher.js413
-rw-r--r--app/assets/javascripts/dispatcher.js.es6400
-rw-r--r--app/assets/javascripts/due_date_select.js (renamed from app/assets/javascripts/due_date_select.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment.js186
-rw-r--r--app/assets/javascripts/environments/components/environment.js.es6193
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.js41
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.js.es643
-rw-r--r--app/assets/javascripts/environments/components/environment_external_url.js (renamed from app/assets/javascripts/environments/components/environment_external_url.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_item.js510
-rw-r--r--app/assets/javascripts/environments/components/environment_item.js.es6534
-rw-r--r--app/assets/javascripts/environments/components/environment_rollback.js (renamed from app/assets/javascripts/environments/components/environment_rollback.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_stop.js (renamed from app/assets/javascripts/environments/components/environment_stop.js.es6)0
-rw-r--r--app/assets/javascripts/environments/components/environment_terminal_button.js26
-rw-r--r--app/assets/javascripts/environments/components/environment_terminal_button.js.es625
-rw-r--r--app/assets/javascripts/environments/components/environments_table.js56
-rw-r--r--app/assets/javascripts/environments/components/environments_table.js.es674
-rw-r--r--app/assets/javascripts/environments/environments_bundle.js (renamed from app/assets/javascripts/environments/environments_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_bundle.js (renamed from app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_view.js182
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_view.js.es6182
-rw-r--r--app/assets/javascripts/environments/services/environments_service.js13
-rw-r--r--app/assets/javascripts/environments/services/environments_service.js.es613
-rw-r--r--app/assets/javascripts/environments/stores/environments_store.js (renamed from app/assets/javascripts/environments/stores/environments_store.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/array.js (renamed from app/assets/javascripts/extensions/array.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/custom_event.js (renamed from app/assets/javascripts/extensions/custom_event.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/element.js (renamed from app/assets/javascripts/extensions/element.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/object.js (renamed from app/assets/javascripts/extensions/object.js.es6)0
-rw-r--r--app/assets/javascripts/extensions/string.js2
-rw-r--r--app/assets/javascripts/filterable_list.js45
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_hint.js (renamed from app/assets/javascripts/filtered_search/dropdown_hint.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_non_user.js (renamed from app/assets/javascripts/filtered_search/dropdown_non_user.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_user.js (renamed from app/assets/javascripts/filtered_search/dropdown_user.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/dropdown_utils.js (renamed from app/assets/javascripts/filtered_search/dropdown_utils.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown.js (renamed from app/assets/javascripts/filtered_search/filtered_search_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js (renamed from app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_manager.js (renamed from app/assets/javascripts/filtered_search/filtered_search_manager.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_token_keys.js (renamed from app/assets/javascripts/filtered_search/filtered_search_token_keys.js.es6)0
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_tokenizer.js (renamed from app/assets/javascripts/filtered_search/filtered_search_tokenizer.js.es6)0
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js396
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js.es6383
-rw-r--r--app/assets/javascripts/gl_field_error.js (renamed from app/assets/javascripts/gl_field_error.js.es6)0
-rw-r--r--app/assets/javascripts/gl_field_errors.js (renamed from app/assets/javascripts/gl_field_errors.js.es6)0
-rw-r--r--app/assets/javascripts/gl_form.js (renamed from app/assets/javascripts/gl_form.js.es6)0
-rw-r--r--app/assets/javascripts/graphs/graphs_bundle.js2
-rw-r--r--app/assets/javascripts/group_label_subscription.js (renamed from app/assets/javascripts/group_label_subscription.js.es6)0
-rw-r--r--app/assets/javascripts/groups_list.js45
-rw-r--r--app/assets/javascripts/issuable.js (renamed from app/assets/javascripts/issuable.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/issuable_bundle.js (renamed from app/assets/javascripts/issuable/issuable_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js42
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/collapsed_state.js.es641
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/comparison_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/estimate_only_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/help_state.js (renamed from app/assets/javascripts/issuable/time_tracking/components/help_state.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/no_tracking_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js (renamed from app/assets/javascripts/issuable/time_tracking/components/spent_only_pane.js.es6)0
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/time_tracker.js117
-rw-r--r--app/assets/javascripts/issuable/time_tracking/components/time_tracker.js.es6119
-rw-r--r--app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js65
-rw-r--r--app/assets/javascripts/issuable/time_tracking/time_tracking_bundle.js.es663
-rw-r--r--app/assets/javascripts/issues_bulk_assignment.js (renamed from app/assets/javascripts/issues_bulk_assignment.js.es6)0
-rw-r--r--app/assets/javascripts/label_manager.js (renamed from app/assets/javascripts/label_manager.js.es6)0
-rw-r--r--app/assets/javascripts/lib/chart.js3
-rw-r--r--app/assets/javascripts/lib/cropper.js7
-rw-r--r--app/assets/javascripts/lib/d3.js3
-rw-r--r--app/assets/javascripts/lib/raphael.js9
-rw-r--r--app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js (renamed from app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js342
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js.es6353
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js (renamed from app/assets/javascripts/lib/utils/datetime_utility.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/pretty_time.js (renamed from app/assets/javascripts/lib/utils/pretty_time.js.es6)0
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js18
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js (renamed from app/assets/javascripts/lib/utils/url_utility.js.es6)0
-rw-r--r--app/assets/javascripts/lib/vue_resource.js.es62
-rw-r--r--app/assets/javascripts/main.js394
-rw-r--r--app/assets/javascripts/member_expiration_date.js (renamed from app/assets/javascripts/member_expiration_date.js.es6)0
-rw-r--r--app/assets/javascripts/members.js (renamed from app/assets/javascripts/members.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/components/diff_file_editor.js (renamed from app/assets/javascripts/merge_conflicts/components/diff_file_editor.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js (renamed from app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js (renamed from app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_service.js (renamed from app/assets/javascripts/merge_conflicts/merge_conflict_service.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_store.js (renamed from app/assets/javascripts/merge_conflicts/merge_conflict_store.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js (renamed from app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js (renamed from app/assets/javascripts/merge_conflicts/mixins/line_conflict_actions.js.es6)0
-rw-r--r--app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js (renamed from app/assets/javascripts/merge_conflicts/mixins/line_conflict_utils.js.es6)0
-rw-r--r--app/assets/javascripts/merge_request_tabs.js (renamed from app/assets/javascripts/merge_request_tabs.js.es6)0
-rw-r--r--app/assets/javascripts/merge_request_widget.js295
-rw-r--r--app/assets/javascripts/merge_request_widget.js.es6285
-rw-r--r--app/assets/javascripts/merge_request_widget/ci_bundle.js53
-rw-r--r--app/assets/javascripts/merge_request_widget/ci_bundle.js.es653
-rw-r--r--app/assets/javascripts/mini_pipeline_graph_dropdown.js (renamed from app/assets/javascripts/mini_pipeline_graph_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/network/branch_graph.js703
-rw-r--r--app/assets/javascripts/network/network.js33
-rw-r--r--app/assets/javascripts/network/network_bundle.js26
-rw-r--r--app/assets/javascripts/network/raphael.js74
-rw-r--r--app/assets/javascripts/notes.js2
-rw-r--r--app/assets/javascripts/pager.js (renamed from app/assets/javascripts/pager.js.es6)0
-rw-r--r--app/assets/javascripts/pipelines.js (renamed from app/assets/javascripts/pipelines.js.es6)0
-rw-r--r--app/assets/javascripts/profile/gl_crop.js173
-rw-r--r--app/assets/javascripts/profile/gl_crop.js.es6171
-rw-r--r--app/assets/javascripts/profile/profile.js (renamed from app/assets/javascripts/profile/profile.js.es6)0
-rw-r--r--app/assets/javascripts/project_label_subscription.js (renamed from app/assets/javascripts/project_label_subscription.js.es6)0
-rw-r--r--app/assets/javascripts/project_variables.js (renamed from app/assets/javascripts/project_variables.js.es6)0
-rw-r--r--app/assets/javascripts/projects_list.js64
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js (renamed from app/assets/javascripts/protected_branches/protected_branch_access_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_create.js (renamed from app/assets/javascripts/protected_branches/protected_branch_create.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_dropdown.js (renamed from app/assets/javascripts/protected_branches/protected_branch_dropdown.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_edit.js (renamed from app/assets/javascripts/protected_branches/protected_branch_edit.js.es6)0
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_edit_list.js (renamed from app/assets/javascripts/protected_branches/protected_branch_edit_list.js.es6)0
-rw-r--r--app/assets/javascripts/search_autocomplete.js (renamed from app/assets/javascripts/search_autocomplete.js.es6)0
-rw-r--r--app/assets/javascripts/shortcuts_blob.js (renamed from app/assets/javascripts/shortcuts_blob.js.es6)0
-rw-r--r--app/assets/javascripts/shortcuts_navigation.js2
-rw-r--r--app/assets/javascripts/signin_tabs_memoizer.js (renamed from app/assets/javascripts/signin_tabs_memoizer.js.es6)0
-rw-r--r--app/assets/javascripts/smart_interval.js (renamed from app/assets/javascripts/smart_interval.js.es6)0
-rw-r--r--app/assets/javascripts/snippets_list.js (renamed from app/assets/javascripts/snippets_list.js.es6)0
-rw-r--r--app/assets/javascripts/subbable_resource.js (renamed from app/assets/javascripts/subbable_resource.js.es6)0
-rw-r--r--app/assets/javascripts/subscription.js (renamed from app/assets/javascripts/subscription.js.es6)0
-rw-r--r--app/assets/javascripts/templates/issuable_template_selector.js (renamed from app/assets/javascripts/templates/issuable_template_selector.js.es6)0
-rw-r--r--app/assets/javascripts/templates/issuable_template_selectors.js (renamed from app/assets/javascripts/templates/issuable_template_selectors.js.es6)0
-rw-r--r--app/assets/javascripts/terminal/terminal.js (renamed from app/assets/javascripts/terminal/terminal.js.es6)0
-rw-r--r--app/assets/javascripts/terminal/terminal_bundle.js (renamed from app/assets/javascripts/terminal/terminal_bundle.js.es6)0
-rw-r--r--app/assets/javascripts/todos.js (renamed from app/assets/javascripts/todos.js.es6)0
-rw-r--r--app/assets/javascripts/u2f/authenticate.js (renamed from app/assets/javascripts/u2f/authenticate.js.es6)0
-rw-r--r--app/assets/javascripts/user.js (renamed from app/assets/javascripts/user.js.es6)0
-rw-r--r--app/assets/javascripts/user_callout.js4
-rw-r--r--app/assets/javascripts/user_tabs.js (renamed from app/assets/javascripts/user_tabs.js.es6)0
-rw-r--r--app/assets/javascripts/username_validator.js (renamed from app/assets/javascripts/username_validator.js.es6)0
-rw-r--r--app/assets/javascripts/users/calendar.js3
-rw-r--r--app/assets/javascripts/users_select.js23
-rw-r--r--app/assets/javascripts/version_check_image.js (renamed from app/assets/javascripts/version_check_image.js.es6)0
-rw-r--r--app/assets/javascripts/visibility_select.js (renamed from app/assets/javascripts/visibility_select.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/index.js29
-rw-r--r--app/assets/javascripts/vue_pipelines_index/index.js.es636
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipeline_actions.js119
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipeline_actions.js.es6113
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipeline_url.js (renamed from app/assets/javascripts/vue_pipelines_index/pipeline_url.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipelines.js87
-rw-r--r--app/assets/javascripts/vue_pipelines_index/pipelines.js.es690
-rw-r--r--app/assets/javascripts/vue_pipelines_index/stage.js119
-rw-r--r--app/assets/javascripts/vue_pipelines_index/stage.js.es6111
-rw-r--r--app/assets/javascripts/vue_pipelines_index/status.js64
-rw-r--r--app/assets/javascripts/vue_pipelines_index/status.js.es634
-rw-r--r--app/assets/javascripts/vue_pipelines_index/store.js (renamed from app/assets/javascripts/vue_pipelines_index/store.js.es6)0
-rw-r--r--app/assets/javascripts/vue_pipelines_index/time_ago.js78
-rw-r--r--app/assets/javascripts/vue_pipelines_index/time_ago.js.es675
-rw-r--r--app/assets/javascripts/vue_realtime_listener/index.js (renamed from app/assets/javascripts/vue_realtime_listener/index.js.es6)0
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.js164
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.js.es6164
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table.js52
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table.js.es661
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table_row.js199
-rw-r--r--app/assets/javascripts/vue_shared/components/pipelines_table_row.js.es6234
-rw-r--r--app/assets/javascripts/vue_shared/components/table_pagination.js147
-rw-r--r--app/assets/javascripts/vue_shared/components/table_pagination.js.es6148
-rw-r--r--app/assets/javascripts/vue_shared/vue_resource_interceptor.js (renamed from app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6)0
-rw-r--r--app/assets/javascripts/wikis.js (renamed from app/assets/javascripts/wikis.js.es6)0
-rw-r--r--app/assets/stylesheets/framework.scss1
-rw-r--r--app/assets/stylesheets/framework/awards.scss10
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss17
-rw-r--r--app/assets/stylesheets/framework/emoji-sprites.scss1811
-rw-r--r--app/assets/stylesheets/framework/emojis.scss1813
-rw-r--r--app/assets/stylesheets/framework/filters.scss15
-rw-r--r--app/assets/stylesheets/framework/header.scss34
-rw-r--r--app/assets/stylesheets/framework/layout.scss13
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss7
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss4
-rw-r--r--app/assets/stylesheets/framework/tw_bootstrap.scss10
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/framework/zen.scss3
-rw-r--r--app/assets/stylesheets/pages/events.scss5
-rw-r--r--app/assets/stylesheets/pages/groups.scss16
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss80
-rw-r--r--app/assets/stylesheets/pages/profile.scss3
-rw-r--r--app/assets/stylesheets/pages/projects.scss27
-rw-r--r--app/assets/stylesheets/pages/search.scss6
-rw-r--r--app/assets/stylesheets/pages/todos.scss10
-rw-r--r--app/assets/stylesheets/pages/tree.scss26
2064 files changed, 8820 insertions, 8079 deletions
diff --git a/app/assets/images/emoji.png b/app/assets/images/emoji.png
index 6f1a34a5591..5dcd9c09b70 100644
--- a/app/assets/images/emoji.png
+++ b/app/assets/images/emoji.png
Binary files differ
diff --git a/app/assets/images/emoji/100.png b/app/assets/images/emoji/100.png
new file mode 100644
index 00000000000..6903ff0304a
--- /dev/null
+++ b/app/assets/images/emoji/100.png
Binary files differ
diff --git a/app/assets/images/emoji/1234.png b/app/assets/images/emoji/1234.png
new file mode 100644
index 00000000000..248dc7e55b6
--- /dev/null
+++ b/app/assets/images/emoji/1234.png
Binary files differ
diff --git a/app/assets/images/emoji/1F627.png b/app/assets/images/emoji/1F627.png
new file mode 100644
index 00000000000..f99026a3bc7
--- /dev/null
+++ b/app/assets/images/emoji/1F627.png
Binary files differ
diff --git a/app/assets/images/emoji/8ball.png b/app/assets/images/emoji/8ball.png
new file mode 100644
index 00000000000..38ca662eded
--- /dev/null
+++ b/app/assets/images/emoji/8ball.png
Binary files differ
diff --git a/app/assets/images/emoji/a.png b/app/assets/images/emoji/a.png
new file mode 100644
index 00000000000..8603ff05a17
--- /dev/null
+++ b/app/assets/images/emoji/a.png
Binary files differ
diff --git a/app/assets/images/emoji/ab.png b/app/assets/images/emoji/ab.png
new file mode 100644
index 00000000000..d9f2d17dea0
--- /dev/null
+++ b/app/assets/images/emoji/ab.png
Binary files differ
diff --git a/app/assets/images/emoji/abc.png b/app/assets/images/emoji/abc.png
new file mode 100644
index 00000000000..7688de692a9
--- /dev/null
+++ b/app/assets/images/emoji/abc.png
Binary files differ
diff --git a/app/assets/images/emoji/abcd.png b/app/assets/images/emoji/abcd.png
new file mode 100644
index 00000000000..0996a870570
--- /dev/null
+++ b/app/assets/images/emoji/abcd.png
Binary files differ
diff --git a/app/assets/images/emoji/accept.png b/app/assets/images/emoji/accept.png
new file mode 100644
index 00000000000..8afd7ce99cf
--- /dev/null
+++ b/app/assets/images/emoji/accept.png
Binary files differ
diff --git a/app/assets/images/emoji/aerial_tramway.png b/app/assets/images/emoji/aerial_tramway.png
new file mode 100644
index 00000000000..3eb4b61bf1d
--- /dev/null
+++ b/app/assets/images/emoji/aerial_tramway.png
Binary files differ
diff --git a/app/assets/images/emoji/airplane.png b/app/assets/images/emoji/airplane.png
new file mode 100644
index 00000000000..268d2ac3c8e
--- /dev/null
+++ b/app/assets/images/emoji/airplane.png
Binary files differ
diff --git a/app/assets/images/emoji/airplane_arriving.png b/app/assets/images/emoji/airplane_arriving.png
new file mode 100644
index 00000000000..d66841962f2
--- /dev/null
+++ b/app/assets/images/emoji/airplane_arriving.png
Binary files differ
diff --git a/app/assets/images/emoji/airplane_departure.png b/app/assets/images/emoji/airplane_departure.png
new file mode 100644
index 00000000000..a5766f9f4ae
--- /dev/null
+++ b/app/assets/images/emoji/airplane_departure.png
Binary files differ
diff --git a/app/assets/images/emoji/airplane_small.png b/app/assets/images/emoji/airplane_small.png
new file mode 100644
index 00000000000..b731b15e3a8
--- /dev/null
+++ b/app/assets/images/emoji/airplane_small.png
Binary files differ
diff --git a/app/assets/images/emoji/alarm_clock.png b/app/assets/images/emoji/alarm_clock.png
new file mode 100644
index 00000000000..cdbc2fbb950
--- /dev/null
+++ b/app/assets/images/emoji/alarm_clock.png
Binary files differ
diff --git a/app/assets/images/emoji/alembic.png b/app/assets/images/emoji/alembic.png
new file mode 100644
index 00000000000..307a7324249
--- /dev/null
+++ b/app/assets/images/emoji/alembic.png
Binary files differ
diff --git a/app/assets/images/emoji/alien.png b/app/assets/images/emoji/alien.png
new file mode 100644
index 00000000000..3b90e97433b
--- /dev/null
+++ b/app/assets/images/emoji/alien.png
Binary files differ
diff --git a/app/assets/images/emoji/ambulance.png b/app/assets/images/emoji/ambulance.png
new file mode 100644
index 00000000000..6fb8076d766
--- /dev/null
+++ b/app/assets/images/emoji/ambulance.png
Binary files differ
diff --git a/app/assets/images/emoji/amphora.png b/app/assets/images/emoji/amphora.png
new file mode 100644
index 00000000000..96de5056059
--- /dev/null
+++ b/app/assets/images/emoji/amphora.png
Binary files differ
diff --git a/app/assets/images/emoji/anchor.png b/app/assets/images/emoji/anchor.png
new file mode 100644
index 00000000000..b036f70a00b
--- /dev/null
+++ b/app/assets/images/emoji/anchor.png
Binary files differ
diff --git a/app/assets/images/emoji/angel.png b/app/assets/images/emoji/angel.png
new file mode 100644
index 00000000000..66ea97a3b99
--- /dev/null
+++ b/app/assets/images/emoji/angel.png
Binary files differ
diff --git a/app/assets/images/emoji/angel_tone1.png b/app/assets/images/emoji/angel_tone1.png
new file mode 100644
index 00000000000..391694dc07e
--- /dev/null
+++ b/app/assets/images/emoji/angel_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/angel_tone2.png b/app/assets/images/emoji/angel_tone2.png
new file mode 100644
index 00000000000..700cbe6ed2c
--- /dev/null
+++ b/app/assets/images/emoji/angel_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/angel_tone3.png b/app/assets/images/emoji/angel_tone3.png
new file mode 100644
index 00000000000..be597437d25
--- /dev/null
+++ b/app/assets/images/emoji/angel_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/angel_tone4.png b/app/assets/images/emoji/angel_tone4.png
new file mode 100644
index 00000000000..b06d3c853ef
--- /dev/null
+++ b/app/assets/images/emoji/angel_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/angel_tone5.png b/app/assets/images/emoji/angel_tone5.png
new file mode 100644
index 00000000000..17bd677e334
--- /dev/null
+++ b/app/assets/images/emoji/angel_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/anger.png b/app/assets/images/emoji/anger.png
new file mode 100644
index 00000000000..d63c2e000e4
--- /dev/null
+++ b/app/assets/images/emoji/anger.png
Binary files differ
diff --git a/app/assets/images/emoji/anger_right.png b/app/assets/images/emoji/anger_right.png
new file mode 100644
index 00000000000..f5c97c4d297
--- /dev/null
+++ b/app/assets/images/emoji/anger_right.png
Binary files differ
diff --git a/app/assets/images/emoji/angry.png b/app/assets/images/emoji/angry.png
new file mode 100644
index 00000000000..cfc4a6ecde5
--- /dev/null
+++ b/app/assets/images/emoji/angry.png
Binary files differ
diff --git a/app/assets/images/emoji/ant.png b/app/assets/images/emoji/ant.png
new file mode 100644
index 00000000000..994127ed6b3
--- /dev/null
+++ b/app/assets/images/emoji/ant.png
Binary files differ
diff --git a/app/assets/images/emoji/apple.png b/app/assets/images/emoji/apple.png
new file mode 100644
index 00000000000..da650c60f62
--- /dev/null
+++ b/app/assets/images/emoji/apple.png
Binary files differ
diff --git a/app/assets/images/emoji/aquarius.png b/app/assets/images/emoji/aquarius.png
new file mode 100644
index 00000000000..641a4f68889
--- /dev/null
+++ b/app/assets/images/emoji/aquarius.png
Binary files differ
diff --git a/app/assets/images/emoji/aries.png b/app/assets/images/emoji/aries.png
new file mode 100644
index 00000000000..21a189d0ede
--- /dev/null
+++ b/app/assets/images/emoji/aries.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_backward.png b/app/assets/images/emoji/arrow_backward.png
new file mode 100644
index 00000000000..ee38e3b038e
--- /dev/null
+++ b/app/assets/images/emoji/arrow_backward.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_double_down.png b/app/assets/images/emoji/arrow_double_down.png
new file mode 100644
index 00000000000..90193bfcb40
--- /dev/null
+++ b/app/assets/images/emoji/arrow_double_down.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_double_up.png b/app/assets/images/emoji/arrow_double_up.png
new file mode 100644
index 00000000000..13543d5eef2
--- /dev/null
+++ b/app/assets/images/emoji/arrow_double_up.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_down.png b/app/assets/images/emoji/arrow_down.png
new file mode 100644
index 00000000000..b8eefd0b19f
--- /dev/null
+++ b/app/assets/images/emoji/arrow_down.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_down_small.png b/app/assets/images/emoji/arrow_down_small.png
new file mode 100644
index 00000000000..5870b9a2241
--- /dev/null
+++ b/app/assets/images/emoji/arrow_down_small.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_forward.png b/app/assets/images/emoji/arrow_forward.png
new file mode 100644
index 00000000000..4e2b682857c
--- /dev/null
+++ b/app/assets/images/emoji/arrow_forward.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_heading_down.png b/app/assets/images/emoji/arrow_heading_down.png
new file mode 100644
index 00000000000..2d9d24bca80
--- /dev/null
+++ b/app/assets/images/emoji/arrow_heading_down.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_heading_up.png b/app/assets/images/emoji/arrow_heading_up.png
new file mode 100644
index 00000000000..f29bfcfc0de
--- /dev/null
+++ b/app/assets/images/emoji/arrow_heading_up.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_left.png b/app/assets/images/emoji/arrow_left.png
new file mode 100644
index 00000000000..8c685e0a81b
--- /dev/null
+++ b/app/assets/images/emoji/arrow_left.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_lower_left.png b/app/assets/images/emoji/arrow_lower_left.png
new file mode 100644
index 00000000000..88b37716078
--- /dev/null
+++ b/app/assets/images/emoji/arrow_lower_left.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_lower_right.png b/app/assets/images/emoji/arrow_lower_right.png
new file mode 100644
index 00000000000..7e807da7392
--- /dev/null
+++ b/app/assets/images/emoji/arrow_lower_right.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_right.png b/app/assets/images/emoji/arrow_right.png
new file mode 100644
index 00000000000..4755670b5cc
--- /dev/null
+++ b/app/assets/images/emoji/arrow_right.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_right_hook.png b/app/assets/images/emoji/arrow_right_hook.png
new file mode 100644
index 00000000000..e7258ad3268
--- /dev/null
+++ b/app/assets/images/emoji/arrow_right_hook.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_up.png b/app/assets/images/emoji/arrow_up.png
new file mode 100644
index 00000000000..af8218a87f7
--- /dev/null
+++ b/app/assets/images/emoji/arrow_up.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_up_down.png b/app/assets/images/emoji/arrow_up_down.png
new file mode 100644
index 00000000000..dfa32b97186
--- /dev/null
+++ b/app/assets/images/emoji/arrow_up_down.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_up_small.png b/app/assets/images/emoji/arrow_up_small.png
new file mode 100644
index 00000000000..20a13dcd5cd
--- /dev/null
+++ b/app/assets/images/emoji/arrow_up_small.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_upper_left.png b/app/assets/images/emoji/arrow_upper_left.png
new file mode 100644
index 00000000000..f38718fbe34
--- /dev/null
+++ b/app/assets/images/emoji/arrow_upper_left.png
Binary files differ
diff --git a/app/assets/images/emoji/arrow_upper_right.png b/app/assets/images/emoji/arrow_upper_right.png
new file mode 100644
index 00000000000..c43e12d0f64
--- /dev/null
+++ b/app/assets/images/emoji/arrow_upper_right.png
Binary files differ
diff --git a/app/assets/images/emoji/arrows_clockwise.png b/app/assets/images/emoji/arrows_clockwise.png
new file mode 100644
index 00000000000..26e49c38388
--- /dev/null
+++ b/app/assets/images/emoji/arrows_clockwise.png
Binary files differ
diff --git a/app/assets/images/emoji/arrows_counterclockwise.png b/app/assets/images/emoji/arrows_counterclockwise.png
new file mode 100644
index 00000000000..8d06d8e0912
--- /dev/null
+++ b/app/assets/images/emoji/arrows_counterclockwise.png
Binary files differ
diff --git a/app/assets/images/emoji/art.png b/app/assets/images/emoji/art.png
new file mode 100644
index 00000000000..bd6afe9ff06
--- /dev/null
+++ b/app/assets/images/emoji/art.png
Binary files differ
diff --git a/app/assets/images/emoji/articulated_lorry.png b/app/assets/images/emoji/articulated_lorry.png
new file mode 100644
index 00000000000..c8217317132
--- /dev/null
+++ b/app/assets/images/emoji/articulated_lorry.png
Binary files differ
diff --git a/app/assets/images/emoji/asterisk.png b/app/assets/images/emoji/asterisk.png
new file mode 100644
index 00000000000..2f8e5113803
--- /dev/null
+++ b/app/assets/images/emoji/asterisk.png
Binary files differ
diff --git a/app/assets/images/emoji/astonished.png b/app/assets/images/emoji/astonished.png
new file mode 100644
index 00000000000..bd0ac55ec8e
--- /dev/null
+++ b/app/assets/images/emoji/astonished.png
Binary files differ
diff --git a/app/assets/images/emoji/athletic_shoe.png b/app/assets/images/emoji/athletic_shoe.png
new file mode 100644
index 00000000000..423fa07dd5d
--- /dev/null
+++ b/app/assets/images/emoji/athletic_shoe.png
Binary files differ
diff --git a/app/assets/images/emoji/atm.png b/app/assets/images/emoji/atm.png
new file mode 100644
index 00000000000..4d935307b94
--- /dev/null
+++ b/app/assets/images/emoji/atm.png
Binary files differ
diff --git a/app/assets/images/emoji/atom.png b/app/assets/images/emoji/atom.png
new file mode 100644
index 00000000000..5f4567aa093
--- /dev/null
+++ b/app/assets/images/emoji/atom.png
Binary files differ
diff --git a/app/assets/images/emoji/avocado.png b/app/assets/images/emoji/avocado.png
new file mode 100644
index 00000000000..06f0d124aed
--- /dev/null
+++ b/app/assets/images/emoji/avocado.png
Binary files differ
diff --git a/app/assets/images/emoji/b.png b/app/assets/images/emoji/b.png
new file mode 100644
index 00000000000..25875bc6a14
--- /dev/null
+++ b/app/assets/images/emoji/b.png
Binary files differ
diff --git a/app/assets/images/emoji/baby.png b/app/assets/images/emoji/baby.png
new file mode 100644
index 00000000000..a4af92c63c7
--- /dev/null
+++ b/app/assets/images/emoji/baby.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_bottle.png b/app/assets/images/emoji/baby_bottle.png
new file mode 100644
index 00000000000..2bd10524180
--- /dev/null
+++ b/app/assets/images/emoji/baby_bottle.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_chick.png b/app/assets/images/emoji/baby_chick.png
new file mode 100644
index 00000000000..dccd96576ea
--- /dev/null
+++ b/app/assets/images/emoji/baby_chick.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_symbol.png b/app/assets/images/emoji/baby_symbol.png
new file mode 100644
index 00000000000..64a10b71710
--- /dev/null
+++ b/app/assets/images/emoji/baby_symbol.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_tone1.png b/app/assets/images/emoji/baby_tone1.png
new file mode 100644
index 00000000000..d20911d40db
--- /dev/null
+++ b/app/assets/images/emoji/baby_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_tone2.png b/app/assets/images/emoji/baby_tone2.png
new file mode 100644
index 00000000000..b0a9b30ed17
--- /dev/null
+++ b/app/assets/images/emoji/baby_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_tone3.png b/app/assets/images/emoji/baby_tone3.png
new file mode 100644
index 00000000000..7de5286fac1
--- /dev/null
+++ b/app/assets/images/emoji/baby_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_tone4.png b/app/assets/images/emoji/baby_tone4.png
new file mode 100644
index 00000000000..9b7a86ac615
--- /dev/null
+++ b/app/assets/images/emoji/baby_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/baby_tone5.png b/app/assets/images/emoji/baby_tone5.png
new file mode 100644
index 00000000000..fe1be34cb88
--- /dev/null
+++ b/app/assets/images/emoji/baby_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/back.png b/app/assets/images/emoji/back.png
new file mode 100644
index 00000000000..d32c5d4f17f
--- /dev/null
+++ b/app/assets/images/emoji/back.png
Binary files differ
diff --git a/app/assets/images/emoji/bacon.png b/app/assets/images/emoji/bacon.png
new file mode 100644
index 00000000000..f38a485fbe4
--- /dev/null
+++ b/app/assets/images/emoji/bacon.png
Binary files differ
diff --git a/app/assets/images/emoji/badminton.png b/app/assets/images/emoji/badminton.png
new file mode 100644
index 00000000000..7ba15708990
--- /dev/null
+++ b/app/assets/images/emoji/badminton.png
Binary files differ
diff --git a/app/assets/images/emoji/baggage_claim.png b/app/assets/images/emoji/baggage_claim.png
new file mode 100644
index 00000000000..409b593e78a
--- /dev/null
+++ b/app/assets/images/emoji/baggage_claim.png
Binary files differ
diff --git a/app/assets/images/emoji/balloon.png b/app/assets/images/emoji/balloon.png
new file mode 100644
index 00000000000..07916fe6df1
--- /dev/null
+++ b/app/assets/images/emoji/balloon.png
Binary files differ
diff --git a/app/assets/images/emoji/ballot_box.png b/app/assets/images/emoji/ballot_box.png
new file mode 100644
index 00000000000..9b6767aea9e
--- /dev/null
+++ b/app/assets/images/emoji/ballot_box.png
Binary files differ
diff --git a/app/assets/images/emoji/ballot_box_with_check.png b/app/assets/images/emoji/ballot_box_with_check.png
new file mode 100644
index 00000000000..284d9573847
--- /dev/null
+++ b/app/assets/images/emoji/ballot_box_with_check.png
Binary files differ
diff --git a/app/assets/images/emoji/bamboo.png b/app/assets/images/emoji/bamboo.png
new file mode 100644
index 00000000000..5d5e0e728a0
--- /dev/null
+++ b/app/assets/images/emoji/bamboo.png
Binary files differ
diff --git a/app/assets/images/emoji/banana.png b/app/assets/images/emoji/banana.png
new file mode 100644
index 00000000000..f4987279580
--- /dev/null
+++ b/app/assets/images/emoji/banana.png
Binary files differ
diff --git a/app/assets/images/emoji/bangbang.png b/app/assets/images/emoji/bangbang.png
new file mode 100644
index 00000000000..58a9c528fca
--- /dev/null
+++ b/app/assets/images/emoji/bangbang.png
Binary files differ
diff --git a/app/assets/images/emoji/bank.png b/app/assets/images/emoji/bank.png
new file mode 100644
index 00000000000..dffdcef36a1
--- /dev/null
+++ b/app/assets/images/emoji/bank.png
Binary files differ
diff --git a/app/assets/images/emoji/bar_chart.png b/app/assets/images/emoji/bar_chart.png
new file mode 100644
index 00000000000..53c89455008
--- /dev/null
+++ b/app/assets/images/emoji/bar_chart.png
Binary files differ
diff --git a/app/assets/images/emoji/barber.png b/app/assets/images/emoji/barber.png
new file mode 100644
index 00000000000..896f4d716cf
--- /dev/null
+++ b/app/assets/images/emoji/barber.png
Binary files differ
diff --git a/app/assets/images/emoji/baseball.png b/app/assets/images/emoji/baseball.png
new file mode 100644
index 00000000000..f8463f1538b
--- /dev/null
+++ b/app/assets/images/emoji/baseball.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball.png b/app/assets/images/emoji/basketball.png
new file mode 100644
index 00000000000..64c76b79c6d
--- /dev/null
+++ b/app/assets/images/emoji/basketball.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball_player.png b/app/assets/images/emoji/basketball_player.png
new file mode 100644
index 00000000000..8ce90c5cad6
--- /dev/null
+++ b/app/assets/images/emoji/basketball_player.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball_player_tone1.png b/app/assets/images/emoji/basketball_player_tone1.png
new file mode 100644
index 00000000000..cd12c7ab9bf
--- /dev/null
+++ b/app/assets/images/emoji/basketball_player_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball_player_tone2.png b/app/assets/images/emoji/basketball_player_tone2.png
new file mode 100644
index 00000000000..f892fd596da
--- /dev/null
+++ b/app/assets/images/emoji/basketball_player_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball_player_tone3.png b/app/assets/images/emoji/basketball_player_tone3.png
new file mode 100644
index 00000000000..e109997a91a
--- /dev/null
+++ b/app/assets/images/emoji/basketball_player_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball_player_tone4.png b/app/assets/images/emoji/basketball_player_tone4.png
new file mode 100644
index 00000000000..3b90b946af4
--- /dev/null
+++ b/app/assets/images/emoji/basketball_player_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/basketball_player_tone5.png b/app/assets/images/emoji/basketball_player_tone5.png
new file mode 100644
index 00000000000..bafed7828a7
--- /dev/null
+++ b/app/assets/images/emoji/basketball_player_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/bat.png b/app/assets/images/emoji/bat.png
new file mode 100644
index 00000000000..3152c047e00
--- /dev/null
+++ b/app/assets/images/emoji/bat.png
Binary files differ
diff --git a/app/assets/images/emoji/bath.png b/app/assets/images/emoji/bath.png
new file mode 100644
index 00000000000..43fba5c8a28
--- /dev/null
+++ b/app/assets/images/emoji/bath.png
Binary files differ
diff --git a/app/assets/images/emoji/bath_tone1.png b/app/assets/images/emoji/bath_tone1.png
new file mode 100644
index 00000000000..2152eabf2f5
--- /dev/null
+++ b/app/assets/images/emoji/bath_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/bath_tone2.png b/app/assets/images/emoji/bath_tone2.png
new file mode 100644
index 00000000000..2102e6133e3
--- /dev/null
+++ b/app/assets/images/emoji/bath_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/bath_tone3.png b/app/assets/images/emoji/bath_tone3.png
new file mode 100644
index 00000000000..fae66181e9f
--- /dev/null
+++ b/app/assets/images/emoji/bath_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/bath_tone4.png b/app/assets/images/emoji/bath_tone4.png
new file mode 100644
index 00000000000..1f8959d0d99
--- /dev/null
+++ b/app/assets/images/emoji/bath_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/bath_tone5.png b/app/assets/images/emoji/bath_tone5.png
new file mode 100644
index 00000000000..c8a08e84f25
--- /dev/null
+++ b/app/assets/images/emoji/bath_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/bathtub.png b/app/assets/images/emoji/bathtub.png
new file mode 100644
index 00000000000..9a5f09361eb
--- /dev/null
+++ b/app/assets/images/emoji/bathtub.png
Binary files differ
diff --git a/app/assets/images/emoji/battery.png b/app/assets/images/emoji/battery.png
new file mode 100644
index 00000000000..f593e2bdb65
--- /dev/null
+++ b/app/assets/images/emoji/battery.png
Binary files differ
diff --git a/app/assets/images/emoji/beach.png b/app/assets/images/emoji/beach.png
new file mode 100644
index 00000000000..69108c8ea10
--- /dev/null
+++ b/app/assets/images/emoji/beach.png
Binary files differ
diff --git a/app/assets/images/emoji/beach_umbrella.png b/app/assets/images/emoji/beach_umbrella.png
new file mode 100644
index 00000000000..220a74f8132
--- /dev/null
+++ b/app/assets/images/emoji/beach_umbrella.png
Binary files differ
diff --git a/app/assets/images/emoji/bear.png b/app/assets/images/emoji/bear.png
new file mode 100644
index 00000000000..272d56bbbcc
--- /dev/null
+++ b/app/assets/images/emoji/bear.png
Binary files differ
diff --git a/app/assets/images/emoji/bed.png b/app/assets/images/emoji/bed.png
new file mode 100644
index 00000000000..86f964e245d
--- /dev/null
+++ b/app/assets/images/emoji/bed.png
Binary files differ
diff --git a/app/assets/images/emoji/bee.png b/app/assets/images/emoji/bee.png
new file mode 100644
index 00000000000..46156060096
--- /dev/null
+++ b/app/assets/images/emoji/bee.png
Binary files differ
diff --git a/app/assets/images/emoji/beer.png b/app/assets/images/emoji/beer.png
new file mode 100644
index 00000000000..b6d73dc0b7a
--- /dev/null
+++ b/app/assets/images/emoji/beer.png
Binary files differ
diff --git a/app/assets/images/emoji/beers.png b/app/assets/images/emoji/beers.png
new file mode 100644
index 00000000000..b55deb66b41
--- /dev/null
+++ b/app/assets/images/emoji/beers.png
Binary files differ
diff --git a/app/assets/images/emoji/beetle.png b/app/assets/images/emoji/beetle.png
new file mode 100644
index 00000000000..3d93174d7fc
--- /dev/null
+++ b/app/assets/images/emoji/beetle.png
Binary files differ
diff --git a/app/assets/images/emoji/beginner.png b/app/assets/images/emoji/beginner.png
new file mode 100644
index 00000000000..bc434fb7cb5
--- /dev/null
+++ b/app/assets/images/emoji/beginner.png
Binary files differ
diff --git a/app/assets/images/emoji/bell.png b/app/assets/images/emoji/bell.png
new file mode 100644
index 00000000000..5b3b0461999
--- /dev/null
+++ b/app/assets/images/emoji/bell.png
Binary files differ
diff --git a/app/assets/images/emoji/bellhop.png b/app/assets/images/emoji/bellhop.png
new file mode 100644
index 00000000000..6b3297ceaf7
--- /dev/null
+++ b/app/assets/images/emoji/bellhop.png
Binary files differ
diff --git a/app/assets/images/emoji/bento.png b/app/assets/images/emoji/bento.png
new file mode 100644
index 00000000000..83d41ca7eb9
--- /dev/null
+++ b/app/assets/images/emoji/bento.png
Binary files differ
diff --git a/app/assets/images/emoji/bicyclist.png b/app/assets/images/emoji/bicyclist.png
new file mode 100644
index 00000000000..9274da11048
--- /dev/null
+++ b/app/assets/images/emoji/bicyclist.png
Binary files differ
diff --git a/app/assets/images/emoji/bicyclist_tone1.png b/app/assets/images/emoji/bicyclist_tone1.png
new file mode 100644
index 00000000000..decc2f728fe
--- /dev/null
+++ b/app/assets/images/emoji/bicyclist_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/bicyclist_tone2.png b/app/assets/images/emoji/bicyclist_tone2.png
new file mode 100644
index 00000000000..0067717b80a
--- /dev/null
+++ b/app/assets/images/emoji/bicyclist_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/bicyclist_tone3.png b/app/assets/images/emoji/bicyclist_tone3.png
new file mode 100644
index 00000000000..a4f7b5e2776
--- /dev/null
+++ b/app/assets/images/emoji/bicyclist_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/bicyclist_tone4.png b/app/assets/images/emoji/bicyclist_tone4.png
new file mode 100644
index 00000000000..a3c8a797db4
--- /dev/null
+++ b/app/assets/images/emoji/bicyclist_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/bicyclist_tone5.png b/app/assets/images/emoji/bicyclist_tone5.png
new file mode 100644
index 00000000000..1606a874051
--- /dev/null
+++ b/app/assets/images/emoji/bicyclist_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/bike.png b/app/assets/images/emoji/bike.png
new file mode 100644
index 00000000000..556ed70f1a7
--- /dev/null
+++ b/app/assets/images/emoji/bike.png
Binary files differ
diff --git a/app/assets/images/emoji/bikini.png b/app/assets/images/emoji/bikini.png
new file mode 100644
index 00000000000..77a8a0aae5b
--- /dev/null
+++ b/app/assets/images/emoji/bikini.png
Binary files differ
diff --git a/app/assets/images/emoji/biohazard.png b/app/assets/images/emoji/biohazard.png
new file mode 100644
index 00000000000..007b4fc2d85
--- /dev/null
+++ b/app/assets/images/emoji/biohazard.png
Binary files differ
diff --git a/app/assets/images/emoji/bird.png b/app/assets/images/emoji/bird.png
new file mode 100644
index 00000000000..e201c22be33
--- /dev/null
+++ b/app/assets/images/emoji/bird.png
Binary files differ
diff --git a/app/assets/images/emoji/birthday.png b/app/assets/images/emoji/birthday.png
new file mode 100644
index 00000000000..317e9a41949
--- /dev/null
+++ b/app/assets/images/emoji/birthday.png
Binary files differ
diff --git a/app/assets/images/emoji/black_circle.png b/app/assets/images/emoji/black_circle.png
new file mode 100644
index 00000000000..b62b87170e8
--- /dev/null
+++ b/app/assets/images/emoji/black_circle.png
Binary files differ
diff --git a/app/assets/images/emoji/black_heart.png b/app/assets/images/emoji/black_heart.png
new file mode 100644
index 00000000000..b4068c3e6e8
--- /dev/null
+++ b/app/assets/images/emoji/black_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/black_joker.png b/app/assets/images/emoji/black_joker.png
new file mode 100644
index 00000000000..3d0924b68aa
--- /dev/null
+++ b/app/assets/images/emoji/black_joker.png
Binary files differ
diff --git a/app/assets/images/emoji/black_large_square.png b/app/assets/images/emoji/black_large_square.png
new file mode 100644
index 00000000000..162f2bb4290
--- /dev/null
+++ b/app/assets/images/emoji/black_large_square.png
Binary files differ
diff --git a/app/assets/images/emoji/black_medium_small_square.png b/app/assets/images/emoji/black_medium_small_square.png
new file mode 100644
index 00000000000..39765bba610
--- /dev/null
+++ b/app/assets/images/emoji/black_medium_small_square.png
Binary files differ
diff --git a/app/assets/images/emoji/black_medium_square.png b/app/assets/images/emoji/black_medium_square.png
new file mode 100644
index 00000000000..05a30a6aa2d
--- /dev/null
+++ b/app/assets/images/emoji/black_medium_square.png
Binary files differ
diff --git a/app/assets/images/emoji/black_nib.png b/app/assets/images/emoji/black_nib.png
new file mode 100644
index 00000000000..872d0ae1598
--- /dev/null
+++ b/app/assets/images/emoji/black_nib.png
Binary files differ
diff --git a/app/assets/images/emoji/black_small_square.png b/app/assets/images/emoji/black_small_square.png
new file mode 100644
index 00000000000..48595d3e1a9
--- /dev/null
+++ b/app/assets/images/emoji/black_small_square.png
Binary files differ
diff --git a/app/assets/images/emoji/black_square_button.png b/app/assets/images/emoji/black_square_button.png
new file mode 100644
index 00000000000..a78fc2f6b63
--- /dev/null
+++ b/app/assets/images/emoji/black_square_button.png
Binary files differ
diff --git a/app/assets/images/emoji/blossom.png b/app/assets/images/emoji/blossom.png
new file mode 100644
index 00000000000..4083026c157
--- /dev/null
+++ b/app/assets/images/emoji/blossom.png
Binary files differ
diff --git a/app/assets/images/emoji/blowfish.png b/app/assets/images/emoji/blowfish.png
new file mode 100644
index 00000000000..a10f4f84e35
--- /dev/null
+++ b/app/assets/images/emoji/blowfish.png
Binary files differ
diff --git a/app/assets/images/emoji/blue_book.png b/app/assets/images/emoji/blue_book.png
new file mode 100644
index 00000000000..e1e455401cc
--- /dev/null
+++ b/app/assets/images/emoji/blue_book.png
Binary files differ
diff --git a/app/assets/images/emoji/blue_car.png b/app/assets/images/emoji/blue_car.png
new file mode 100644
index 00000000000..e8ba817d393
--- /dev/null
+++ b/app/assets/images/emoji/blue_car.png
Binary files differ
diff --git a/app/assets/images/emoji/blue_heart.png b/app/assets/images/emoji/blue_heart.png
new file mode 100644
index 00000000000..bdf1287e55e
--- /dev/null
+++ b/app/assets/images/emoji/blue_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/blush.png b/app/assets/images/emoji/blush.png
new file mode 100644
index 00000000000..aac1a424ad4
--- /dev/null
+++ b/app/assets/images/emoji/blush.png
Binary files differ
diff --git a/app/assets/images/emoji/boar.png b/app/assets/images/emoji/boar.png
new file mode 100644
index 00000000000..fead972633c
--- /dev/null
+++ b/app/assets/images/emoji/boar.png
Binary files differ
diff --git a/app/assets/images/emoji/bomb.png b/app/assets/images/emoji/bomb.png
new file mode 100644
index 00000000000..c7f8f81c939
--- /dev/null
+++ b/app/assets/images/emoji/bomb.png
Binary files differ
diff --git a/app/assets/images/emoji/book.png b/app/assets/images/emoji/book.png
new file mode 100644
index 00000000000..0f4447ed396
--- /dev/null
+++ b/app/assets/images/emoji/book.png
Binary files differ
diff --git a/app/assets/images/emoji/bookmark.png b/app/assets/images/emoji/bookmark.png
new file mode 100644
index 00000000000..bbb444611f0
--- /dev/null
+++ b/app/assets/images/emoji/bookmark.png
Binary files differ
diff --git a/app/assets/images/emoji/bookmark_tabs.png b/app/assets/images/emoji/bookmark_tabs.png
new file mode 100644
index 00000000000..f8d9e01b428
--- /dev/null
+++ b/app/assets/images/emoji/bookmark_tabs.png
Binary files differ
diff --git a/app/assets/images/emoji/books.png b/app/assets/images/emoji/books.png
new file mode 100644
index 00000000000..59a8bafeb0d
--- /dev/null
+++ b/app/assets/images/emoji/books.png
Binary files differ
diff --git a/app/assets/images/emoji/boom.png b/app/assets/images/emoji/boom.png
new file mode 100644
index 00000000000..9b0f027b1a8
--- /dev/null
+++ b/app/assets/images/emoji/boom.png
Binary files differ
diff --git a/app/assets/images/emoji/boot.png b/app/assets/images/emoji/boot.png
new file mode 100644
index 00000000000..11f1065ed07
--- /dev/null
+++ b/app/assets/images/emoji/boot.png
Binary files differ
diff --git a/app/assets/images/emoji/bouquet.png b/app/assets/images/emoji/bouquet.png
new file mode 100644
index 00000000000..11455af6df4
--- /dev/null
+++ b/app/assets/images/emoji/bouquet.png
Binary files differ
diff --git a/app/assets/images/emoji/bow.png b/app/assets/images/emoji/bow.png
new file mode 100644
index 00000000000..d8f793088dc
--- /dev/null
+++ b/app/assets/images/emoji/bow.png
Binary files differ
diff --git a/app/assets/images/emoji/bow_and_arrow.png b/app/assets/images/emoji/bow_and_arrow.png
new file mode 100644
index 00000000000..6a538bf475f
--- /dev/null
+++ b/app/assets/images/emoji/bow_and_arrow.png
Binary files differ
diff --git a/app/assets/images/emoji/bow_tone1.png b/app/assets/images/emoji/bow_tone1.png
new file mode 100644
index 00000000000..87afb7b54cf
--- /dev/null
+++ b/app/assets/images/emoji/bow_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/bow_tone2.png b/app/assets/images/emoji/bow_tone2.png
new file mode 100644
index 00000000000..3ccf7dc0850
--- /dev/null
+++ b/app/assets/images/emoji/bow_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/bow_tone3.png b/app/assets/images/emoji/bow_tone3.png
new file mode 100644
index 00000000000..8b9eb64f926
--- /dev/null
+++ b/app/assets/images/emoji/bow_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/bow_tone4.png b/app/assets/images/emoji/bow_tone4.png
new file mode 100644
index 00000000000..683795ff40d
--- /dev/null
+++ b/app/assets/images/emoji/bow_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/bow_tone5.png b/app/assets/images/emoji/bow_tone5.png
new file mode 100644
index 00000000000..7969d971752
--- /dev/null
+++ b/app/assets/images/emoji/bow_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/bowling.png b/app/assets/images/emoji/bowling.png
new file mode 100644
index 00000000000..63add89e53b
--- /dev/null
+++ b/app/assets/images/emoji/bowling.png
Binary files differ
diff --git a/app/assets/images/emoji/boxing_glove.png b/app/assets/images/emoji/boxing_glove.png
new file mode 100644
index 00000000000..9838f24e51a
--- /dev/null
+++ b/app/assets/images/emoji/boxing_glove.png
Binary files differ
diff --git a/app/assets/images/emoji/boy.png b/app/assets/images/emoji/boy.png
new file mode 100644
index 00000000000..8ecfb0a4e92
--- /dev/null
+++ b/app/assets/images/emoji/boy.png
Binary files differ
diff --git a/app/assets/images/emoji/boy_tone1.png b/app/assets/images/emoji/boy_tone1.png
new file mode 100644
index 00000000000..2fc436ea512
--- /dev/null
+++ b/app/assets/images/emoji/boy_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/boy_tone2.png b/app/assets/images/emoji/boy_tone2.png
new file mode 100644
index 00000000000..09a5f18d360
--- /dev/null
+++ b/app/assets/images/emoji/boy_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/boy_tone3.png b/app/assets/images/emoji/boy_tone3.png
new file mode 100644
index 00000000000..3cfe675dd3a
--- /dev/null
+++ b/app/assets/images/emoji/boy_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/boy_tone4.png b/app/assets/images/emoji/boy_tone4.png
new file mode 100644
index 00000000000..780be0ace36
--- /dev/null
+++ b/app/assets/images/emoji/boy_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/boy_tone5.png b/app/assets/images/emoji/boy_tone5.png
new file mode 100644
index 00000000000..f32fe22e35c
--- /dev/null
+++ b/app/assets/images/emoji/boy_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/bread.png b/app/assets/images/emoji/bread.png
new file mode 100644
index 00000000000..6676510aaa5
--- /dev/null
+++ b/app/assets/images/emoji/bread.png
Binary files differ
diff --git a/app/assets/images/emoji/bride_with_veil.png b/app/assets/images/emoji/bride_with_veil.png
new file mode 100644
index 00000000000..eaf4bd97890
--- /dev/null
+++ b/app/assets/images/emoji/bride_with_veil.png
Binary files differ
diff --git a/app/assets/images/emoji/bride_with_veil_tone1.png b/app/assets/images/emoji/bride_with_veil_tone1.png
new file mode 100644
index 00000000000..c4fb141ae8f
--- /dev/null
+++ b/app/assets/images/emoji/bride_with_veil_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/bride_with_veil_tone2.png b/app/assets/images/emoji/bride_with_veil_tone2.png
new file mode 100644
index 00000000000..c248769fc06
--- /dev/null
+++ b/app/assets/images/emoji/bride_with_veil_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/bride_with_veil_tone3.png b/app/assets/images/emoji/bride_with_veil_tone3.png
new file mode 100644
index 00000000000..962c0a6eedb
--- /dev/null
+++ b/app/assets/images/emoji/bride_with_veil_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/bride_with_veil_tone4.png b/app/assets/images/emoji/bride_with_veil_tone4.png
new file mode 100644
index 00000000000..740ca208cd4
--- /dev/null
+++ b/app/assets/images/emoji/bride_with_veil_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/bride_with_veil_tone5.png b/app/assets/images/emoji/bride_with_veil_tone5.png
new file mode 100644
index 00000000000..5cc5598587d
--- /dev/null
+++ b/app/assets/images/emoji/bride_with_veil_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/bridge_at_night.png b/app/assets/images/emoji/bridge_at_night.png
new file mode 100644
index 00000000000..1d444e0be65
--- /dev/null
+++ b/app/assets/images/emoji/bridge_at_night.png
Binary files differ
diff --git a/app/assets/images/emoji/briefcase.png b/app/assets/images/emoji/briefcase.png
new file mode 100644
index 00000000000..b9912ba2148
--- /dev/null
+++ b/app/assets/images/emoji/briefcase.png
Binary files differ
diff --git a/app/assets/images/emoji/broken_heart.png b/app/assets/images/emoji/broken_heart.png
new file mode 100644
index 00000000000..718e26ee122
--- /dev/null
+++ b/app/assets/images/emoji/broken_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/bug.png b/app/assets/images/emoji/bug.png
new file mode 100644
index 00000000000..e64e72f259a
--- /dev/null
+++ b/app/assets/images/emoji/bug.png
Binary files differ
diff --git a/app/assets/images/emoji/bulb.png b/app/assets/images/emoji/bulb.png
new file mode 100644
index 00000000000..38e32e02d9f
--- /dev/null
+++ b/app/assets/images/emoji/bulb.png
Binary files differ
diff --git a/app/assets/images/emoji/bullettrain_front.png b/app/assets/images/emoji/bullettrain_front.png
new file mode 100644
index 00000000000..4f698e056fa
--- /dev/null
+++ b/app/assets/images/emoji/bullettrain_front.png
Binary files differ
diff --git a/app/assets/images/emoji/bullettrain_side.png b/app/assets/images/emoji/bullettrain_side.png
new file mode 100644
index 00000000000..ed61c67bf07
--- /dev/null
+++ b/app/assets/images/emoji/bullettrain_side.png
Binary files differ
diff --git a/app/assets/images/emoji/burrito.png b/app/assets/images/emoji/burrito.png
new file mode 100644
index 00000000000..02bd5601df7
--- /dev/null
+++ b/app/assets/images/emoji/burrito.png
Binary files differ
diff --git a/app/assets/images/emoji/bus.png b/app/assets/images/emoji/bus.png
new file mode 100644
index 00000000000..641ddc56ca7
--- /dev/null
+++ b/app/assets/images/emoji/bus.png
Binary files differ
diff --git a/app/assets/images/emoji/busstop.png b/app/assets/images/emoji/busstop.png
new file mode 100644
index 00000000000..b2b62208bfd
--- /dev/null
+++ b/app/assets/images/emoji/busstop.png
Binary files differ
diff --git a/app/assets/images/emoji/bust_in_silhouette.png b/app/assets/images/emoji/bust_in_silhouette.png
new file mode 100644
index 00000000000..123b2cbe1fb
--- /dev/null
+++ b/app/assets/images/emoji/bust_in_silhouette.png
Binary files differ
diff --git a/app/assets/images/emoji/busts_in_silhouette.png b/app/assets/images/emoji/busts_in_silhouette.png
new file mode 100644
index 00000000000..d7656860a1c
--- /dev/null
+++ b/app/assets/images/emoji/busts_in_silhouette.png
Binary files differ
diff --git a/app/assets/images/emoji/butterfly.png b/app/assets/images/emoji/butterfly.png
new file mode 100644
index 00000000000..5631fe99226
--- /dev/null
+++ b/app/assets/images/emoji/butterfly.png
Binary files differ
diff --git a/app/assets/images/emoji/cactus.png b/app/assets/images/emoji/cactus.png
new file mode 100644
index 00000000000..9b48ccf3d0c
--- /dev/null
+++ b/app/assets/images/emoji/cactus.png
Binary files differ
diff --git a/app/assets/images/emoji/cake.png b/app/assets/images/emoji/cake.png
new file mode 100644
index 00000000000..4368177be9a
--- /dev/null
+++ b/app/assets/images/emoji/cake.png
Binary files differ
diff --git a/app/assets/images/emoji/calendar.png b/app/assets/images/emoji/calendar.png
new file mode 100644
index 00000000000..47353b74447
--- /dev/null
+++ b/app/assets/images/emoji/calendar.png
Binary files differ
diff --git a/app/assets/images/emoji/calendar_spiral.png b/app/assets/images/emoji/calendar_spiral.png
new file mode 100644
index 00000000000..dec8d49bfa8
--- /dev/null
+++ b/app/assets/images/emoji/calendar_spiral.png
Binary files differ
diff --git a/app/assets/images/emoji/call_me.png b/app/assets/images/emoji/call_me.png
new file mode 100644
index 00000000000..a10c59ba711
--- /dev/null
+++ b/app/assets/images/emoji/call_me.png
Binary files differ
diff --git a/app/assets/images/emoji/call_me_tone1.png b/app/assets/images/emoji/call_me_tone1.png
new file mode 100644
index 00000000000..2c93201181a
--- /dev/null
+++ b/app/assets/images/emoji/call_me_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/call_me_tone2.png b/app/assets/images/emoji/call_me_tone2.png
new file mode 100644
index 00000000000..c39f45a41ed
--- /dev/null
+++ b/app/assets/images/emoji/call_me_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/call_me_tone3.png b/app/assets/images/emoji/call_me_tone3.png
new file mode 100644
index 00000000000..83a57f63c29
--- /dev/null
+++ b/app/assets/images/emoji/call_me_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/call_me_tone4.png b/app/assets/images/emoji/call_me_tone4.png
new file mode 100644
index 00000000000..65b3468fe44
--- /dev/null
+++ b/app/assets/images/emoji/call_me_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/call_me_tone5.png b/app/assets/images/emoji/call_me_tone5.png
new file mode 100644
index 00000000000..94ef68ff3b3
--- /dev/null
+++ b/app/assets/images/emoji/call_me_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/calling.png b/app/assets/images/emoji/calling.png
new file mode 100644
index 00000000000..e2f308f8e46
--- /dev/null
+++ b/app/assets/images/emoji/calling.png
Binary files differ
diff --git a/app/assets/images/emoji/camel.png b/app/assets/images/emoji/camel.png
new file mode 100644
index 00000000000..b421d07a805
--- /dev/null
+++ b/app/assets/images/emoji/camel.png
Binary files differ
diff --git a/app/assets/images/emoji/camera.png b/app/assets/images/emoji/camera.png
new file mode 100644
index 00000000000..0a3429f72ef
--- /dev/null
+++ b/app/assets/images/emoji/camera.png
Binary files differ
diff --git a/app/assets/images/emoji/camera_with_flash.png b/app/assets/images/emoji/camera_with_flash.png
new file mode 100644
index 00000000000..27471da2029
--- /dev/null
+++ b/app/assets/images/emoji/camera_with_flash.png
Binary files differ
diff --git a/app/assets/images/emoji/camping.png b/app/assets/images/emoji/camping.png
new file mode 100644
index 00000000000..d589cc1f44b
--- /dev/null
+++ b/app/assets/images/emoji/camping.png
Binary files differ
diff --git a/app/assets/images/emoji/cancer.png b/app/assets/images/emoji/cancer.png
new file mode 100644
index 00000000000..a64af07cb5f
--- /dev/null
+++ b/app/assets/images/emoji/cancer.png
Binary files differ
diff --git a/app/assets/images/emoji/candle.png b/app/assets/images/emoji/candle.png
new file mode 100644
index 00000000000..0b56444e355
--- /dev/null
+++ b/app/assets/images/emoji/candle.png
Binary files differ
diff --git a/app/assets/images/emoji/candy.png b/app/assets/images/emoji/candy.png
new file mode 100644
index 00000000000..8c67ace3a35
--- /dev/null
+++ b/app/assets/images/emoji/candy.png
Binary files differ
diff --git a/app/assets/images/emoji/canoe.png b/app/assets/images/emoji/canoe.png
new file mode 100644
index 00000000000..e26cdb9da69
--- /dev/null
+++ b/app/assets/images/emoji/canoe.png
Binary files differ
diff --git a/app/assets/images/emoji/capital_abcd.png b/app/assets/images/emoji/capital_abcd.png
new file mode 100644
index 00000000000..fe9482d2d8a
--- /dev/null
+++ b/app/assets/images/emoji/capital_abcd.png
Binary files differ
diff --git a/app/assets/images/emoji/capricorn.png b/app/assets/images/emoji/capricorn.png
new file mode 100644
index 00000000000..6293d31d4b1
--- /dev/null
+++ b/app/assets/images/emoji/capricorn.png
Binary files differ
diff --git a/app/assets/images/emoji/card_box.png b/app/assets/images/emoji/card_box.png
new file mode 100644
index 00000000000..f2e764ce59d
--- /dev/null
+++ b/app/assets/images/emoji/card_box.png
Binary files differ
diff --git a/app/assets/images/emoji/card_index.png b/app/assets/images/emoji/card_index.png
new file mode 100644
index 00000000000..151e11cb3b4
--- /dev/null
+++ b/app/assets/images/emoji/card_index.png
Binary files differ
diff --git a/app/assets/images/emoji/carousel_horse.png b/app/assets/images/emoji/carousel_horse.png
new file mode 100644
index 00000000000..a17074edf05
--- /dev/null
+++ b/app/assets/images/emoji/carousel_horse.png
Binary files differ
diff --git a/app/assets/images/emoji/carrot.png b/app/assets/images/emoji/carrot.png
new file mode 100644
index 00000000000..c68829b58e7
--- /dev/null
+++ b/app/assets/images/emoji/carrot.png
Binary files differ
diff --git a/app/assets/images/emoji/cartwheel.png b/app/assets/images/emoji/cartwheel.png
new file mode 100644
index 00000000000..cbcaa578253
--- /dev/null
+++ b/app/assets/images/emoji/cartwheel.png
Binary files differ
diff --git a/app/assets/images/emoji/cartwheel_tone1.png b/app/assets/images/emoji/cartwheel_tone1.png
new file mode 100644
index 00000000000..db6d65895fb
--- /dev/null
+++ b/app/assets/images/emoji/cartwheel_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/cartwheel_tone2.png b/app/assets/images/emoji/cartwheel_tone2.png
new file mode 100644
index 00000000000..e00ffbc27a8
--- /dev/null
+++ b/app/assets/images/emoji/cartwheel_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/cartwheel_tone3.png b/app/assets/images/emoji/cartwheel_tone3.png
new file mode 100644
index 00000000000..49321be391f
--- /dev/null
+++ b/app/assets/images/emoji/cartwheel_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/cartwheel_tone4.png b/app/assets/images/emoji/cartwheel_tone4.png
new file mode 100644
index 00000000000..d4562b5e3dd
--- /dev/null
+++ b/app/assets/images/emoji/cartwheel_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/cartwheel_tone5.png b/app/assets/images/emoji/cartwheel_tone5.png
new file mode 100644
index 00000000000..6e09a870767
--- /dev/null
+++ b/app/assets/images/emoji/cartwheel_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/cat.png b/app/assets/images/emoji/cat.png
new file mode 100644
index 00000000000..efd82c2abf3
--- /dev/null
+++ b/app/assets/images/emoji/cat.png
Binary files differ
diff --git a/app/assets/images/emoji/cat2.png b/app/assets/images/emoji/cat2.png
new file mode 100644
index 00000000000..46abe8cbc14
--- /dev/null
+++ b/app/assets/images/emoji/cat2.png
Binary files differ
diff --git a/app/assets/images/emoji/cd.png b/app/assets/images/emoji/cd.png
new file mode 100644
index 00000000000..e6b01449cd9
--- /dev/null
+++ b/app/assets/images/emoji/cd.png
Binary files differ
diff --git a/app/assets/images/emoji/chains.png b/app/assets/images/emoji/chains.png
new file mode 100644
index 00000000000..57f46139a06
--- /dev/null
+++ b/app/assets/images/emoji/chains.png
Binary files differ
diff --git a/app/assets/images/emoji/champagne.png b/app/assets/images/emoji/champagne.png
new file mode 100644
index 00000000000..285a79a93d0
--- /dev/null
+++ b/app/assets/images/emoji/champagne.png
Binary files differ
diff --git a/app/assets/images/emoji/champagne_glass.png b/app/assets/images/emoji/champagne_glass.png
new file mode 100644
index 00000000000..31937ae9392
--- /dev/null
+++ b/app/assets/images/emoji/champagne_glass.png
Binary files differ
diff --git a/app/assets/images/emoji/chart.png b/app/assets/images/emoji/chart.png
new file mode 100644
index 00000000000..9773f03be22
--- /dev/null
+++ b/app/assets/images/emoji/chart.png
Binary files differ
diff --git a/app/assets/images/emoji/chart_with_downwards_trend.png b/app/assets/images/emoji/chart_with_downwards_trend.png
new file mode 100644
index 00000000000..5222ec72d85
--- /dev/null
+++ b/app/assets/images/emoji/chart_with_downwards_trend.png
Binary files differ
diff --git a/app/assets/images/emoji/chart_with_upwards_trend.png b/app/assets/images/emoji/chart_with_upwards_trend.png
new file mode 100644
index 00000000000..f13cfcf9956
--- /dev/null
+++ b/app/assets/images/emoji/chart_with_upwards_trend.png
Binary files differ
diff --git a/app/assets/images/emoji/checkered_flag.png b/app/assets/images/emoji/checkered_flag.png
new file mode 100644
index 00000000000..5a71eecb89b
--- /dev/null
+++ b/app/assets/images/emoji/checkered_flag.png
Binary files differ
diff --git a/app/assets/images/emoji/cheese.png b/app/assets/images/emoji/cheese.png
new file mode 100644
index 00000000000..00e99762286
--- /dev/null
+++ b/app/assets/images/emoji/cheese.png
Binary files differ
diff --git a/app/assets/images/emoji/cherries.png b/app/assets/images/emoji/cherries.png
new file mode 100644
index 00000000000..9b10cbaac5e
--- /dev/null
+++ b/app/assets/images/emoji/cherries.png
Binary files differ
diff --git a/app/assets/images/emoji/cherry_blossom.png b/app/assets/images/emoji/cherry_blossom.png
new file mode 100644
index 00000000000..282f3e7bc81
--- /dev/null
+++ b/app/assets/images/emoji/cherry_blossom.png
Binary files differ
diff --git a/app/assets/images/emoji/chestnut.png b/app/assets/images/emoji/chestnut.png
new file mode 100644
index 00000000000..e9fb40468ed
--- /dev/null
+++ b/app/assets/images/emoji/chestnut.png
Binary files differ
diff --git a/app/assets/images/emoji/chicken.png b/app/assets/images/emoji/chicken.png
new file mode 100644
index 00000000000..9a6992e55ba
--- /dev/null
+++ b/app/assets/images/emoji/chicken.png
Binary files differ
diff --git a/app/assets/images/emoji/children_crossing.png b/app/assets/images/emoji/children_crossing.png
new file mode 100644
index 00000000000..fa4c091c7c3
--- /dev/null
+++ b/app/assets/images/emoji/children_crossing.png
Binary files differ
diff --git a/app/assets/images/emoji/chipmunk.png b/app/assets/images/emoji/chipmunk.png
new file mode 100644
index 00000000000..2aac560cb22
--- /dev/null
+++ b/app/assets/images/emoji/chipmunk.png
Binary files differ
diff --git a/app/assets/images/emoji/chocolate_bar.png b/app/assets/images/emoji/chocolate_bar.png
new file mode 100644
index 00000000000..318bbd40ef9
--- /dev/null
+++ b/app/assets/images/emoji/chocolate_bar.png
Binary files differ
diff --git a/app/assets/images/emoji/christmas_tree.png b/app/assets/images/emoji/christmas_tree.png
new file mode 100644
index 00000000000..4197d37a52b
--- /dev/null
+++ b/app/assets/images/emoji/christmas_tree.png
Binary files differ
diff --git a/app/assets/images/emoji/church.png b/app/assets/images/emoji/church.png
new file mode 100644
index 00000000000..8242fd272b3
--- /dev/null
+++ b/app/assets/images/emoji/church.png
Binary files differ
diff --git a/app/assets/images/emoji/cinema.png b/app/assets/images/emoji/cinema.png
new file mode 100644
index 00000000000..65f27b386f2
--- /dev/null
+++ b/app/assets/images/emoji/cinema.png
Binary files differ
diff --git a/app/assets/images/emoji/circus_tent.png b/app/assets/images/emoji/circus_tent.png
new file mode 100644
index 00000000000..b0379775b12
--- /dev/null
+++ b/app/assets/images/emoji/circus_tent.png
Binary files differ
diff --git a/app/assets/images/emoji/city_dusk.png b/app/assets/images/emoji/city_dusk.png
new file mode 100644
index 00000000000..80cdff7cf5d
--- /dev/null
+++ b/app/assets/images/emoji/city_dusk.png
Binary files differ
diff --git a/app/assets/images/emoji/city_sunset.png b/app/assets/images/emoji/city_sunset.png
new file mode 100644
index 00000000000..7cded0ba55b
--- /dev/null
+++ b/app/assets/images/emoji/city_sunset.png
Binary files differ
diff --git a/app/assets/images/emoji/cityscape.png b/app/assets/images/emoji/cityscape.png
new file mode 100644
index 00000000000..d7b9844a0b4
--- /dev/null
+++ b/app/assets/images/emoji/cityscape.png
Binary files differ
diff --git a/app/assets/images/emoji/cl.png b/app/assets/images/emoji/cl.png
new file mode 100644
index 00000000000..8b01b4343e2
--- /dev/null
+++ b/app/assets/images/emoji/cl.png
Binary files differ
diff --git a/app/assets/images/emoji/clap.png b/app/assets/images/emoji/clap.png
new file mode 100644
index 00000000000..b0ffe928920
--- /dev/null
+++ b/app/assets/images/emoji/clap.png
Binary files differ
diff --git a/app/assets/images/emoji/clap_tone1.png b/app/assets/images/emoji/clap_tone1.png
new file mode 100644
index 00000000000..de4bc837b96
--- /dev/null
+++ b/app/assets/images/emoji/clap_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/clap_tone2.png b/app/assets/images/emoji/clap_tone2.png
new file mode 100644
index 00000000000..1323de775ba
--- /dev/null
+++ b/app/assets/images/emoji/clap_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/clap_tone3.png b/app/assets/images/emoji/clap_tone3.png
new file mode 100644
index 00000000000..d448ca19dde
--- /dev/null
+++ b/app/assets/images/emoji/clap_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/clap_tone4.png b/app/assets/images/emoji/clap_tone4.png
new file mode 100644
index 00000000000..c49f44ee91d
--- /dev/null
+++ b/app/assets/images/emoji/clap_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/clap_tone5.png b/app/assets/images/emoji/clap_tone5.png
new file mode 100644
index 00000000000..29ee9bdf37c
--- /dev/null
+++ b/app/assets/images/emoji/clap_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/clapper.png b/app/assets/images/emoji/clapper.png
new file mode 100644
index 00000000000..81390883111
--- /dev/null
+++ b/app/assets/images/emoji/clapper.png
Binary files differ
diff --git a/app/assets/images/emoji/classical_building.png b/app/assets/images/emoji/classical_building.png
new file mode 100644
index 00000000000..de7b559daaf
--- /dev/null
+++ b/app/assets/images/emoji/classical_building.png
Binary files differ
diff --git a/app/assets/images/emoji/clipboard.png b/app/assets/images/emoji/clipboard.png
new file mode 100644
index 00000000000..7edcfc52509
--- /dev/null
+++ b/app/assets/images/emoji/clipboard.png
Binary files differ
diff --git a/app/assets/images/emoji/clock.png b/app/assets/images/emoji/clock.png
new file mode 100644
index 00000000000..ffdb451e3a8
--- /dev/null
+++ b/app/assets/images/emoji/clock.png
Binary files differ
diff --git a/app/assets/images/emoji/clock1.png b/app/assets/images/emoji/clock1.png
new file mode 100644
index 00000000000..d6e34941f23
--- /dev/null
+++ b/app/assets/images/emoji/clock1.png
Binary files differ
diff --git a/app/assets/images/emoji/clock10.png b/app/assets/images/emoji/clock10.png
new file mode 100644
index 00000000000..e62b245cdbe
--- /dev/null
+++ b/app/assets/images/emoji/clock10.png
Binary files differ
diff --git a/app/assets/images/emoji/clock1030.png b/app/assets/images/emoji/clock1030.png
new file mode 100644
index 00000000000..0802b3c65b9
--- /dev/null
+++ b/app/assets/images/emoji/clock1030.png
Binary files differ
diff --git a/app/assets/images/emoji/clock11.png b/app/assets/images/emoji/clock11.png
new file mode 100644
index 00000000000..0983345273b
--- /dev/null
+++ b/app/assets/images/emoji/clock11.png
Binary files differ
diff --git a/app/assets/images/emoji/clock1130.png b/app/assets/images/emoji/clock1130.png
new file mode 100644
index 00000000000..d970d03b809
--- /dev/null
+++ b/app/assets/images/emoji/clock1130.png
Binary files differ
diff --git a/app/assets/images/emoji/clock12.png b/app/assets/images/emoji/clock12.png
new file mode 100644
index 00000000000..e61caa4b3e2
--- /dev/null
+++ b/app/assets/images/emoji/clock12.png
Binary files differ
diff --git a/app/assets/images/emoji/clock1230.png b/app/assets/images/emoji/clock1230.png
new file mode 100644
index 00000000000..f2b1d261721
--- /dev/null
+++ b/app/assets/images/emoji/clock1230.png
Binary files differ
diff --git a/app/assets/images/emoji/clock130.png b/app/assets/images/emoji/clock130.png
new file mode 100644
index 00000000000..86b7689b84e
--- /dev/null
+++ b/app/assets/images/emoji/clock130.png
Binary files differ
diff --git a/app/assets/images/emoji/clock2.png b/app/assets/images/emoji/clock2.png
new file mode 100644
index 00000000000..a54253d7d57
--- /dev/null
+++ b/app/assets/images/emoji/clock2.png
Binary files differ
diff --git a/app/assets/images/emoji/clock230.png b/app/assets/images/emoji/clock230.png
new file mode 100644
index 00000000000..7a787e018e6
--- /dev/null
+++ b/app/assets/images/emoji/clock230.png
Binary files differ
diff --git a/app/assets/images/emoji/clock3.png b/app/assets/images/emoji/clock3.png
new file mode 100644
index 00000000000..27ec4b1f514
--- /dev/null
+++ b/app/assets/images/emoji/clock3.png
Binary files differ
diff --git a/app/assets/images/emoji/clock330.png b/app/assets/images/emoji/clock330.png
new file mode 100644
index 00000000000..c6860395cec
--- /dev/null
+++ b/app/assets/images/emoji/clock330.png
Binary files differ
diff --git a/app/assets/images/emoji/clock4.png b/app/assets/images/emoji/clock4.png
new file mode 100644
index 00000000000..60a1ef4cc13
--- /dev/null
+++ b/app/assets/images/emoji/clock4.png
Binary files differ
diff --git a/app/assets/images/emoji/clock430.png b/app/assets/images/emoji/clock430.png
new file mode 100644
index 00000000000..3c05b362122
--- /dev/null
+++ b/app/assets/images/emoji/clock430.png
Binary files differ
diff --git a/app/assets/images/emoji/clock5.png b/app/assets/images/emoji/clock5.png
new file mode 100644
index 00000000000..c9382d1e094
--- /dev/null
+++ b/app/assets/images/emoji/clock5.png
Binary files differ
diff --git a/app/assets/images/emoji/clock530.png b/app/assets/images/emoji/clock530.png
new file mode 100644
index 00000000000..c21fa926db2
--- /dev/null
+++ b/app/assets/images/emoji/clock530.png
Binary files differ
diff --git a/app/assets/images/emoji/clock6.png b/app/assets/images/emoji/clock6.png
new file mode 100644
index 00000000000..8fd5d3f5bd7
--- /dev/null
+++ b/app/assets/images/emoji/clock6.png
Binary files differ
diff --git a/app/assets/images/emoji/clock630.png b/app/assets/images/emoji/clock630.png
new file mode 100644
index 00000000000..2aec87fefcf
--- /dev/null
+++ b/app/assets/images/emoji/clock630.png
Binary files differ
diff --git a/app/assets/images/emoji/clock7.png b/app/assets/images/emoji/clock7.png
new file mode 100644
index 00000000000..8c7084036f2
--- /dev/null
+++ b/app/assets/images/emoji/clock7.png
Binary files differ
diff --git a/app/assets/images/emoji/clock730.png b/app/assets/images/emoji/clock730.png
new file mode 100644
index 00000000000..f7a1135e03f
--- /dev/null
+++ b/app/assets/images/emoji/clock730.png
Binary files differ
diff --git a/app/assets/images/emoji/clock8.png b/app/assets/images/emoji/clock8.png
new file mode 100644
index 00000000000..fcddf722e95
--- /dev/null
+++ b/app/assets/images/emoji/clock8.png
Binary files differ
diff --git a/app/assets/images/emoji/clock830.png b/app/assets/images/emoji/clock830.png
new file mode 100644
index 00000000000..799b4aebc08
--- /dev/null
+++ b/app/assets/images/emoji/clock830.png
Binary files differ
diff --git a/app/assets/images/emoji/clock9.png b/app/assets/images/emoji/clock9.png
new file mode 100644
index 00000000000..dfbe0117981
--- /dev/null
+++ b/app/assets/images/emoji/clock9.png
Binary files differ
diff --git a/app/assets/images/emoji/clock930.png b/app/assets/images/emoji/clock930.png
new file mode 100644
index 00000000000..4a2092ee6f0
--- /dev/null
+++ b/app/assets/images/emoji/clock930.png
Binary files differ
diff --git a/app/assets/images/emoji/closed_book.png b/app/assets/images/emoji/closed_book.png
new file mode 100644
index 00000000000..6395cf2151e
--- /dev/null
+++ b/app/assets/images/emoji/closed_book.png
Binary files differ
diff --git a/app/assets/images/emoji/closed_lock_with_key.png b/app/assets/images/emoji/closed_lock_with_key.png
new file mode 100644
index 00000000000..1c1cd5d0741
--- /dev/null
+++ b/app/assets/images/emoji/closed_lock_with_key.png
Binary files differ
diff --git a/app/assets/images/emoji/closed_umbrella.png b/app/assets/images/emoji/closed_umbrella.png
new file mode 100644
index 00000000000..ecefba9e446
--- /dev/null
+++ b/app/assets/images/emoji/closed_umbrella.png
Binary files differ
diff --git a/app/assets/images/emoji/cloud.png b/app/assets/images/emoji/cloud.png
new file mode 100644
index 00000000000..5b4f57f77ba
--- /dev/null
+++ b/app/assets/images/emoji/cloud.png
Binary files differ
diff --git a/app/assets/images/emoji/cloud_lightning.png b/app/assets/images/emoji/cloud_lightning.png
new file mode 100644
index 00000000000..0831e88aa31
--- /dev/null
+++ b/app/assets/images/emoji/cloud_lightning.png
Binary files differ
diff --git a/app/assets/images/emoji/cloud_rain.png b/app/assets/images/emoji/cloud_rain.png
new file mode 100644
index 00000000000..385685e0512
--- /dev/null
+++ b/app/assets/images/emoji/cloud_rain.png
Binary files differ
diff --git a/app/assets/images/emoji/cloud_snow.png b/app/assets/images/emoji/cloud_snow.png
new file mode 100644
index 00000000000..9720384eb99
--- /dev/null
+++ b/app/assets/images/emoji/cloud_snow.png
Binary files differ
diff --git a/app/assets/images/emoji/cloud_tornado.png b/app/assets/images/emoji/cloud_tornado.png
new file mode 100644
index 00000000000..4821c89da1e
--- /dev/null
+++ b/app/assets/images/emoji/cloud_tornado.png
Binary files differ
diff --git a/app/assets/images/emoji/clown.png b/app/assets/images/emoji/clown.png
new file mode 100644
index 00000000000..02b7ff70049
--- /dev/null
+++ b/app/assets/images/emoji/clown.png
Binary files differ
diff --git a/app/assets/images/emoji/clubs.png b/app/assets/images/emoji/clubs.png
new file mode 100644
index 00000000000..4f2abf791ca
--- /dev/null
+++ b/app/assets/images/emoji/clubs.png
Binary files differ
diff --git a/app/assets/images/emoji/cocktail.png b/app/assets/images/emoji/cocktail.png
new file mode 100644
index 00000000000..2e50c57e98d
--- /dev/null
+++ b/app/assets/images/emoji/cocktail.png
Binary files differ
diff --git a/app/assets/images/emoji/coffee.png b/app/assets/images/emoji/coffee.png
new file mode 100644
index 00000000000..553061471b1
--- /dev/null
+++ b/app/assets/images/emoji/coffee.png
Binary files differ
diff --git a/app/assets/images/emoji/coffin.png b/app/assets/images/emoji/coffin.png
new file mode 100644
index 00000000000..fb2932aa5f6
--- /dev/null
+++ b/app/assets/images/emoji/coffin.png
Binary files differ
diff --git a/app/assets/images/emoji/cold_sweat.png b/app/assets/images/emoji/cold_sweat.png
new file mode 100644
index 00000000000..85b2231bbf6
--- /dev/null
+++ b/app/assets/images/emoji/cold_sweat.png
Binary files differ
diff --git a/app/assets/images/emoji/comet.png b/app/assets/images/emoji/comet.png
new file mode 100644
index 00000000000..a99751f79be
--- /dev/null
+++ b/app/assets/images/emoji/comet.png
Binary files differ
diff --git a/app/assets/images/emoji/compression.png b/app/assets/images/emoji/compression.png
new file mode 100644
index 00000000000..d7eda7f362a
--- /dev/null
+++ b/app/assets/images/emoji/compression.png
Binary files differ
diff --git a/app/assets/images/emoji/computer.png b/app/assets/images/emoji/computer.png
new file mode 100644
index 00000000000..c1fee27e3a9
--- /dev/null
+++ b/app/assets/images/emoji/computer.png
Binary files differ
diff --git a/app/assets/images/emoji/confetti_ball.png b/app/assets/images/emoji/confetti_ball.png
new file mode 100644
index 00000000000..ba4fd9b12be
--- /dev/null
+++ b/app/assets/images/emoji/confetti_ball.png
Binary files differ
diff --git a/app/assets/images/emoji/confounded.png b/app/assets/images/emoji/confounded.png
new file mode 100644
index 00000000000..aa4b29e9375
--- /dev/null
+++ b/app/assets/images/emoji/confounded.png
Binary files differ
diff --git a/app/assets/images/emoji/confused.png b/app/assets/images/emoji/confused.png
new file mode 100644
index 00000000000..502b6bf0e0b
--- /dev/null
+++ b/app/assets/images/emoji/confused.png
Binary files differ
diff --git a/app/assets/images/emoji/congratulations.png b/app/assets/images/emoji/congratulations.png
new file mode 100644
index 00000000000..ba8c89d95ee
--- /dev/null
+++ b/app/assets/images/emoji/congratulations.png
Binary files differ
diff --git a/app/assets/images/emoji/construction.png b/app/assets/images/emoji/construction.png
new file mode 100644
index 00000000000..ef8db5f471c
--- /dev/null
+++ b/app/assets/images/emoji/construction.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_site.png b/app/assets/images/emoji/construction_site.png
new file mode 100644
index 00000000000..8206a20f63f
--- /dev/null
+++ b/app/assets/images/emoji/construction_site.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_worker.png b/app/assets/images/emoji/construction_worker.png
new file mode 100644
index 00000000000..a9970a89005
--- /dev/null
+++ b/app/assets/images/emoji/construction_worker.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_worker_tone1.png b/app/assets/images/emoji/construction_worker_tone1.png
new file mode 100644
index 00000000000..2f24a2bab24
--- /dev/null
+++ b/app/assets/images/emoji/construction_worker_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_worker_tone2.png b/app/assets/images/emoji/construction_worker_tone2.png
new file mode 100644
index 00000000000..93c8fec5a75
--- /dev/null
+++ b/app/assets/images/emoji/construction_worker_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_worker_tone3.png b/app/assets/images/emoji/construction_worker_tone3.png
new file mode 100644
index 00000000000..abc1f2af2e0
--- /dev/null
+++ b/app/assets/images/emoji/construction_worker_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_worker_tone4.png b/app/assets/images/emoji/construction_worker_tone4.png
new file mode 100644
index 00000000000..eed83289aeb
--- /dev/null
+++ b/app/assets/images/emoji/construction_worker_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/construction_worker_tone5.png b/app/assets/images/emoji/construction_worker_tone5.png
new file mode 100644
index 00000000000..acbb220b8bb
--- /dev/null
+++ b/app/assets/images/emoji/construction_worker_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/control_knobs.png b/app/assets/images/emoji/control_knobs.png
new file mode 100644
index 00000000000..6635ac93b50
--- /dev/null
+++ b/app/assets/images/emoji/control_knobs.png
Binary files differ
diff --git a/app/assets/images/emoji/convenience_store.png b/app/assets/images/emoji/convenience_store.png
new file mode 100644
index 00000000000..26b53b5669e
--- /dev/null
+++ b/app/assets/images/emoji/convenience_store.png
Binary files differ
diff --git a/app/assets/images/emoji/cookie.png b/app/assets/images/emoji/cookie.png
new file mode 100644
index 00000000000..1b6bcb1554f
--- /dev/null
+++ b/app/assets/images/emoji/cookie.png
Binary files differ
diff --git a/app/assets/images/emoji/cooking.png b/app/assets/images/emoji/cooking.png
new file mode 100644
index 00000000000..918c980577a
--- /dev/null
+++ b/app/assets/images/emoji/cooking.png
Binary files differ
diff --git a/app/assets/images/emoji/cool.png b/app/assets/images/emoji/cool.png
new file mode 100644
index 00000000000..74674978d00
--- /dev/null
+++ b/app/assets/images/emoji/cool.png
Binary files differ
diff --git a/app/assets/images/emoji/cop.png b/app/assets/images/emoji/cop.png
new file mode 100644
index 00000000000..0b16d7c17b7
--- /dev/null
+++ b/app/assets/images/emoji/cop.png
Binary files differ
diff --git a/app/assets/images/emoji/cop_tone1.png b/app/assets/images/emoji/cop_tone1.png
new file mode 100644
index 00000000000..6ccba3879dc
--- /dev/null
+++ b/app/assets/images/emoji/cop_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/cop_tone2.png b/app/assets/images/emoji/cop_tone2.png
new file mode 100644
index 00000000000..7814ea9f52d
--- /dev/null
+++ b/app/assets/images/emoji/cop_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/cop_tone3.png b/app/assets/images/emoji/cop_tone3.png
new file mode 100644
index 00000000000..d78e88ec872
--- /dev/null
+++ b/app/assets/images/emoji/cop_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/cop_tone4.png b/app/assets/images/emoji/cop_tone4.png
new file mode 100644
index 00000000000..2e13c508315
--- /dev/null
+++ b/app/assets/images/emoji/cop_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/cop_tone5.png b/app/assets/images/emoji/cop_tone5.png
new file mode 100644
index 00000000000..2980d61cc2e
--- /dev/null
+++ b/app/assets/images/emoji/cop_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/copyright.png b/app/assets/images/emoji/copyright.png
new file mode 100644
index 00000000000..6b9a6adbfd2
--- /dev/null
+++ b/app/assets/images/emoji/copyright.png
Binary files differ
diff --git a/app/assets/images/emoji/corn.png b/app/assets/images/emoji/corn.png
new file mode 100644
index 00000000000..36e20127931
--- /dev/null
+++ b/app/assets/images/emoji/corn.png
Binary files differ
diff --git a/app/assets/images/emoji/couch.png b/app/assets/images/emoji/couch.png
new file mode 100644
index 00000000000..27b19b13bb0
--- /dev/null
+++ b/app/assets/images/emoji/couch.png
Binary files differ
diff --git a/app/assets/images/emoji/couple.png b/app/assets/images/emoji/couple.png
new file mode 100644
index 00000000000..960323f3c16
--- /dev/null
+++ b/app/assets/images/emoji/couple.png
Binary files differ
diff --git a/app/assets/images/emoji/couple_mm.png b/app/assets/images/emoji/couple_mm.png
new file mode 100644
index 00000000000..8759fa5db87
--- /dev/null
+++ b/app/assets/images/emoji/couple_mm.png
Binary files differ
diff --git a/app/assets/images/emoji/couple_with_heart.png b/app/assets/images/emoji/couple_with_heart.png
new file mode 100644
index 00000000000..62111601b36
--- /dev/null
+++ b/app/assets/images/emoji/couple_with_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/couple_ww.png b/app/assets/images/emoji/couple_ww.png
new file mode 100644
index 00000000000..08fdabcdc5c
--- /dev/null
+++ b/app/assets/images/emoji/couple_ww.png
Binary files differ
diff --git a/app/assets/images/emoji/couplekiss.png b/app/assets/images/emoji/couplekiss.png
new file mode 100644
index 00000000000..9aa519da9e8
--- /dev/null
+++ b/app/assets/images/emoji/couplekiss.png
Binary files differ
diff --git a/app/assets/images/emoji/cow.png b/app/assets/images/emoji/cow.png
new file mode 100644
index 00000000000..718a3986d64
--- /dev/null
+++ b/app/assets/images/emoji/cow.png
Binary files differ
diff --git a/app/assets/images/emoji/cow2.png b/app/assets/images/emoji/cow2.png
new file mode 100644
index 00000000000..4d0ca534ff1
--- /dev/null
+++ b/app/assets/images/emoji/cow2.png
Binary files differ
diff --git a/app/assets/images/emoji/cowboy.png b/app/assets/images/emoji/cowboy.png
new file mode 100644
index 00000000000..70dd5d0d9d1
--- /dev/null
+++ b/app/assets/images/emoji/cowboy.png
Binary files differ
diff --git a/app/assets/images/emoji/crab.png b/app/assets/images/emoji/crab.png
new file mode 100644
index 00000000000..19f3047ab61
--- /dev/null
+++ b/app/assets/images/emoji/crab.png
Binary files differ
diff --git a/app/assets/images/emoji/crayon.png b/app/assets/images/emoji/crayon.png
new file mode 100644
index 00000000000..8d7b427aaa3
--- /dev/null
+++ b/app/assets/images/emoji/crayon.png
Binary files differ
diff --git a/app/assets/images/emoji/credit_card.png b/app/assets/images/emoji/credit_card.png
new file mode 100644
index 00000000000..372777d5c61
--- /dev/null
+++ b/app/assets/images/emoji/credit_card.png
Binary files differ
diff --git a/app/assets/images/emoji/crescent_moon.png b/app/assets/images/emoji/crescent_moon.png
new file mode 100644
index 00000000000..765420ecec7
--- /dev/null
+++ b/app/assets/images/emoji/crescent_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/cricket.png b/app/assets/images/emoji/cricket.png
new file mode 100644
index 00000000000..d602294a2cd
--- /dev/null
+++ b/app/assets/images/emoji/cricket.png
Binary files differ
diff --git a/app/assets/images/emoji/crocodile.png b/app/assets/images/emoji/crocodile.png
new file mode 100644
index 00000000000..3005c46f176
--- /dev/null
+++ b/app/assets/images/emoji/crocodile.png
Binary files differ
diff --git a/app/assets/images/emoji/croissant.png b/app/assets/images/emoji/croissant.png
new file mode 100644
index 00000000000..fb33feb1a38
--- /dev/null
+++ b/app/assets/images/emoji/croissant.png
Binary files differ
diff --git a/app/assets/images/emoji/cross.png b/app/assets/images/emoji/cross.png
new file mode 100644
index 00000000000..42b10e82257
--- /dev/null
+++ b/app/assets/images/emoji/cross.png
Binary files differ
diff --git a/app/assets/images/emoji/crossed_flags.png b/app/assets/images/emoji/crossed_flags.png
new file mode 100644
index 00000000000..273bd0f0fe5
--- /dev/null
+++ b/app/assets/images/emoji/crossed_flags.png
Binary files differ
diff --git a/app/assets/images/emoji/crossed_swords.png b/app/assets/images/emoji/crossed_swords.png
new file mode 100644
index 00000000000..907e9607134
--- /dev/null
+++ b/app/assets/images/emoji/crossed_swords.png
Binary files differ
diff --git a/app/assets/images/emoji/crown.png b/app/assets/images/emoji/crown.png
new file mode 100644
index 00000000000..93b82d92f04
--- /dev/null
+++ b/app/assets/images/emoji/crown.png
Binary files differ
diff --git a/app/assets/images/emoji/cruise_ship.png b/app/assets/images/emoji/cruise_ship.png
new file mode 100644
index 00000000000..19d4acbe40c
--- /dev/null
+++ b/app/assets/images/emoji/cruise_ship.png
Binary files differ
diff --git a/app/assets/images/emoji/cry.png b/app/assets/images/emoji/cry.png
new file mode 100644
index 00000000000..b7877f8a173
--- /dev/null
+++ b/app/assets/images/emoji/cry.png
Binary files differ
diff --git a/app/assets/images/emoji/crying_cat_face.png b/app/assets/images/emoji/crying_cat_face.png
new file mode 100644
index 00000000000..b4f49715e00
--- /dev/null
+++ b/app/assets/images/emoji/crying_cat_face.png
Binary files differ
diff --git a/app/assets/images/emoji/crystal_ball.png b/app/assets/images/emoji/crystal_ball.png
new file mode 100644
index 00000000000..485d5c888f1
--- /dev/null
+++ b/app/assets/images/emoji/crystal_ball.png
Binary files differ
diff --git a/app/assets/images/emoji/cucumber.png b/app/assets/images/emoji/cucumber.png
new file mode 100644
index 00000000000..500807059d2
--- /dev/null
+++ b/app/assets/images/emoji/cucumber.png
Binary files differ
diff --git a/app/assets/images/emoji/cupid.png b/app/assets/images/emoji/cupid.png
new file mode 100644
index 00000000000..2df0078ddd1
--- /dev/null
+++ b/app/assets/images/emoji/cupid.png
Binary files differ
diff --git a/app/assets/images/emoji/curly_loop.png b/app/assets/images/emoji/curly_loop.png
new file mode 100644
index 00000000000..440aa56d50e
--- /dev/null
+++ b/app/assets/images/emoji/curly_loop.png
Binary files differ
diff --git a/app/assets/images/emoji/currency_exchange.png b/app/assets/images/emoji/currency_exchange.png
new file mode 100644
index 00000000000..4d46c6050e7
--- /dev/null
+++ b/app/assets/images/emoji/currency_exchange.png
Binary files differ
diff --git a/app/assets/images/emoji/curry.png b/app/assets/images/emoji/curry.png
new file mode 100644
index 00000000000..69657ca8103
--- /dev/null
+++ b/app/assets/images/emoji/curry.png
Binary files differ
diff --git a/app/assets/images/emoji/custard.png b/app/assets/images/emoji/custard.png
new file mode 100644
index 00000000000..fa3df67b8f6
--- /dev/null
+++ b/app/assets/images/emoji/custard.png
Binary files differ
diff --git a/app/assets/images/emoji/customs.png b/app/assets/images/emoji/customs.png
new file mode 100644
index 00000000000..21b7ce2c69e
--- /dev/null
+++ b/app/assets/images/emoji/customs.png
Binary files differ
diff --git a/app/assets/images/emoji/cyclone.png b/app/assets/images/emoji/cyclone.png
new file mode 100644
index 00000000000..ff00b1afe70
--- /dev/null
+++ b/app/assets/images/emoji/cyclone.png
Binary files differ
diff --git a/app/assets/images/emoji/dagger.png b/app/assets/images/emoji/dagger.png
new file mode 100644
index 00000000000..66e97b0aa25
--- /dev/null
+++ b/app/assets/images/emoji/dagger.png
Binary files differ
diff --git a/app/assets/images/emoji/dancer.png b/app/assets/images/emoji/dancer.png
new file mode 100644
index 00000000000..04b166991cb
--- /dev/null
+++ b/app/assets/images/emoji/dancer.png
Binary files differ
diff --git a/app/assets/images/emoji/dancer_tone1.png b/app/assets/images/emoji/dancer_tone1.png
new file mode 100644
index 00000000000..2c7b11c3a6e
--- /dev/null
+++ b/app/assets/images/emoji/dancer_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/dancer_tone2.png b/app/assets/images/emoji/dancer_tone2.png
new file mode 100644
index 00000000000..cb04b1f907e
--- /dev/null
+++ b/app/assets/images/emoji/dancer_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/dancer_tone3.png b/app/assets/images/emoji/dancer_tone3.png
new file mode 100644
index 00000000000..98c5bca7b64
--- /dev/null
+++ b/app/assets/images/emoji/dancer_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/dancer_tone4.png b/app/assets/images/emoji/dancer_tone4.png
new file mode 100644
index 00000000000..fdb1e00cbba
--- /dev/null
+++ b/app/assets/images/emoji/dancer_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/dancer_tone5.png b/app/assets/images/emoji/dancer_tone5.png
new file mode 100644
index 00000000000..0e34e0e23f0
--- /dev/null
+++ b/app/assets/images/emoji/dancer_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/dancers.png b/app/assets/images/emoji/dancers.png
new file mode 100644
index 00000000000..67e6ffacb76
--- /dev/null
+++ b/app/assets/images/emoji/dancers.png
Binary files differ
diff --git a/app/assets/images/emoji/dango.png b/app/assets/images/emoji/dango.png
new file mode 100644
index 00000000000..f73f37b01c7
--- /dev/null
+++ b/app/assets/images/emoji/dango.png
Binary files differ
diff --git a/app/assets/images/emoji/dark_sunglasses.png b/app/assets/images/emoji/dark_sunglasses.png
new file mode 100644
index 00000000000..b1b6db0acff
--- /dev/null
+++ b/app/assets/images/emoji/dark_sunglasses.png
Binary files differ
diff --git a/app/assets/images/emoji/dart.png b/app/assets/images/emoji/dart.png
new file mode 100644
index 00000000000..f6704aeb8ba
--- /dev/null
+++ b/app/assets/images/emoji/dart.png
Binary files differ
diff --git a/app/assets/images/emoji/dash.png b/app/assets/images/emoji/dash.png
new file mode 100644
index 00000000000..064b8525c12
--- /dev/null
+++ b/app/assets/images/emoji/dash.png
Binary files differ
diff --git a/app/assets/images/emoji/date.png b/app/assets/images/emoji/date.png
new file mode 100644
index 00000000000..f05b3da97b8
--- /dev/null
+++ b/app/assets/images/emoji/date.png
Binary files differ
diff --git a/app/assets/images/emoji/deciduous_tree.png b/app/assets/images/emoji/deciduous_tree.png
new file mode 100644
index 00000000000..785fc1c30ea
--- /dev/null
+++ b/app/assets/images/emoji/deciduous_tree.png
Binary files differ
diff --git a/app/assets/images/emoji/deer.png b/app/assets/images/emoji/deer.png
new file mode 100644
index 00000000000..d8698195ff0
--- /dev/null
+++ b/app/assets/images/emoji/deer.png
Binary files differ
diff --git a/app/assets/images/emoji/department_store.png b/app/assets/images/emoji/department_store.png
new file mode 100644
index 00000000000..58867c7a6e1
--- /dev/null
+++ b/app/assets/images/emoji/department_store.png
Binary files differ
diff --git a/app/assets/images/emoji/desert.png b/app/assets/images/emoji/desert.png
new file mode 100644
index 00000000000..e9966ff8c65
--- /dev/null
+++ b/app/assets/images/emoji/desert.png
Binary files differ
diff --git a/app/assets/images/emoji/desktop.png b/app/assets/images/emoji/desktop.png
new file mode 100644
index 00000000000..909bd42b5e1
--- /dev/null
+++ b/app/assets/images/emoji/desktop.png
Binary files differ
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
new file mode 100644
index 00000000000..2a22a26d1e2
--- /dev/null
+++ b/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png
Binary files differ
diff --git a/app/assets/images/emoji/diamonds.png b/app/assets/images/emoji/diamonds.png
new file mode 100644
index 00000000000..1f25f51f97a
--- /dev/null
+++ b/app/assets/images/emoji/diamonds.png
Binary files differ
diff --git a/app/assets/images/emoji/disappointed.png b/app/assets/images/emoji/disappointed.png
new file mode 100644
index 00000000000..efe4e67e23c
--- /dev/null
+++ b/app/assets/images/emoji/disappointed.png
Binary files differ
diff --git a/app/assets/images/emoji/disappointed_relieved.png b/app/assets/images/emoji/disappointed_relieved.png
new file mode 100644
index 00000000000..aef864d2b3d
--- /dev/null
+++ b/app/assets/images/emoji/disappointed_relieved.png
Binary files differ
diff --git a/app/assets/images/emoji/dividers.png b/app/assets/images/emoji/dividers.png
new file mode 100644
index 00000000000..46a7e403f9d
--- /dev/null
+++ b/app/assets/images/emoji/dividers.png
Binary files differ
diff --git a/app/assets/images/emoji/dizzy.png b/app/assets/images/emoji/dizzy.png
new file mode 100644
index 00000000000..85f52efad24
--- /dev/null
+++ b/app/assets/images/emoji/dizzy.png
Binary files differ
diff --git a/app/assets/images/emoji/dizzy_face.png b/app/assets/images/emoji/dizzy_face.png
new file mode 100644
index 00000000000..3120316ab5e
--- /dev/null
+++ b/app/assets/images/emoji/dizzy_face.png
Binary files differ
diff --git a/app/assets/images/emoji/do_not_litter.png b/app/assets/images/emoji/do_not_litter.png
new file mode 100644
index 00000000000..341d2575f4f
--- /dev/null
+++ b/app/assets/images/emoji/do_not_litter.png
Binary files differ
diff --git a/app/assets/images/emoji/dog.png b/app/assets/images/emoji/dog.png
new file mode 100644
index 00000000000..281b81d58bd
--- /dev/null
+++ b/app/assets/images/emoji/dog.png
Binary files differ
diff --git a/app/assets/images/emoji/dog2.png b/app/assets/images/emoji/dog2.png
new file mode 100644
index 00000000000..976143dbdbe
--- /dev/null
+++ b/app/assets/images/emoji/dog2.png
Binary files differ
diff --git a/app/assets/images/emoji/dollar.png b/app/assets/images/emoji/dollar.png
new file mode 100644
index 00000000000..a9904c28293
--- /dev/null
+++ b/app/assets/images/emoji/dollar.png
Binary files differ
diff --git a/app/assets/images/emoji/dolls.png b/app/assets/images/emoji/dolls.png
new file mode 100644
index 00000000000..10955615110
--- /dev/null
+++ b/app/assets/images/emoji/dolls.png
Binary files differ
diff --git a/app/assets/images/emoji/dolphin.png b/app/assets/images/emoji/dolphin.png
new file mode 100644
index 00000000000..81434809003
--- /dev/null
+++ b/app/assets/images/emoji/dolphin.png
Binary files differ
diff --git a/app/assets/images/emoji/door.png b/app/assets/images/emoji/door.png
new file mode 100644
index 00000000000..36ae3e27494
--- /dev/null
+++ b/app/assets/images/emoji/door.png
Binary files differ
diff --git a/app/assets/images/emoji/doughnut.png b/app/assets/images/emoji/doughnut.png
new file mode 100644
index 00000000000..0ca4cd0bde8
--- /dev/null
+++ b/app/assets/images/emoji/doughnut.png
Binary files differ
diff --git a/app/assets/images/emoji/dove.png b/app/assets/images/emoji/dove.png
new file mode 100644
index 00000000000..9580c4917d7
--- /dev/null
+++ b/app/assets/images/emoji/dove.png
Binary files differ
diff --git a/app/assets/images/emoji/dragon.png b/app/assets/images/emoji/dragon.png
new file mode 100644
index 00000000000..d6311cf5429
--- /dev/null
+++ b/app/assets/images/emoji/dragon.png
Binary files differ
diff --git a/app/assets/images/emoji/dragon_face.png b/app/assets/images/emoji/dragon_face.png
new file mode 100644
index 00000000000..3c2720446c6
--- /dev/null
+++ b/app/assets/images/emoji/dragon_face.png
Binary files differ
diff --git a/app/assets/images/emoji/dress.png b/app/assets/images/emoji/dress.png
new file mode 100644
index 00000000000..a697ca5c57d
--- /dev/null
+++ b/app/assets/images/emoji/dress.png
Binary files differ
diff --git a/app/assets/images/emoji/dromedary_camel.png b/app/assets/images/emoji/dromedary_camel.png
new file mode 100644
index 00000000000..5271637c7c4
--- /dev/null
+++ b/app/assets/images/emoji/dromedary_camel.png
Binary files differ
diff --git a/app/assets/images/emoji/drooling_face.png b/app/assets/images/emoji/drooling_face.png
new file mode 100644
index 00000000000..a5460532597
--- /dev/null
+++ b/app/assets/images/emoji/drooling_face.png
Binary files differ
diff --git a/app/assets/images/emoji/droplet.png b/app/assets/images/emoji/droplet.png
new file mode 100644
index 00000000000..71241ec3061
--- /dev/null
+++ b/app/assets/images/emoji/droplet.png
Binary files differ
diff --git a/app/assets/images/emoji/drum.png b/app/assets/images/emoji/drum.png
new file mode 100644
index 00000000000..b038727cc99
--- /dev/null
+++ b/app/assets/images/emoji/drum.png
Binary files differ
diff --git a/app/assets/images/emoji/duck.png b/app/assets/images/emoji/duck.png
new file mode 100644
index 00000000000..74330b77ca3
--- /dev/null
+++ b/app/assets/images/emoji/duck.png
Binary files differ
diff --git a/app/assets/images/emoji/dvd.png b/app/assets/images/emoji/dvd.png
new file mode 100644
index 00000000000..045a6f7a08d
--- /dev/null
+++ b/app/assets/images/emoji/dvd.png
Binary files differ
diff --git a/app/assets/images/emoji/e-mail.png b/app/assets/images/emoji/e-mail.png
new file mode 100644
index 00000000000..d22e654a20b
--- /dev/null
+++ b/app/assets/images/emoji/e-mail.png
Binary files differ
diff --git a/app/assets/images/emoji/eagle.png b/app/assets/images/emoji/eagle.png
new file mode 100644
index 00000000000..4f277debeef
--- /dev/null
+++ b/app/assets/images/emoji/eagle.png
Binary files differ
diff --git a/app/assets/images/emoji/ear.png b/app/assets/images/emoji/ear.png
new file mode 100644
index 00000000000..f84f9ff154a
--- /dev/null
+++ b/app/assets/images/emoji/ear.png
Binary files differ
diff --git a/app/assets/images/emoji/ear_of_rice.png b/app/assets/images/emoji/ear_of_rice.png
new file mode 100644
index 00000000000..3564d9d643a
--- /dev/null
+++ b/app/assets/images/emoji/ear_of_rice.png
Binary files differ
diff --git a/app/assets/images/emoji/ear_tone1.png b/app/assets/images/emoji/ear_tone1.png
new file mode 100644
index 00000000000..d09e1e41996
--- /dev/null
+++ b/app/assets/images/emoji/ear_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/ear_tone2.png b/app/assets/images/emoji/ear_tone2.png
new file mode 100644
index 00000000000..300d60a9948
--- /dev/null
+++ b/app/assets/images/emoji/ear_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/ear_tone3.png b/app/assets/images/emoji/ear_tone3.png
new file mode 100644
index 00000000000..2a56eebe445
--- /dev/null
+++ b/app/assets/images/emoji/ear_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/ear_tone4.png b/app/assets/images/emoji/ear_tone4.png
new file mode 100644
index 00000000000..bd270f7763e
--- /dev/null
+++ b/app/assets/images/emoji/ear_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/ear_tone5.png b/app/assets/images/emoji/ear_tone5.png
new file mode 100644
index 00000000000..b96bb441dff
--- /dev/null
+++ b/app/assets/images/emoji/ear_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/earth_africa.png b/app/assets/images/emoji/earth_africa.png
new file mode 100644
index 00000000000..66c3348c23a
--- /dev/null
+++ b/app/assets/images/emoji/earth_africa.png
Binary files differ
diff --git a/app/assets/images/emoji/earth_americas.png b/app/assets/images/emoji/earth_americas.png
new file mode 100644
index 00000000000..538c3cddd68
--- /dev/null
+++ b/app/assets/images/emoji/earth_americas.png
Binary files differ
diff --git a/app/assets/images/emoji/earth_asia.png b/app/assets/images/emoji/earth_asia.png
new file mode 100644
index 00000000000..d8df97fec3c
--- /dev/null
+++ b/app/assets/images/emoji/earth_asia.png
Binary files differ
diff --git a/app/assets/images/emoji/egg.png b/app/assets/images/emoji/egg.png
new file mode 100644
index 00000000000..c171974d993
--- /dev/null
+++ b/app/assets/images/emoji/egg.png
Binary files differ
diff --git a/app/assets/images/emoji/eggplant.png b/app/assets/images/emoji/eggplant.png
new file mode 100644
index 00000000000..fafd7c1a14c
--- /dev/null
+++ b/app/assets/images/emoji/eggplant.png
Binary files differ
diff --git a/app/assets/images/emoji/eight.png b/app/assets/images/emoji/eight.png
new file mode 100644
index 00000000000..8c95874d4c5
--- /dev/null
+++ b/app/assets/images/emoji/eight.png
Binary files differ
diff --git a/app/assets/images/emoji/eight_pointed_black_star.png b/app/assets/images/emoji/eight_pointed_black_star.png
new file mode 100644
index 00000000000..820179bda50
--- /dev/null
+++ b/app/assets/images/emoji/eight_pointed_black_star.png
Binary files differ
diff --git a/app/assets/images/emoji/eight_spoked_asterisk.png b/app/assets/images/emoji/eight_spoked_asterisk.png
new file mode 100644
index 00000000000..3307ffa62ee
--- /dev/null
+++ b/app/assets/images/emoji/eight_spoked_asterisk.png
Binary files differ
diff --git a/app/assets/images/emoji/eject.png b/app/assets/images/emoji/eject.png
new file mode 100644
index 00000000000..ec5cfc48973
--- /dev/null
+++ b/app/assets/images/emoji/eject.png
Binary files differ
diff --git a/app/assets/images/emoji/electric_plug.png b/app/assets/images/emoji/electric_plug.png
new file mode 100644
index 00000000000..31d1eb215b4
--- /dev/null
+++ b/app/assets/images/emoji/electric_plug.png
Binary files differ
diff --git a/app/assets/images/emoji/elephant.png b/app/assets/images/emoji/elephant.png
new file mode 100644
index 00000000000..b8a6d140595
--- /dev/null
+++ b/app/assets/images/emoji/elephant.png
Binary files differ
diff --git a/app/assets/images/emoji/end.png b/app/assets/images/emoji/end.png
new file mode 100644
index 00000000000..ef3ccd5f367
--- /dev/null
+++ b/app/assets/images/emoji/end.png
Binary files differ
diff --git a/app/assets/images/emoji/envelope.png b/app/assets/images/emoji/envelope.png
new file mode 100644
index 00000000000..ec77ac375a4
--- /dev/null
+++ b/app/assets/images/emoji/envelope.png
Binary files differ
diff --git a/app/assets/images/emoji/envelope_with_arrow.png b/app/assets/images/emoji/envelope_with_arrow.png
new file mode 100644
index 00000000000..7448a6b7673
--- /dev/null
+++ b/app/assets/images/emoji/envelope_with_arrow.png
Binary files differ
diff --git a/app/assets/images/emoji/euro.png b/app/assets/images/emoji/euro.png
new file mode 100644
index 00000000000..a49020820e1
--- /dev/null
+++ b/app/assets/images/emoji/euro.png
Binary files differ
diff --git a/app/assets/images/emoji/european_castle.png b/app/assets/images/emoji/european_castle.png
new file mode 100644
index 00000000000..888d11332ce
--- /dev/null
+++ b/app/assets/images/emoji/european_castle.png
Binary files differ
diff --git a/app/assets/images/emoji/european_post_office.png b/app/assets/images/emoji/european_post_office.png
new file mode 100644
index 00000000000..3745aff8dd2
--- /dev/null
+++ b/app/assets/images/emoji/european_post_office.png
Binary files differ
diff --git a/app/assets/images/emoji/evergreen_tree.png b/app/assets/images/emoji/evergreen_tree.png
new file mode 100644
index 00000000000..f679d8dd772
--- /dev/null
+++ b/app/assets/images/emoji/evergreen_tree.png
Binary files differ
diff --git a/app/assets/images/emoji/exclamation.png b/app/assets/images/emoji/exclamation.png
new file mode 100644
index 00000000000..2c14406422f
--- /dev/null
+++ b/app/assets/images/emoji/exclamation.png
Binary files differ
diff --git a/app/assets/images/emoji/expressionless.png b/app/assets/images/emoji/expressionless.png
new file mode 100644
index 00000000000..2954017f6c2
--- /dev/null
+++ b/app/assets/images/emoji/expressionless.png
Binary files differ
diff --git a/app/assets/images/emoji/eye.png b/app/assets/images/emoji/eye.png
new file mode 100644
index 00000000000..9d989cdd375
--- /dev/null
+++ b/app/assets/images/emoji/eye.png
Binary files differ
diff --git a/app/assets/images/emoji/eye_in_speech_bubble.png b/app/assets/images/emoji/eye_in_speech_bubble.png
new file mode 100644
index 00000000000..21bd22bbcce
--- /dev/null
+++ b/app/assets/images/emoji/eye_in_speech_bubble.png
Binary files differ
diff --git a/app/assets/images/emoji/eyeglasses.png b/app/assets/images/emoji/eyeglasses.png
new file mode 100644
index 00000000000..865d8274acf
--- /dev/null
+++ b/app/assets/images/emoji/eyeglasses.png
Binary files differ
diff --git a/app/assets/images/emoji/eyes.png b/app/assets/images/emoji/eyes.png
new file mode 100644
index 00000000000..2102ada7e09
--- /dev/null
+++ b/app/assets/images/emoji/eyes.png
Binary files differ
diff --git a/app/assets/images/emoji/face_palm.png b/app/assets/images/emoji/face_palm.png
new file mode 100644
index 00000000000..defc796cf16
--- /dev/null
+++ b/app/assets/images/emoji/face_palm.png
Binary files differ
diff --git a/app/assets/images/emoji/face_palm_tone1.png b/app/assets/images/emoji/face_palm_tone1.png
new file mode 100644
index 00000000000..2f4b010bb40
--- /dev/null
+++ b/app/assets/images/emoji/face_palm_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/face_palm_tone2.png b/app/assets/images/emoji/face_palm_tone2.png
new file mode 100644
index 00000000000..97fb6831687
--- /dev/null
+++ b/app/assets/images/emoji/face_palm_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/face_palm_tone3.png b/app/assets/images/emoji/face_palm_tone3.png
new file mode 100644
index 00000000000..b5b5c1e5306
--- /dev/null
+++ b/app/assets/images/emoji/face_palm_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/face_palm_tone4.png b/app/assets/images/emoji/face_palm_tone4.png
new file mode 100644
index 00000000000..2840b113483
--- /dev/null
+++ b/app/assets/images/emoji/face_palm_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/face_palm_tone5.png b/app/assets/images/emoji/face_palm_tone5.png
new file mode 100644
index 00000000000..6f070db98be
--- /dev/null
+++ b/app/assets/images/emoji/face_palm_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/factory.png b/app/assets/images/emoji/factory.png
new file mode 100644
index 00000000000..e1d2ddf4a27
--- /dev/null
+++ b/app/assets/images/emoji/factory.png
Binary files differ
diff --git a/app/assets/images/emoji/fallen_leaf.png b/app/assets/images/emoji/fallen_leaf.png
new file mode 100644
index 00000000000..0d60e7bdf2d
--- /dev/null
+++ b/app/assets/images/emoji/fallen_leaf.png
Binary files differ
diff --git a/app/assets/images/emoji/family.png b/app/assets/images/emoji/family.png
new file mode 100644
index 00000000000..26421965791
--- /dev/null
+++ b/app/assets/images/emoji/family.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mmb.png b/app/assets/images/emoji/family_mmb.png
new file mode 100644
index 00000000000..7a2e4e2c491
--- /dev/null
+++ b/app/assets/images/emoji/family_mmb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mmbb.png b/app/assets/images/emoji/family_mmbb.png
new file mode 100644
index 00000000000..81e6c0fc0ee
--- /dev/null
+++ b/app/assets/images/emoji/family_mmbb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mmg.png b/app/assets/images/emoji/family_mmg.png
new file mode 100644
index 00000000000..932a85e1fe5
--- /dev/null
+++ b/app/assets/images/emoji/family_mmg.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mmgb.png b/app/assets/images/emoji/family_mmgb.png
new file mode 100644
index 00000000000..41e35166670
--- /dev/null
+++ b/app/assets/images/emoji/family_mmgb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mmgg.png b/app/assets/images/emoji/family_mmgg.png
new file mode 100644
index 00000000000..8e8ccfe6c7f
--- /dev/null
+++ b/app/assets/images/emoji/family_mmgg.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mwbb.png b/app/assets/images/emoji/family_mwbb.png
new file mode 100644
index 00000000000..b544fbe573f
--- /dev/null
+++ b/app/assets/images/emoji/family_mwbb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mwg.png b/app/assets/images/emoji/family_mwg.png
new file mode 100644
index 00000000000..71d2681c32a
--- /dev/null
+++ b/app/assets/images/emoji/family_mwg.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mwgb.png b/app/assets/images/emoji/family_mwgb.png
new file mode 100644
index 00000000000..40dbf1f7a18
--- /dev/null
+++ b/app/assets/images/emoji/family_mwgb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_mwgg.png b/app/assets/images/emoji/family_mwgg.png
new file mode 100644
index 00000000000..bfefa4879cb
--- /dev/null
+++ b/app/assets/images/emoji/family_mwgg.png
Binary files differ
diff --git a/app/assets/images/emoji/family_wwb.png b/app/assets/images/emoji/family_wwb.png
new file mode 100644
index 00000000000..836feae7c78
--- /dev/null
+++ b/app/assets/images/emoji/family_wwb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_wwbb.png b/app/assets/images/emoji/family_wwbb.png
new file mode 100644
index 00000000000..6c6ba45e7bb
--- /dev/null
+++ b/app/assets/images/emoji/family_wwbb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_wwg.png b/app/assets/images/emoji/family_wwg.png
new file mode 100644
index 00000000000..41225c6fa5a
--- /dev/null
+++ b/app/assets/images/emoji/family_wwg.png
Binary files differ
diff --git a/app/assets/images/emoji/family_wwgb.png b/app/assets/images/emoji/family_wwgb.png
new file mode 100644
index 00000000000..284d29ab5da
--- /dev/null
+++ b/app/assets/images/emoji/family_wwgb.png
Binary files differ
diff --git a/app/assets/images/emoji/family_wwgg.png b/app/assets/images/emoji/family_wwgg.png
new file mode 100644
index 00000000000..d8d3f49b85f
--- /dev/null
+++ b/app/assets/images/emoji/family_wwgg.png
Binary files differ
diff --git a/app/assets/images/emoji/fast_forward.png b/app/assets/images/emoji/fast_forward.png
new file mode 100644
index 00000000000..c406fedfdb1
--- /dev/null
+++ b/app/assets/images/emoji/fast_forward.png
Binary files differ
diff --git a/app/assets/images/emoji/fax.png b/app/assets/images/emoji/fax.png
new file mode 100644
index 00000000000..6f929e294c2
--- /dev/null
+++ b/app/assets/images/emoji/fax.png
Binary files differ
diff --git a/app/assets/images/emoji/fearful.png b/app/assets/images/emoji/fearful.png
new file mode 100644
index 00000000000..eb8b347cef9
--- /dev/null
+++ b/app/assets/images/emoji/fearful.png
Binary files differ
diff --git a/app/assets/images/emoji/feet.png b/app/assets/images/emoji/feet.png
new file mode 100644
index 00000000000..5fe568cee93
--- /dev/null
+++ b/app/assets/images/emoji/feet.png
Binary files differ
diff --git a/app/assets/images/emoji/fencer.png b/app/assets/images/emoji/fencer.png
new file mode 100644
index 00000000000..5288c920eb9
--- /dev/null
+++ b/app/assets/images/emoji/fencer.png
Binary files differ
diff --git a/app/assets/images/emoji/ferris_wheel.png b/app/assets/images/emoji/ferris_wheel.png
new file mode 100644
index 00000000000..55c8ff0475b
--- /dev/null
+++ b/app/assets/images/emoji/ferris_wheel.png
Binary files differ
diff --git a/app/assets/images/emoji/ferry.png b/app/assets/images/emoji/ferry.png
new file mode 100644
index 00000000000..41816b3ae34
--- /dev/null
+++ b/app/assets/images/emoji/ferry.png
Binary files differ
diff --git a/app/assets/images/emoji/field_hockey.png b/app/assets/images/emoji/field_hockey.png
new file mode 100644
index 00000000000..839637716ee
--- /dev/null
+++ b/app/assets/images/emoji/field_hockey.png
Binary files differ
diff --git a/app/assets/images/emoji/file_cabinet.png b/app/assets/images/emoji/file_cabinet.png
new file mode 100644
index 00000000000..fddc65dde96
--- /dev/null
+++ b/app/assets/images/emoji/file_cabinet.png
Binary files differ
diff --git a/app/assets/images/emoji/file_folder.png b/app/assets/images/emoji/file_folder.png
new file mode 100644
index 00000000000..addedaf0870
--- /dev/null
+++ b/app/assets/images/emoji/file_folder.png
Binary files differ
diff --git a/app/assets/images/emoji/film_frames.png b/app/assets/images/emoji/film_frames.png
new file mode 100644
index 00000000000..30143aedbe6
--- /dev/null
+++ b/app/assets/images/emoji/film_frames.png
Binary files differ
diff --git a/app/assets/images/emoji/fingers_crossed.png b/app/assets/images/emoji/fingers_crossed.png
new file mode 100644
index 00000000000..4cd18514ea3
--- /dev/null
+++ b/app/assets/images/emoji/fingers_crossed.png
Binary files differ
diff --git a/app/assets/images/emoji/fingers_crossed_tone1.png b/app/assets/images/emoji/fingers_crossed_tone1.png
new file mode 100644
index 00000000000..dd2384a6cd5
--- /dev/null
+++ b/app/assets/images/emoji/fingers_crossed_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/fingers_crossed_tone2.png b/app/assets/images/emoji/fingers_crossed_tone2.png
new file mode 100644
index 00000000000..6228401befe
--- /dev/null
+++ b/app/assets/images/emoji/fingers_crossed_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/fingers_crossed_tone3.png b/app/assets/images/emoji/fingers_crossed_tone3.png
new file mode 100644
index 00000000000..b1074da15f5
--- /dev/null
+++ b/app/assets/images/emoji/fingers_crossed_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/fingers_crossed_tone4.png b/app/assets/images/emoji/fingers_crossed_tone4.png
new file mode 100644
index 00000000000..75e05e4d332
--- /dev/null
+++ b/app/assets/images/emoji/fingers_crossed_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/fingers_crossed_tone5.png b/app/assets/images/emoji/fingers_crossed_tone5.png
new file mode 100644
index 00000000000..761aebdc30f
--- /dev/null
+++ b/app/assets/images/emoji/fingers_crossed_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/fire.png b/app/assets/images/emoji/fire.png
new file mode 100644
index 00000000000..bd3775a460b
--- /dev/null
+++ b/app/assets/images/emoji/fire.png
Binary files differ
diff --git a/app/assets/images/emoji/fire_engine.png b/app/assets/images/emoji/fire_engine.png
new file mode 100644
index 00000000000..2cd45b7cf7e
--- /dev/null
+++ b/app/assets/images/emoji/fire_engine.png
Binary files differ
diff --git a/app/assets/images/emoji/fireworks.png b/app/assets/images/emoji/fireworks.png
new file mode 100644
index 00000000000..176c8b58265
--- /dev/null
+++ b/app/assets/images/emoji/fireworks.png
Binary files differ
diff --git a/app/assets/images/emoji/first_place.png b/app/assets/images/emoji/first_place.png
new file mode 100644
index 00000000000..15612b66492
--- /dev/null
+++ b/app/assets/images/emoji/first_place.png
Binary files differ
diff --git a/app/assets/images/emoji/first_quarter_moon.png b/app/assets/images/emoji/first_quarter_moon.png
new file mode 100644
index 00000000000..5dccaf72a4f
--- /dev/null
+++ b/app/assets/images/emoji/first_quarter_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/first_quarter_moon_with_face.png b/app/assets/images/emoji/first_quarter_moon_with_face.png
new file mode 100644
index 00000000000..cd8a3d7acd8
--- /dev/null
+++ b/app/assets/images/emoji/first_quarter_moon_with_face.png
Binary files differ
diff --git a/app/assets/images/emoji/fish.png b/app/assets/images/emoji/fish.png
new file mode 100644
index 00000000000..c2d2faaacd4
--- /dev/null
+++ b/app/assets/images/emoji/fish.png
Binary files differ
diff --git a/app/assets/images/emoji/fish_cake.png b/app/assets/images/emoji/fish_cake.png
new file mode 100644
index 00000000000..157bded65db
--- /dev/null
+++ b/app/assets/images/emoji/fish_cake.png
Binary files differ
diff --git a/app/assets/images/emoji/fishing_pole_and_fish.png b/app/assets/images/emoji/fishing_pole_and_fish.png
new file mode 100644
index 00000000000..dfcdf07eb50
--- /dev/null
+++ b/app/assets/images/emoji/fishing_pole_and_fish.png
Binary files differ
diff --git a/app/assets/images/emoji/fist.png b/app/assets/images/emoji/fist.png
new file mode 100644
index 00000000000..de33592bf98
--- /dev/null
+++ b/app/assets/images/emoji/fist.png
Binary files differ
diff --git a/app/assets/images/emoji/fist_tone1.png b/app/assets/images/emoji/fist_tone1.png
new file mode 100644
index 00000000000..02809e2dd68
--- /dev/null
+++ b/app/assets/images/emoji/fist_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/fist_tone2.png b/app/assets/images/emoji/fist_tone2.png
new file mode 100644
index 00000000000..5de34810383
--- /dev/null
+++ b/app/assets/images/emoji/fist_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/fist_tone3.png b/app/assets/images/emoji/fist_tone3.png
new file mode 100644
index 00000000000..0d5240129b1
--- /dev/null
+++ b/app/assets/images/emoji/fist_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/fist_tone4.png b/app/assets/images/emoji/fist_tone4.png
new file mode 100644
index 00000000000..a95c0dd634b
--- /dev/null
+++ b/app/assets/images/emoji/fist_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/fist_tone5.png b/app/assets/images/emoji/fist_tone5.png
new file mode 100644
index 00000000000..a2f092fd8c7
--- /dev/null
+++ b/app/assets/images/emoji/fist_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/five.png b/app/assets/images/emoji/five.png
new file mode 100644
index 00000000000..d14371f3f27
--- /dev/null
+++ b/app/assets/images/emoji/five.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ac.png b/app/assets/images/emoji/flag_ac.png
new file mode 100644
index 00000000000..286239920c7
--- /dev/null
+++ b/app/assets/images/emoji/flag_ac.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ad.png b/app/assets/images/emoji/flag_ad.png
new file mode 100644
index 00000000000..20f4b14e8ad
--- /dev/null
+++ b/app/assets/images/emoji/flag_ad.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ae.png b/app/assets/images/emoji/flag_ae.png
new file mode 100644
index 00000000000..d16ffe4b862
--- /dev/null
+++ b/app/assets/images/emoji/flag_ae.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_af.png b/app/assets/images/emoji/flag_af.png
new file mode 100644
index 00000000000..a51533b554d
--- /dev/null
+++ b/app/assets/images/emoji/flag_af.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ag.png b/app/assets/images/emoji/flag_ag.png
new file mode 100644
index 00000000000..07f2ce397d0
--- /dev/null
+++ b/app/assets/images/emoji/flag_ag.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ai.png b/app/assets/images/emoji/flag_ai.png
new file mode 100644
index 00000000000..500b5ab09fb
--- /dev/null
+++ b/app/assets/images/emoji/flag_ai.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_al.png b/app/assets/images/emoji/flag_al.png
new file mode 100644
index 00000000000..03a20132cc6
--- /dev/null
+++ b/app/assets/images/emoji/flag_al.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_am.png b/app/assets/images/emoji/flag_am.png
new file mode 100644
index 00000000000..2ad60a273ec
--- /dev/null
+++ b/app/assets/images/emoji/flag_am.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ao.png b/app/assets/images/emoji/flag_ao.png
new file mode 100644
index 00000000000..cb46c31f862
--- /dev/null
+++ b/app/assets/images/emoji/flag_ao.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_aq.png b/app/assets/images/emoji/flag_aq.png
new file mode 100644
index 00000000000..b272021d375
--- /dev/null
+++ b/app/assets/images/emoji/flag_aq.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ar.png b/app/assets/images/emoji/flag_ar.png
new file mode 100644
index 00000000000..73136caf3b7
--- /dev/null
+++ b/app/assets/images/emoji/flag_ar.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_as.png b/app/assets/images/emoji/flag_as.png
new file mode 100644
index 00000000000..3db45a0d9f3
--- /dev/null
+++ b/app/assets/images/emoji/flag_as.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_at.png b/app/assets/images/emoji/flag_at.png
new file mode 100644
index 00000000000..c43769dcb19
--- /dev/null
+++ b/app/assets/images/emoji/flag_at.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_au.png b/app/assets/images/emoji/flag_au.png
new file mode 100644
index 00000000000..7794309c78c
--- /dev/null
+++ b/app/assets/images/emoji/flag_au.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_aw.png b/app/assets/images/emoji/flag_aw.png
new file mode 100644
index 00000000000..02c840d12c9
--- /dev/null
+++ b/app/assets/images/emoji/flag_aw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ax.png b/app/assets/images/emoji/flag_ax.png
new file mode 100644
index 00000000000..fc5466174bb
--- /dev/null
+++ b/app/assets/images/emoji/flag_ax.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_az.png b/app/assets/images/emoji/flag_az.png
new file mode 100644
index 00000000000..89d3d15fd9f
--- /dev/null
+++ b/app/assets/images/emoji/flag_az.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ba.png b/app/assets/images/emoji/flag_ba.png
new file mode 100644
index 00000000000..25fe407e13c
--- /dev/null
+++ b/app/assets/images/emoji/flag_ba.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bb.png b/app/assets/images/emoji/flag_bb.png
new file mode 100644
index 00000000000..bccd8c5c9b0
--- /dev/null
+++ b/app/assets/images/emoji/flag_bb.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bd.png b/app/assets/images/emoji/flag_bd.png
new file mode 100644
index 00000000000..b0597a3149b
--- /dev/null
+++ b/app/assets/images/emoji/flag_bd.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_be.png b/app/assets/images/emoji/flag_be.png
new file mode 100644
index 00000000000..551f086e3c4
--- /dev/null
+++ b/app/assets/images/emoji/flag_be.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bf.png b/app/assets/images/emoji/flag_bf.png
new file mode 100644
index 00000000000..444d4829f94
--- /dev/null
+++ b/app/assets/images/emoji/flag_bf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bg.png b/app/assets/images/emoji/flag_bg.png
new file mode 100644
index 00000000000..821eee5e170
--- /dev/null
+++ b/app/assets/images/emoji/flag_bg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bh.png b/app/assets/images/emoji/flag_bh.png
new file mode 100644
index 00000000000..f33724249f0
--- /dev/null
+++ b/app/assets/images/emoji/flag_bh.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bi.png b/app/assets/images/emoji/flag_bi.png
new file mode 100644
index 00000000000..ea20ac93211
--- /dev/null
+++ b/app/assets/images/emoji/flag_bi.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bj.png b/app/assets/images/emoji/flag_bj.png
new file mode 100644
index 00000000000..7cca4f80457
--- /dev/null
+++ b/app/assets/images/emoji/flag_bj.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bl.png b/app/assets/images/emoji/flag_bl.png
new file mode 100644
index 00000000000..1082e78999f
--- /dev/null
+++ b/app/assets/images/emoji/flag_bl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_black.png b/app/assets/images/emoji/flag_black.png
new file mode 100644
index 00000000000..0e28d05d5ac
--- /dev/null
+++ b/app/assets/images/emoji/flag_black.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bm.png b/app/assets/images/emoji/flag_bm.png
new file mode 100644
index 00000000000..ab8cafdac63
--- /dev/null
+++ b/app/assets/images/emoji/flag_bm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bn.png b/app/assets/images/emoji/flag_bn.png
new file mode 100644
index 00000000000..caa9329a896
--- /dev/null
+++ b/app/assets/images/emoji/flag_bn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bo.png b/app/assets/images/emoji/flag_bo.png
new file mode 100644
index 00000000000..98af62b3da7
--- /dev/null
+++ b/app/assets/images/emoji/flag_bo.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bq.png b/app/assets/images/emoji/flag_bq.png
new file mode 100644
index 00000000000..cb978ef9de9
--- /dev/null
+++ b/app/assets/images/emoji/flag_bq.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_br.png b/app/assets/images/emoji/flag_br.png
new file mode 100644
index 00000000000..b139366a42b
--- /dev/null
+++ b/app/assets/images/emoji/flag_br.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bs.png b/app/assets/images/emoji/flag_bs.png
new file mode 100644
index 00000000000..d36bcd2fb52
--- /dev/null
+++ b/app/assets/images/emoji/flag_bs.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bt.png b/app/assets/images/emoji/flag_bt.png
new file mode 100644
index 00000000000..ed57aa0360e
--- /dev/null
+++ b/app/assets/images/emoji/flag_bt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bv.png b/app/assets/images/emoji/flag_bv.png
new file mode 100644
index 00000000000..5884e648228
--- /dev/null
+++ b/app/assets/images/emoji/flag_bv.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bw.png b/app/assets/images/emoji/flag_bw.png
new file mode 100644
index 00000000000..cb12f34739d
--- /dev/null
+++ b/app/assets/images/emoji/flag_bw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_by.png b/app/assets/images/emoji/flag_by.png
new file mode 100644
index 00000000000..859c05beb13
--- /dev/null
+++ b/app/assets/images/emoji/flag_by.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_bz.png b/app/assets/images/emoji/flag_bz.png
new file mode 100644
index 00000000000..34761cd03d8
--- /dev/null
+++ b/app/assets/images/emoji/flag_bz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ca.png b/app/assets/images/emoji/flag_ca.png
new file mode 100644
index 00000000000..7c5b390e85b
--- /dev/null
+++ b/app/assets/images/emoji/flag_ca.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cc.png b/app/assets/images/emoji/flag_cc.png
new file mode 100644
index 00000000000..b6555a23d83
--- /dev/null
+++ b/app/assets/images/emoji/flag_cc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cd.png b/app/assets/images/emoji/flag_cd.png
new file mode 100644
index 00000000000..fa92009771d
--- /dev/null
+++ b/app/assets/images/emoji/flag_cd.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cf.png b/app/assets/images/emoji/flag_cf.png
new file mode 100644
index 00000000000..b969ae29ea9
--- /dev/null
+++ b/app/assets/images/emoji/flag_cf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cg.png b/app/assets/images/emoji/flag_cg.png
new file mode 100644
index 00000000000..3a38a40a95e
--- /dev/null
+++ b/app/assets/images/emoji/flag_cg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ch.png b/app/assets/images/emoji/flag_ch.png
new file mode 100644
index 00000000000..5ff86b8a3b7
--- /dev/null
+++ b/app/assets/images/emoji/flag_ch.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ci.png b/app/assets/images/emoji/flag_ci.png
new file mode 100644
index 00000000000..e3b4d15c7f1
--- /dev/null
+++ b/app/assets/images/emoji/flag_ci.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ck.png b/app/assets/images/emoji/flag_ck.png
new file mode 100644
index 00000000000..b6b53dbc1c4
--- /dev/null
+++ b/app/assets/images/emoji/flag_ck.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cl.png b/app/assets/images/emoji/flag_cl.png
new file mode 100644
index 00000000000..c9390da5499
--- /dev/null
+++ b/app/assets/images/emoji/flag_cl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cm.png b/app/assets/images/emoji/flag_cm.png
new file mode 100644
index 00000000000..2d3f6ec4518
--- /dev/null
+++ b/app/assets/images/emoji/flag_cm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cn.png b/app/assets/images/emoji/flag_cn.png
new file mode 100644
index 00000000000..0a7f350a6d2
--- /dev/null
+++ b/app/assets/images/emoji/flag_cn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_co.png b/app/assets/images/emoji/flag_co.png
new file mode 100644
index 00000000000..7e0f5e0dc3c
--- /dev/null
+++ b/app/assets/images/emoji/flag_co.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cp.png b/app/assets/images/emoji/flag_cp.png
new file mode 100644
index 00000000000..70c761036bd
--- /dev/null
+++ b/app/assets/images/emoji/flag_cp.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cr.png b/app/assets/images/emoji/flag_cr.png
new file mode 100644
index 00000000000..a5fce126515
--- /dev/null
+++ b/app/assets/images/emoji/flag_cr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cu.png b/app/assets/images/emoji/flag_cu.png
new file mode 100644
index 00000000000..447328f7dfd
--- /dev/null
+++ b/app/assets/images/emoji/flag_cu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cv.png b/app/assets/images/emoji/flag_cv.png
new file mode 100644
index 00000000000..43faf4d64d5
--- /dev/null
+++ b/app/assets/images/emoji/flag_cv.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cw.png b/app/assets/images/emoji/flag_cw.png
new file mode 100644
index 00000000000..eb39e8d0078
--- /dev/null
+++ b/app/assets/images/emoji/flag_cw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cx.png b/app/assets/images/emoji/flag_cx.png
new file mode 100644
index 00000000000..09d21359f3a
--- /dev/null
+++ b/app/assets/images/emoji/flag_cx.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cy.png b/app/assets/images/emoji/flag_cy.png
new file mode 100644
index 00000000000..154a7aa3176
--- /dev/null
+++ b/app/assets/images/emoji/flag_cy.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_cz.png b/app/assets/images/emoji/flag_cz.png
new file mode 100644
index 00000000000..9737ca223c7
--- /dev/null
+++ b/app/assets/images/emoji/flag_cz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_de.png b/app/assets/images/emoji/flag_de.png
new file mode 100644
index 00000000000..98ed76b3bab
--- /dev/null
+++ b/app/assets/images/emoji/flag_de.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_dg.png b/app/assets/images/emoji/flag_dg.png
new file mode 100644
index 00000000000..aae927d14b8
--- /dev/null
+++ b/app/assets/images/emoji/flag_dg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_dj.png b/app/assets/images/emoji/flag_dj.png
new file mode 100644
index 00000000000..73c2a2acbd9
--- /dev/null
+++ b/app/assets/images/emoji/flag_dj.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_dk.png b/app/assets/images/emoji/flag_dk.png
new file mode 100644
index 00000000000..e5a60b06256
--- /dev/null
+++ b/app/assets/images/emoji/flag_dk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_dm.png b/app/assets/images/emoji/flag_dm.png
new file mode 100644
index 00000000000..50f8a53981d
--- /dev/null
+++ b/app/assets/images/emoji/flag_dm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_do.png b/app/assets/images/emoji/flag_do.png
new file mode 100644
index 00000000000..037a45d7c26
--- /dev/null
+++ b/app/assets/images/emoji/flag_do.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_dz.png b/app/assets/images/emoji/flag_dz.png
new file mode 100644
index 00000000000..24945b10f2d
--- /dev/null
+++ b/app/assets/images/emoji/flag_dz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ea.png b/app/assets/images/emoji/flag_ea.png
new file mode 100644
index 00000000000..356ff347838
--- /dev/null
+++ b/app/assets/images/emoji/flag_ea.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ec.png b/app/assets/images/emoji/flag_ec.png
new file mode 100644
index 00000000000..13814594619
--- /dev/null
+++ b/app/assets/images/emoji/flag_ec.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ee.png b/app/assets/images/emoji/flag_ee.png
new file mode 100644
index 00000000000..84f317e7747
--- /dev/null
+++ b/app/assets/images/emoji/flag_ee.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_eg.png b/app/assets/images/emoji/flag_eg.png
new file mode 100644
index 00000000000..57786064a95
--- /dev/null
+++ b/app/assets/images/emoji/flag_eg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_eh.png b/app/assets/images/emoji/flag_eh.png
new file mode 100644
index 00000000000..4d7a76687f6
--- /dev/null
+++ b/app/assets/images/emoji/flag_eh.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_er.png b/app/assets/images/emoji/flag_er.png
new file mode 100644
index 00000000000..0c3c724c1fb
--- /dev/null
+++ b/app/assets/images/emoji/flag_er.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_es.png b/app/assets/images/emoji/flag_es.png
new file mode 100644
index 00000000000..3e73597a225
--- /dev/null
+++ b/app/assets/images/emoji/flag_es.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_et.png b/app/assets/images/emoji/flag_et.png
new file mode 100644
index 00000000000..9560a134c97
--- /dev/null
+++ b/app/assets/images/emoji/flag_et.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_eu.png b/app/assets/images/emoji/flag_eu.png
new file mode 100644
index 00000000000..0b456cf3330
--- /dev/null
+++ b/app/assets/images/emoji/flag_eu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_fi.png b/app/assets/images/emoji/flag_fi.png
new file mode 100644
index 00000000000..ebcf58abfc5
--- /dev/null
+++ b/app/assets/images/emoji/flag_fi.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_fj.png b/app/assets/images/emoji/flag_fj.png
new file mode 100644
index 00000000000..9cc8c37fe37
--- /dev/null
+++ b/app/assets/images/emoji/flag_fj.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_fk.png b/app/assets/images/emoji/flag_fk.png
new file mode 100644
index 00000000000..61372fd2549
--- /dev/null
+++ b/app/assets/images/emoji/flag_fk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_fm.png b/app/assets/images/emoji/flag_fm.png
new file mode 100644
index 00000000000..0889825c8e1
--- /dev/null
+++ b/app/assets/images/emoji/flag_fm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_fo.png b/app/assets/images/emoji/flag_fo.png
new file mode 100644
index 00000000000..9a4431b0831
--- /dev/null
+++ b/app/assets/images/emoji/flag_fo.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_fr.png b/app/assets/images/emoji/flag_fr.png
new file mode 100644
index 00000000000..62ca19c3fcf
--- /dev/null
+++ b/app/assets/images/emoji/flag_fr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ga.png b/app/assets/images/emoji/flag_ga.png
new file mode 100644
index 00000000000..2e68e527a3e
--- /dev/null
+++ b/app/assets/images/emoji/flag_ga.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gb.png b/app/assets/images/emoji/flag_gb.png
new file mode 100644
index 00000000000..3ed10f62347
--- /dev/null
+++ b/app/assets/images/emoji/flag_gb.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gd.png b/app/assets/images/emoji/flag_gd.png
new file mode 100644
index 00000000000..527aad33807
--- /dev/null
+++ b/app/assets/images/emoji/flag_gd.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ge.png b/app/assets/images/emoji/flag_ge.png
new file mode 100644
index 00000000000..a75d142480d
--- /dev/null
+++ b/app/assets/images/emoji/flag_ge.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gf.png b/app/assets/images/emoji/flag_gf.png
new file mode 100644
index 00000000000..0cf96f327c0
--- /dev/null
+++ b/app/assets/images/emoji/flag_gf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gg.png b/app/assets/images/emoji/flag_gg.png
new file mode 100644
index 00000000000..970002c7f76
--- /dev/null
+++ b/app/assets/images/emoji/flag_gg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gh.png b/app/assets/images/emoji/flag_gh.png
new file mode 100644
index 00000000000..f31b5eb7b45
--- /dev/null
+++ b/app/assets/images/emoji/flag_gh.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gi.png b/app/assets/images/emoji/flag_gi.png
new file mode 100644
index 00000000000..e554a2a1d0c
--- /dev/null
+++ b/app/assets/images/emoji/flag_gi.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gl.png b/app/assets/images/emoji/flag_gl.png
new file mode 100644
index 00000000000..2e795dd4e33
--- /dev/null
+++ b/app/assets/images/emoji/flag_gl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gm.png b/app/assets/images/emoji/flag_gm.png
new file mode 100644
index 00000000000..bb69c0975a3
--- /dev/null
+++ b/app/assets/images/emoji/flag_gm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gn.png b/app/assets/images/emoji/flag_gn.png
new file mode 100644
index 00000000000..1981f61dbf5
--- /dev/null
+++ b/app/assets/images/emoji/flag_gn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gp.png b/app/assets/images/emoji/flag_gp.png
new file mode 100644
index 00000000000..10e42e672bd
--- /dev/null
+++ b/app/assets/images/emoji/flag_gp.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gq.png b/app/assets/images/emoji/flag_gq.png
new file mode 100644
index 00000000000..11475e61eeb
--- /dev/null
+++ b/app/assets/images/emoji/flag_gq.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gr.png b/app/assets/images/emoji/flag_gr.png
new file mode 100644
index 00000000000..0f6bb1b6b94
--- /dev/null
+++ b/app/assets/images/emoji/flag_gr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gs.png b/app/assets/images/emoji/flag_gs.png
new file mode 100644
index 00000000000..6fc92780453
--- /dev/null
+++ b/app/assets/images/emoji/flag_gs.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gt.png b/app/assets/images/emoji/flag_gt.png
new file mode 100644
index 00000000000..7213d4139ed
--- /dev/null
+++ b/app/assets/images/emoji/flag_gt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gu.png b/app/assets/images/emoji/flag_gu.png
new file mode 100644
index 00000000000..4027549ca3c
--- /dev/null
+++ b/app/assets/images/emoji/flag_gu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gw.png b/app/assets/images/emoji/flag_gw.png
new file mode 100644
index 00000000000..6357f6225f4
--- /dev/null
+++ b/app/assets/images/emoji/flag_gw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_gy.png b/app/assets/images/emoji/flag_gy.png
new file mode 100644
index 00000000000..746e2fb7e44
--- /dev/null
+++ b/app/assets/images/emoji/flag_gy.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_hk.png b/app/assets/images/emoji/flag_hk.png
new file mode 100644
index 00000000000..cf0c7151b56
--- /dev/null
+++ b/app/assets/images/emoji/flag_hk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_hm.png b/app/assets/images/emoji/flag_hm.png
new file mode 100644
index 00000000000..b613509e466
--- /dev/null
+++ b/app/assets/images/emoji/flag_hm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_hn.png b/app/assets/images/emoji/flag_hn.png
new file mode 100644
index 00000000000..402cdcefdf8
--- /dev/null
+++ b/app/assets/images/emoji/flag_hn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_hr.png b/app/assets/images/emoji/flag_hr.png
new file mode 100644
index 00000000000..46f4f06b4f2
--- /dev/null
+++ b/app/assets/images/emoji/flag_hr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ht.png b/app/assets/images/emoji/flag_ht.png
new file mode 100644
index 00000000000..d8d0c888498
--- /dev/null
+++ b/app/assets/images/emoji/flag_ht.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_hu.png b/app/assets/images/emoji/flag_hu.png
new file mode 100644
index 00000000000..a898de636a5
--- /dev/null
+++ b/app/assets/images/emoji/flag_hu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ic.png b/app/assets/images/emoji/flag_ic.png
new file mode 100644
index 00000000000..69fd990aa95
--- /dev/null
+++ b/app/assets/images/emoji/flag_ic.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_id.png b/app/assets/images/emoji/flag_id.png
new file mode 100644
index 00000000000..85b4c063a45
--- /dev/null
+++ b/app/assets/images/emoji/flag_id.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ie.png b/app/assets/images/emoji/flag_ie.png
new file mode 100644
index 00000000000..a28295838cc
--- /dev/null
+++ b/app/assets/images/emoji/flag_ie.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_il.png b/app/assets/images/emoji/flag_il.png
new file mode 100644
index 00000000000..85c410d45fb
--- /dev/null
+++ b/app/assets/images/emoji/flag_il.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_im.png b/app/assets/images/emoji/flag_im.png
new file mode 100644
index 00000000000..60a2458e38e
--- /dev/null
+++ b/app/assets/images/emoji/flag_im.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_in.png b/app/assets/images/emoji/flag_in.png
new file mode 100644
index 00000000000..feccc8952ce
--- /dev/null
+++ b/app/assets/images/emoji/flag_in.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_io.png b/app/assets/images/emoji/flag_io.png
new file mode 100644
index 00000000000..aae927d14b8
--- /dev/null
+++ b/app/assets/images/emoji/flag_io.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_iq.png b/app/assets/images/emoji/flag_iq.png
new file mode 100644
index 00000000000..41fd1db6f86
--- /dev/null
+++ b/app/assets/images/emoji/flag_iq.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ir.png b/app/assets/images/emoji/flag_ir.png
new file mode 100644
index 00000000000..ff7aaf62ba6
--- /dev/null
+++ b/app/assets/images/emoji/flag_ir.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_is.png b/app/assets/images/emoji/flag_is.png
new file mode 100644
index 00000000000..ad8d4131dd2
--- /dev/null
+++ b/app/assets/images/emoji/flag_is.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_it.png b/app/assets/images/emoji/flag_it.png
new file mode 100644
index 00000000000..f21563ec533
--- /dev/null
+++ b/app/assets/images/emoji/flag_it.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_je.png b/app/assets/images/emoji/flag_je.png
new file mode 100644
index 00000000000..198a918f6a4
--- /dev/null
+++ b/app/assets/images/emoji/flag_je.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_jm.png b/app/assets/images/emoji/flag_jm.png
new file mode 100644
index 00000000000..f84e4f9e8db
--- /dev/null
+++ b/app/assets/images/emoji/flag_jm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_jo.png b/app/assets/images/emoji/flag_jo.png
new file mode 100644
index 00000000000..20bfa147e3e
--- /dev/null
+++ b/app/assets/images/emoji/flag_jo.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_jp.png b/app/assets/images/emoji/flag_jp.png
new file mode 100644
index 00000000000..8d8838e4708
--- /dev/null
+++ b/app/assets/images/emoji/flag_jp.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ke.png b/app/assets/images/emoji/flag_ke.png
new file mode 100644
index 00000000000..9e417ab3009
--- /dev/null
+++ b/app/assets/images/emoji/flag_ke.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kg.png b/app/assets/images/emoji/flag_kg.png
new file mode 100644
index 00000000000..2f2d848fe58
--- /dev/null
+++ b/app/assets/images/emoji/flag_kg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kh.png b/app/assets/images/emoji/flag_kh.png
new file mode 100644
index 00000000000..9a2877dd620
--- /dev/null
+++ b/app/assets/images/emoji/flag_kh.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ki.png b/app/assets/images/emoji/flag_ki.png
new file mode 100644
index 00000000000..10e507e3245
--- /dev/null
+++ b/app/assets/images/emoji/flag_ki.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_km.png b/app/assets/images/emoji/flag_km.png
new file mode 100644
index 00000000000..bd5a0588e03
--- /dev/null
+++ b/app/assets/images/emoji/flag_km.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kn.png b/app/assets/images/emoji/flag_kn.png
new file mode 100644
index 00000000000..776207c9605
--- /dev/null
+++ b/app/assets/images/emoji/flag_kn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kp.png b/app/assets/images/emoji/flag_kp.png
new file mode 100644
index 00000000000..6b3fd89eaaa
--- /dev/null
+++ b/app/assets/images/emoji/flag_kp.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kr.png b/app/assets/images/emoji/flag_kr.png
new file mode 100644
index 00000000000..833a88116e1
--- /dev/null
+++ b/app/assets/images/emoji/flag_kr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kw.png b/app/assets/images/emoji/flag_kw.png
new file mode 100644
index 00000000000..4d19bfa6ca7
--- /dev/null
+++ b/app/assets/images/emoji/flag_kw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ky.png b/app/assets/images/emoji/flag_ky.png
new file mode 100644
index 00000000000..40daa4da597
--- /dev/null
+++ b/app/assets/images/emoji/flag_ky.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_kz.png b/app/assets/images/emoji/flag_kz.png
new file mode 100644
index 00000000000..2f97a8fd3c6
--- /dev/null
+++ b/app/assets/images/emoji/flag_kz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_la.png b/app/assets/images/emoji/flag_la.png
new file mode 100644
index 00000000000..4d4179f34f6
--- /dev/null
+++ b/app/assets/images/emoji/flag_la.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lb.png b/app/assets/images/emoji/flag_lb.png
new file mode 100644
index 00000000000..3d594467011
--- /dev/null
+++ b/app/assets/images/emoji/flag_lb.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lc.png b/app/assets/images/emoji/flag_lc.png
new file mode 100644
index 00000000000..45547b1e439
--- /dev/null
+++ b/app/assets/images/emoji/flag_lc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_li.png b/app/assets/images/emoji/flag_li.png
new file mode 100644
index 00000000000..0eafa6a2215
--- /dev/null
+++ b/app/assets/images/emoji/flag_li.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lk.png b/app/assets/images/emoji/flag_lk.png
new file mode 100644
index 00000000000..ab4fe10c40c
--- /dev/null
+++ b/app/assets/images/emoji/flag_lk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lr.png b/app/assets/images/emoji/flag_lr.png
new file mode 100644
index 00000000000..f66f267fea2
--- /dev/null
+++ b/app/assets/images/emoji/flag_lr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ls.png b/app/assets/images/emoji/flag_ls.png
new file mode 100644
index 00000000000..24745631e3c
--- /dev/null
+++ b/app/assets/images/emoji/flag_ls.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lt.png b/app/assets/images/emoji/flag_lt.png
new file mode 100644
index 00000000000..d644b56d62a
--- /dev/null
+++ b/app/assets/images/emoji/flag_lt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lu.png b/app/assets/images/emoji/flag_lu.png
new file mode 100644
index 00000000000..a2df9c92994
--- /dev/null
+++ b/app/assets/images/emoji/flag_lu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_lv.png b/app/assets/images/emoji/flag_lv.png
new file mode 100644
index 00000000000..ae680d5f0e3
--- /dev/null
+++ b/app/assets/images/emoji/flag_lv.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ly.png b/app/assets/images/emoji/flag_ly.png
new file mode 100644
index 00000000000..f6e77b0f3ba
--- /dev/null
+++ b/app/assets/images/emoji/flag_ly.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ma.png b/app/assets/images/emoji/flag_ma.png
new file mode 100644
index 00000000000..c4a056722cd
--- /dev/null
+++ b/app/assets/images/emoji/flag_ma.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mc.png b/app/assets/images/emoji/flag_mc.png
new file mode 100644
index 00000000000..d479eab98cb
--- /dev/null
+++ b/app/assets/images/emoji/flag_mc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_md.png b/app/assets/images/emoji/flag_md.png
new file mode 100644
index 00000000000..a7a72539872
--- /dev/null
+++ b/app/assets/images/emoji/flag_md.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_me.png b/app/assets/images/emoji/flag_me.png
new file mode 100644
index 00000000000..7c771e7e120
--- /dev/null
+++ b/app/assets/images/emoji/flag_me.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mf.png b/app/assets/images/emoji/flag_mf.png
new file mode 100644
index 00000000000..70c761036bd
--- /dev/null
+++ b/app/assets/images/emoji/flag_mf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mg.png b/app/assets/images/emoji/flag_mg.png
new file mode 100644
index 00000000000..2f3ccdda76f
--- /dev/null
+++ b/app/assets/images/emoji/flag_mg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mh.png b/app/assets/images/emoji/flag_mh.png
new file mode 100644
index 00000000000..598016481c1
--- /dev/null
+++ b/app/assets/images/emoji/flag_mh.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mk.png b/app/assets/images/emoji/flag_mk.png
new file mode 100644
index 00000000000..7ba775ee75c
--- /dev/null
+++ b/app/assets/images/emoji/flag_mk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ml.png b/app/assets/images/emoji/flag_ml.png
new file mode 100644
index 00000000000..68343785468
--- /dev/null
+++ b/app/assets/images/emoji/flag_ml.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mm.png b/app/assets/images/emoji/flag_mm.png
new file mode 100644
index 00000000000..37dc7d71591
--- /dev/null
+++ b/app/assets/images/emoji/flag_mm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mn.png b/app/assets/images/emoji/flag_mn.png
new file mode 100644
index 00000000000..1f146bbcd1a
--- /dev/null
+++ b/app/assets/images/emoji/flag_mn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mo.png b/app/assets/images/emoji/flag_mo.png
new file mode 100644
index 00000000000..7edde31f64b
--- /dev/null
+++ b/app/assets/images/emoji/flag_mo.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mp.png b/app/assets/images/emoji/flag_mp.png
new file mode 100644
index 00000000000..17ec1c441ed
--- /dev/null
+++ b/app/assets/images/emoji/flag_mp.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mq.png b/app/assets/images/emoji/flag_mq.png
new file mode 100644
index 00000000000..1e672dc9087
--- /dev/null
+++ b/app/assets/images/emoji/flag_mq.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mr.png b/app/assets/images/emoji/flag_mr.png
new file mode 100644
index 00000000000..f87de46effe
--- /dev/null
+++ b/app/assets/images/emoji/flag_mr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ms.png b/app/assets/images/emoji/flag_ms.png
new file mode 100644
index 00000000000..480b0d4ebda
--- /dev/null
+++ b/app/assets/images/emoji/flag_ms.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mt.png b/app/assets/images/emoji/flag_mt.png
new file mode 100644
index 00000000000..c9e1dbdce82
--- /dev/null
+++ b/app/assets/images/emoji/flag_mt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mu.png b/app/assets/images/emoji/flag_mu.png
new file mode 100644
index 00000000000..55b33cb7c33
--- /dev/null
+++ b/app/assets/images/emoji/flag_mu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mv.png b/app/assets/images/emoji/flag_mv.png
new file mode 100644
index 00000000000..ce5867126ae
--- /dev/null
+++ b/app/assets/images/emoji/flag_mv.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mw.png b/app/assets/images/emoji/flag_mw.png
new file mode 100644
index 00000000000..003d8548401
--- /dev/null
+++ b/app/assets/images/emoji/flag_mw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mx.png b/app/assets/images/emoji/flag_mx.png
new file mode 100644
index 00000000000..42572bcd0ba
--- /dev/null
+++ b/app/assets/images/emoji/flag_mx.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_my.png b/app/assets/images/emoji/flag_my.png
new file mode 100644
index 00000000000..17526c26742
--- /dev/null
+++ b/app/assets/images/emoji/flag_my.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_mz.png b/app/assets/images/emoji/flag_mz.png
new file mode 100644
index 00000000000..2352a78e786
--- /dev/null
+++ b/app/assets/images/emoji/flag_mz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_na.png b/app/assets/images/emoji/flag_na.png
new file mode 100644
index 00000000000..ed31c3df04d
--- /dev/null
+++ b/app/assets/images/emoji/flag_na.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_nc.png b/app/assets/images/emoji/flag_nc.png
new file mode 100644
index 00000000000..90b3afebfa3
--- /dev/null
+++ b/app/assets/images/emoji/flag_nc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ne.png b/app/assets/images/emoji/flag_ne.png
new file mode 100644
index 00000000000..f98a1173c2a
--- /dev/null
+++ b/app/assets/images/emoji/flag_ne.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_nf.png b/app/assets/images/emoji/flag_nf.png
new file mode 100644
index 00000000000..9099e767420
--- /dev/null
+++ b/app/assets/images/emoji/flag_nf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ng.png b/app/assets/images/emoji/flag_ng.png
new file mode 100644
index 00000000000..ea0abeff1a1
--- /dev/null
+++ b/app/assets/images/emoji/flag_ng.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ni.png b/app/assets/images/emoji/flag_ni.png
new file mode 100644
index 00000000000..772920dfa10
--- /dev/null
+++ b/app/assets/images/emoji/flag_ni.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_nl.png b/app/assets/images/emoji/flag_nl.png
new file mode 100644
index 00000000000..83a0e817e41
--- /dev/null
+++ b/app/assets/images/emoji/flag_nl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_no.png b/app/assets/images/emoji/flag_no.png
new file mode 100644
index 00000000000..99d3142eb7b
--- /dev/null
+++ b/app/assets/images/emoji/flag_no.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_np.png b/app/assets/images/emoji/flag_np.png
new file mode 100644
index 00000000000..87425a8dfef
--- /dev/null
+++ b/app/assets/images/emoji/flag_np.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_nr.png b/app/assets/images/emoji/flag_nr.png
new file mode 100644
index 00000000000..b3e3a5d5621
--- /dev/null
+++ b/app/assets/images/emoji/flag_nr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_nu.png b/app/assets/images/emoji/flag_nu.png
new file mode 100644
index 00000000000..f03614443ee
--- /dev/null
+++ b/app/assets/images/emoji/flag_nu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_nz.png b/app/assets/images/emoji/flag_nz.png
new file mode 100644
index 00000000000..a4eeeab9cd9
--- /dev/null
+++ b/app/assets/images/emoji/flag_nz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_om.png b/app/assets/images/emoji/flag_om.png
new file mode 100644
index 00000000000..ea824ba31e7
--- /dev/null
+++ b/app/assets/images/emoji/flag_om.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pa.png b/app/assets/images/emoji/flag_pa.png
new file mode 100644
index 00000000000..c3091d89889
--- /dev/null
+++ b/app/assets/images/emoji/flag_pa.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pe.png b/app/assets/images/emoji/flag_pe.png
new file mode 100644
index 00000000000..39223aa9dbb
--- /dev/null
+++ b/app/assets/images/emoji/flag_pe.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pf.png b/app/assets/images/emoji/flag_pf.png
new file mode 100644
index 00000000000..113445f8f6e
--- /dev/null
+++ b/app/assets/images/emoji/flag_pf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pg.png b/app/assets/images/emoji/flag_pg.png
new file mode 100644
index 00000000000..825e9dcb762
--- /dev/null
+++ b/app/assets/images/emoji/flag_pg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ph.png b/app/assets/images/emoji/flag_ph.png
new file mode 100644
index 00000000000..8260e15bd2c
--- /dev/null
+++ b/app/assets/images/emoji/flag_ph.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pk.png b/app/assets/images/emoji/flag_pk.png
new file mode 100644
index 00000000000..a7b6a1c5074
--- /dev/null
+++ b/app/assets/images/emoji/flag_pk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pl.png b/app/assets/images/emoji/flag_pl.png
new file mode 100644
index 00000000000..19de2edec11
--- /dev/null
+++ b/app/assets/images/emoji/flag_pl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pm.png b/app/assets/images/emoji/flag_pm.png
new file mode 100644
index 00000000000..2ca60554193
--- /dev/null
+++ b/app/assets/images/emoji/flag_pm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pn.png b/app/assets/images/emoji/flag_pn.png
new file mode 100644
index 00000000000..f2263b154bc
--- /dev/null
+++ b/app/assets/images/emoji/flag_pn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pr.png b/app/assets/images/emoji/flag_pr.png
new file mode 100644
index 00000000000..d0209cddb79
--- /dev/null
+++ b/app/assets/images/emoji/flag_pr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ps.png b/app/assets/images/emoji/flag_ps.png
new file mode 100644
index 00000000000..7ccab09778b
--- /dev/null
+++ b/app/assets/images/emoji/flag_ps.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pt.png b/app/assets/images/emoji/flag_pt.png
new file mode 100644
index 00000000000..cc93f27c64b
--- /dev/null
+++ b/app/assets/images/emoji/flag_pt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_pw.png b/app/assets/images/emoji/flag_pw.png
new file mode 100644
index 00000000000..154b2f12d3c
--- /dev/null
+++ b/app/assets/images/emoji/flag_pw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_py.png b/app/assets/images/emoji/flag_py.png
new file mode 100644
index 00000000000..662ad2f6ff1
--- /dev/null
+++ b/app/assets/images/emoji/flag_py.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_qa.png b/app/assets/images/emoji/flag_qa.png
new file mode 100644
index 00000000000..a01d8b05cc7
--- /dev/null
+++ b/app/assets/images/emoji/flag_qa.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_re.png b/app/assets/images/emoji/flag_re.png
new file mode 100644
index 00000000000..57f2bbe9df8
--- /dev/null
+++ b/app/assets/images/emoji/flag_re.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ro.png b/app/assets/images/emoji/flag_ro.png
new file mode 100644
index 00000000000..3e48c447706
--- /dev/null
+++ b/app/assets/images/emoji/flag_ro.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_rs.png b/app/assets/images/emoji/flag_rs.png
new file mode 100644
index 00000000000..9df6c9a5235
--- /dev/null
+++ b/app/assets/images/emoji/flag_rs.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ru.png b/app/assets/images/emoji/flag_ru.png
new file mode 100644
index 00000000000..e50c9db90e7
--- /dev/null
+++ b/app/assets/images/emoji/flag_ru.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_rw.png b/app/assets/images/emoji/flag_rw.png
new file mode 100644
index 00000000000..c238c874e1d
--- /dev/null
+++ b/app/assets/images/emoji/flag_rw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sa.png b/app/assets/images/emoji/flag_sa.png
new file mode 100644
index 00000000000..4941be7d198
--- /dev/null
+++ b/app/assets/images/emoji/flag_sa.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sb.png b/app/assets/images/emoji/flag_sb.png
new file mode 100644
index 00000000000..7d8f1ac6130
--- /dev/null
+++ b/app/assets/images/emoji/flag_sb.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sc.png b/app/assets/images/emoji/flag_sc.png
new file mode 100644
index 00000000000..6ae4d90765e
--- /dev/null
+++ b/app/assets/images/emoji/flag_sc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sd.png b/app/assets/images/emoji/flag_sd.png
new file mode 100644
index 00000000000..963be1b36fb
--- /dev/null
+++ b/app/assets/images/emoji/flag_sd.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_se.png b/app/assets/images/emoji/flag_se.png
new file mode 100644
index 00000000000..fc0d0e0ce89
--- /dev/null
+++ b/app/assets/images/emoji/flag_se.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sg.png b/app/assets/images/emoji/flag_sg.png
new file mode 100644
index 00000000000..de3c7737c42
--- /dev/null
+++ b/app/assets/images/emoji/flag_sg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sh.png b/app/assets/images/emoji/flag_sh.png
new file mode 100644
index 00000000000..40cd9e44e96
--- /dev/null
+++ b/app/assets/images/emoji/flag_sh.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_si.png b/app/assets/images/emoji/flag_si.png
new file mode 100644
index 00000000000..e308999dba2
--- /dev/null
+++ b/app/assets/images/emoji/flag_si.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sj.png b/app/assets/images/emoji/flag_sj.png
new file mode 100644
index 00000000000..5884e648228
--- /dev/null
+++ b/app/assets/images/emoji/flag_sj.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sk.png b/app/assets/images/emoji/flag_sk.png
new file mode 100644
index 00000000000..4259d0e1418
--- /dev/null
+++ b/app/assets/images/emoji/flag_sk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sl.png b/app/assets/images/emoji/flag_sl.png
new file mode 100644
index 00000000000..d2cc68830ab
--- /dev/null
+++ b/app/assets/images/emoji/flag_sl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sm.png b/app/assets/images/emoji/flag_sm.png
new file mode 100644
index 00000000000..03b8708754e
--- /dev/null
+++ b/app/assets/images/emoji/flag_sm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sn.png b/app/assets/images/emoji/flag_sn.png
new file mode 100644
index 00000000000..5368bbe93df
--- /dev/null
+++ b/app/assets/images/emoji/flag_sn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_so.png b/app/assets/images/emoji/flag_so.png
new file mode 100644
index 00000000000..68a0597365a
--- /dev/null
+++ b/app/assets/images/emoji/flag_so.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sr.png b/app/assets/images/emoji/flag_sr.png
new file mode 100644
index 00000000000..d3251327035
--- /dev/null
+++ b/app/assets/images/emoji/flag_sr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ss.png b/app/assets/images/emoji/flag_ss.png
new file mode 100644
index 00000000000..122977e798f
--- /dev/null
+++ b/app/assets/images/emoji/flag_ss.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_st.png b/app/assets/images/emoji/flag_st.png
new file mode 100644
index 00000000000..f83a863d612
--- /dev/null
+++ b/app/assets/images/emoji/flag_st.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sv.png b/app/assets/images/emoji/flag_sv.png
new file mode 100644
index 00000000000..efb83e2f253
--- /dev/null
+++ b/app/assets/images/emoji/flag_sv.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sx.png b/app/assets/images/emoji/flag_sx.png
new file mode 100644
index 00000000000..94b760fbedf
--- /dev/null
+++ b/app/assets/images/emoji/flag_sx.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sy.png b/app/assets/images/emoji/flag_sy.png
new file mode 100644
index 00000000000..09a8ee8f78c
--- /dev/null
+++ b/app/assets/images/emoji/flag_sy.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_sz.png b/app/assets/images/emoji/flag_sz.png
new file mode 100644
index 00000000000..f74e82ea1fd
--- /dev/null
+++ b/app/assets/images/emoji/flag_sz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ta.png b/app/assets/images/emoji/flag_ta.png
new file mode 100644
index 00000000000..b44283e90e2
--- /dev/null
+++ b/app/assets/images/emoji/flag_ta.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tc.png b/app/assets/images/emoji/flag_tc.png
new file mode 100644
index 00000000000..156b33d1ba6
--- /dev/null
+++ b/app/assets/images/emoji/flag_tc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_td.png b/app/assets/images/emoji/flag_td.png
new file mode 100644
index 00000000000..ebe7f592828
--- /dev/null
+++ b/app/assets/images/emoji/flag_td.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tf.png b/app/assets/images/emoji/flag_tf.png
new file mode 100644
index 00000000000..a1a3ad68ee2
--- /dev/null
+++ b/app/assets/images/emoji/flag_tf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tg.png b/app/assets/images/emoji/flag_tg.png
new file mode 100644
index 00000000000..826b73c9ac5
--- /dev/null
+++ b/app/assets/images/emoji/flag_tg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_th.png b/app/assets/images/emoji/flag_th.png
new file mode 100644
index 00000000000..93ff542c5a6
--- /dev/null
+++ b/app/assets/images/emoji/flag_th.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tj.png b/app/assets/images/emoji/flag_tj.png
new file mode 100644
index 00000000000..7a8a0b6190a
--- /dev/null
+++ b/app/assets/images/emoji/flag_tj.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tk.png b/app/assets/images/emoji/flag_tk.png
new file mode 100644
index 00000000000..2fa5a21b1bb
--- /dev/null
+++ b/app/assets/images/emoji/flag_tk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tl.png b/app/assets/images/emoji/flag_tl.png
new file mode 100644
index 00000000000..5b120eccc6f
--- /dev/null
+++ b/app/assets/images/emoji/flag_tl.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tm.png b/app/assets/images/emoji/flag_tm.png
new file mode 100644
index 00000000000..c3c4f532302
--- /dev/null
+++ b/app/assets/images/emoji/flag_tm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tn.png b/app/assets/images/emoji/flag_tn.png
new file mode 100644
index 00000000000..58ef161229f
--- /dev/null
+++ b/app/assets/images/emoji/flag_tn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_to.png b/app/assets/images/emoji/flag_to.png
new file mode 100644
index 00000000000..1ffa7bb9d19
--- /dev/null
+++ b/app/assets/images/emoji/flag_to.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tr.png b/app/assets/images/emoji/flag_tr.png
new file mode 100644
index 00000000000..325251fae88
--- /dev/null
+++ b/app/assets/images/emoji/flag_tr.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tt.png b/app/assets/images/emoji/flag_tt.png
new file mode 100644
index 00000000000..ed3bb39a300
--- /dev/null
+++ b/app/assets/images/emoji/flag_tt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tv.png b/app/assets/images/emoji/flag_tv.png
new file mode 100644
index 00000000000..e82c65c7bb9
--- /dev/null
+++ b/app/assets/images/emoji/flag_tv.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tw.png b/app/assets/images/emoji/flag_tw.png
new file mode 100644
index 00000000000..3a8f00b5928
--- /dev/null
+++ b/app/assets/images/emoji/flag_tw.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_tz.png b/app/assets/images/emoji/flag_tz.png
new file mode 100644
index 00000000000..2a020853d4e
--- /dev/null
+++ b/app/assets/images/emoji/flag_tz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ua.png b/app/assets/images/emoji/flag_ua.png
new file mode 100644
index 00000000000..cd84d1bbd36
--- /dev/null
+++ b/app/assets/images/emoji/flag_ua.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ug.png b/app/assets/images/emoji/flag_ug.png
new file mode 100644
index 00000000000..dc97690eb55
--- /dev/null
+++ b/app/assets/images/emoji/flag_ug.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_um.png b/app/assets/images/emoji/flag_um.png
new file mode 100644
index 00000000000..4a7ee3cdf13
--- /dev/null
+++ b/app/assets/images/emoji/flag_um.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_us.png b/app/assets/images/emoji/flag_us.png
new file mode 100644
index 00000000000..9f730305860
--- /dev/null
+++ b/app/assets/images/emoji/flag_us.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_uy.png b/app/assets/images/emoji/flag_uy.png
new file mode 100644
index 00000000000..b8002a697a6
--- /dev/null
+++ b/app/assets/images/emoji/flag_uy.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_uz.png b/app/assets/images/emoji/flag_uz.png
new file mode 100644
index 00000000000..d56ca9bc424
--- /dev/null
+++ b/app/assets/images/emoji/flag_uz.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_va.png b/app/assets/images/emoji/flag_va.png
new file mode 100644
index 00000000000..ddaf5e3141b
--- /dev/null
+++ b/app/assets/images/emoji/flag_va.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_vc.png b/app/assets/images/emoji/flag_vc.png
new file mode 100644
index 00000000000..43703c62a71
--- /dev/null
+++ b/app/assets/images/emoji/flag_vc.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ve.png b/app/assets/images/emoji/flag_ve.png
new file mode 100644
index 00000000000..1b62796824e
--- /dev/null
+++ b/app/assets/images/emoji/flag_ve.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_vg.png b/app/assets/images/emoji/flag_vg.png
new file mode 100644
index 00000000000..536f780f1c0
--- /dev/null
+++ b/app/assets/images/emoji/flag_vg.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_vi.png b/app/assets/images/emoji/flag_vi.png
new file mode 100644
index 00000000000..64102012cfe
--- /dev/null
+++ b/app/assets/images/emoji/flag_vi.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_vn.png b/app/assets/images/emoji/flag_vn.png
new file mode 100644
index 00000000000..427036046b6
--- /dev/null
+++ b/app/assets/images/emoji/flag_vn.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_vu.png b/app/assets/images/emoji/flag_vu.png
new file mode 100644
index 00000000000..706eba44070
--- /dev/null
+++ b/app/assets/images/emoji/flag_vu.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_wf.png b/app/assets/images/emoji/flag_wf.png
new file mode 100644
index 00000000000..70c761036bd
--- /dev/null
+++ b/app/assets/images/emoji/flag_wf.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_white.png b/app/assets/images/emoji/flag_white.png
new file mode 100644
index 00000000000..86d6e96d5e9
--- /dev/null
+++ b/app/assets/images/emoji/flag_white.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ws.png b/app/assets/images/emoji/flag_ws.png
new file mode 100644
index 00000000000..a1ea0703141
--- /dev/null
+++ b/app/assets/images/emoji/flag_ws.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_xk.png b/app/assets/images/emoji/flag_xk.png
new file mode 100644
index 00000000000..e587a446632
--- /dev/null
+++ b/app/assets/images/emoji/flag_xk.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_ye.png b/app/assets/images/emoji/flag_ye.png
new file mode 100644
index 00000000000..eadfebd5f67
--- /dev/null
+++ b/app/assets/images/emoji/flag_ye.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_yt.png b/app/assets/images/emoji/flag_yt.png
new file mode 100644
index 00000000000..c81fa6d886e
--- /dev/null
+++ b/app/assets/images/emoji/flag_yt.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_za.png b/app/assets/images/emoji/flag_za.png
new file mode 100644
index 00000000000..f397ef5072f
--- /dev/null
+++ b/app/assets/images/emoji/flag_za.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_zm.png b/app/assets/images/emoji/flag_zm.png
new file mode 100644
index 00000000000..2494a31f662
--- /dev/null
+++ b/app/assets/images/emoji/flag_zm.png
Binary files differ
diff --git a/app/assets/images/emoji/flag_zw.png b/app/assets/images/emoji/flag_zw.png
new file mode 100644
index 00000000000..e09b9652be6
--- /dev/null
+++ b/app/assets/images/emoji/flag_zw.png
Binary files differ
diff --git a/app/assets/images/emoji/flags.png b/app/assets/images/emoji/flags.png
new file mode 100644
index 00000000000..3b451035a3a
--- /dev/null
+++ b/app/assets/images/emoji/flags.png
Binary files differ
diff --git a/app/assets/images/emoji/flashlight.png b/app/assets/images/emoji/flashlight.png
new file mode 100644
index 00000000000..eee36c25067
--- /dev/null
+++ b/app/assets/images/emoji/flashlight.png
Binary files differ
diff --git a/app/assets/images/emoji/fleur-de-lis.png b/app/assets/images/emoji/fleur-de-lis.png
new file mode 100644
index 00000000000..c9250d27fa7
--- /dev/null
+++ b/app/assets/images/emoji/fleur-de-lis.png
Binary files differ
diff --git a/app/assets/images/emoji/floppy_disk.png b/app/assets/images/emoji/floppy_disk.png
new file mode 100644
index 00000000000..072a76d3c13
--- /dev/null
+++ b/app/assets/images/emoji/floppy_disk.png
Binary files differ
diff --git a/app/assets/images/emoji/flower_playing_cards.png b/app/assets/images/emoji/flower_playing_cards.png
new file mode 100644
index 00000000000..6766b044d95
--- /dev/null
+++ b/app/assets/images/emoji/flower_playing_cards.png
Binary files differ
diff --git a/app/assets/images/emoji/flushed.png b/app/assets/images/emoji/flushed.png
new file mode 100644
index 00000000000..829220bc470
--- /dev/null
+++ b/app/assets/images/emoji/flushed.png
Binary files differ
diff --git a/app/assets/images/emoji/fog.png b/app/assets/images/emoji/fog.png
new file mode 100644
index 00000000000..4e73c2de272
--- /dev/null
+++ b/app/assets/images/emoji/fog.png
Binary files differ
diff --git a/app/assets/images/emoji/foggy.png b/app/assets/images/emoji/foggy.png
new file mode 100644
index 00000000000..57702d8d3ac
--- /dev/null
+++ b/app/assets/images/emoji/foggy.png
Binary files differ
diff --git a/app/assets/images/emoji/football.png b/app/assets/images/emoji/football.png
new file mode 100644
index 00000000000..10366f41fce
--- /dev/null
+++ b/app/assets/images/emoji/football.png
Binary files differ
diff --git a/app/assets/images/emoji/footprints.png b/app/assets/images/emoji/footprints.png
new file mode 100644
index 00000000000..b2673c5a1a8
--- /dev/null
+++ b/app/assets/images/emoji/footprints.png
Binary files differ
diff --git a/app/assets/images/emoji/fork_and_knife.png b/app/assets/images/emoji/fork_and_knife.png
new file mode 100644
index 00000000000..09f1feaea1c
--- /dev/null
+++ b/app/assets/images/emoji/fork_and_knife.png
Binary files differ
diff --git a/app/assets/images/emoji/fork_knife_plate.png b/app/assets/images/emoji/fork_knife_plate.png
new file mode 100644
index 00000000000..7411755f708
--- /dev/null
+++ b/app/assets/images/emoji/fork_knife_plate.png
Binary files differ
diff --git a/app/assets/images/emoji/fountain.png b/app/assets/images/emoji/fountain.png
new file mode 100644
index 00000000000..293f5d91c0f
--- /dev/null
+++ b/app/assets/images/emoji/fountain.png
Binary files differ
diff --git a/app/assets/images/emoji/four.png b/app/assets/images/emoji/four.png
new file mode 100644
index 00000000000..b0e914aac45
--- /dev/null
+++ b/app/assets/images/emoji/four.png
Binary files differ
diff --git a/app/assets/images/emoji/four_leaf_clover.png b/app/assets/images/emoji/four_leaf_clover.png
new file mode 100644
index 00000000000..fdedfcc2b4e
--- /dev/null
+++ b/app/assets/images/emoji/four_leaf_clover.png
Binary files differ
diff --git a/app/assets/images/emoji/fox.png b/app/assets/images/emoji/fox.png
new file mode 100644
index 00000000000..1ab339bf054
--- /dev/null
+++ b/app/assets/images/emoji/fox.png
Binary files differ
diff --git a/app/assets/images/emoji/frame_photo.png b/app/assets/images/emoji/frame_photo.png
new file mode 100644
index 00000000000..9fe84607bfd
--- /dev/null
+++ b/app/assets/images/emoji/frame_photo.png
Binary files differ
diff --git a/app/assets/images/emoji/free.png b/app/assets/images/emoji/free.png
new file mode 100644
index 00000000000..b71956eb48a
--- /dev/null
+++ b/app/assets/images/emoji/free.png
Binary files differ
diff --git a/app/assets/images/emoji/french_bread.png b/app/assets/images/emoji/french_bread.png
new file mode 100644
index 00000000000..4c2c5639822
--- /dev/null
+++ b/app/assets/images/emoji/french_bread.png
Binary files differ
diff --git a/app/assets/images/emoji/fried_shrimp.png b/app/assets/images/emoji/fried_shrimp.png
new file mode 100644
index 00000000000..752ba7f1398
--- /dev/null
+++ b/app/assets/images/emoji/fried_shrimp.png
Binary files differ
diff --git a/app/assets/images/emoji/fries.png b/app/assets/images/emoji/fries.png
new file mode 100644
index 00000000000..4e2a4caacef
--- /dev/null
+++ b/app/assets/images/emoji/fries.png
Binary files differ
diff --git a/app/assets/images/emoji/frog.png b/app/assets/images/emoji/frog.png
new file mode 100644
index 00000000000..8825d1ad577
--- /dev/null
+++ b/app/assets/images/emoji/frog.png
Binary files differ
diff --git a/app/assets/images/emoji/frowning.png b/app/assets/images/emoji/frowning.png
new file mode 100644
index 00000000000..43ab6b0a1c1
--- /dev/null
+++ b/app/assets/images/emoji/frowning.png
Binary files differ
diff --git a/app/assets/images/emoji/frowning2.png b/app/assets/images/emoji/frowning2.png
new file mode 100644
index 00000000000..6ae71f233b9
--- /dev/null
+++ b/app/assets/images/emoji/frowning2.png
Binary files differ
diff --git a/app/assets/images/emoji/fuelpump.png b/app/assets/images/emoji/fuelpump.png
new file mode 100644
index 00000000000..05b18794474
--- /dev/null
+++ b/app/assets/images/emoji/fuelpump.png
Binary files differ
diff --git a/app/assets/images/emoji/full_moon.png b/app/assets/images/emoji/full_moon.png
new file mode 100644
index 00000000000..c9a2d6aa7c9
--- /dev/null
+++ b/app/assets/images/emoji/full_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/full_moon_with_face.png b/app/assets/images/emoji/full_moon_with_face.png
new file mode 100644
index 00000000000..a5c25bbaf64
--- /dev/null
+++ b/app/assets/images/emoji/full_moon_with_face.png
Binary files differ
diff --git a/app/assets/images/emoji/game_die.png b/app/assets/images/emoji/game_die.png
new file mode 100644
index 00000000000..ad3626fe5e5
--- /dev/null
+++ b/app/assets/images/emoji/game_die.png
Binary files differ
diff --git a/app/assets/images/emoji/gear.png b/app/assets/images/emoji/gear.png
new file mode 100644
index 00000000000..2a1cc2c0ff4
--- /dev/null
+++ b/app/assets/images/emoji/gear.png
Binary files differ
diff --git a/app/assets/images/emoji/gem.png b/app/assets/images/emoji/gem.png
new file mode 100644
index 00000000000..db122d26a19
--- /dev/null
+++ b/app/assets/images/emoji/gem.png
Binary files differ
diff --git a/app/assets/images/emoji/gemini.png b/app/assets/images/emoji/gemini.png
new file mode 100644
index 00000000000..1a09698cf00
--- /dev/null
+++ b/app/assets/images/emoji/gemini.png
Binary files differ
diff --git a/app/assets/images/emoji/ghost.png b/app/assets/images/emoji/ghost.png
new file mode 100644
index 00000000000..5650bc0ed18
--- /dev/null
+++ b/app/assets/images/emoji/ghost.png
Binary files differ
diff --git a/app/assets/images/emoji/gift.png b/app/assets/images/emoji/gift.png
new file mode 100644
index 00000000000..844e2164560
--- /dev/null
+++ b/app/assets/images/emoji/gift.png
Binary files differ
diff --git a/app/assets/images/emoji/gift_heart.png b/app/assets/images/emoji/gift_heart.png
new file mode 100644
index 00000000000..902ceafe4d1
--- /dev/null
+++ b/app/assets/images/emoji/gift_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/girl.png b/app/assets/images/emoji/girl.png
new file mode 100644
index 00000000000..dc1d4d08b39
--- /dev/null
+++ b/app/assets/images/emoji/girl.png
Binary files differ
diff --git a/app/assets/images/emoji/girl_tone1.png b/app/assets/images/emoji/girl_tone1.png
new file mode 100644
index 00000000000..bb667e88651
--- /dev/null
+++ b/app/assets/images/emoji/girl_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/girl_tone2.png b/app/assets/images/emoji/girl_tone2.png
new file mode 100644
index 00000000000..a59ed4a3f0d
--- /dev/null
+++ b/app/assets/images/emoji/girl_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/girl_tone3.png b/app/assets/images/emoji/girl_tone3.png
new file mode 100644
index 00000000000..517e7f2a7b0
--- /dev/null
+++ b/app/assets/images/emoji/girl_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/girl_tone4.png b/app/assets/images/emoji/girl_tone4.png
new file mode 100644
index 00000000000..542d96c8487
--- /dev/null
+++ b/app/assets/images/emoji/girl_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/girl_tone5.png b/app/assets/images/emoji/girl_tone5.png
new file mode 100644
index 00000000000..66b7c28c2df
--- /dev/null
+++ b/app/assets/images/emoji/girl_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/globe_with_meridians.png b/app/assets/images/emoji/globe_with_meridians.png
new file mode 100644
index 00000000000..82450c1a4ba
--- /dev/null
+++ b/app/assets/images/emoji/globe_with_meridians.png
Binary files differ
diff --git a/app/assets/images/emoji/goal.png b/app/assets/images/emoji/goal.png
new file mode 100644
index 00000000000..df3a53da0fb
--- /dev/null
+++ b/app/assets/images/emoji/goal.png
Binary files differ
diff --git a/app/assets/images/emoji/goat.png b/app/assets/images/emoji/goat.png
new file mode 100644
index 00000000000..f9d9e38a128
--- /dev/null
+++ b/app/assets/images/emoji/goat.png
Binary files differ
diff --git a/app/assets/images/emoji/golf.png b/app/assets/images/emoji/golf.png
new file mode 100644
index 00000000000..f65a21d8a46
--- /dev/null
+++ b/app/assets/images/emoji/golf.png
Binary files differ
diff --git a/app/assets/images/emoji/golfer.png b/app/assets/images/emoji/golfer.png
new file mode 100644
index 00000000000..39c552de86d
--- /dev/null
+++ b/app/assets/images/emoji/golfer.png
Binary files differ
diff --git a/app/assets/images/emoji/gorilla.png b/app/assets/images/emoji/gorilla.png
new file mode 100644
index 00000000000..acc51e13622
--- /dev/null
+++ b/app/assets/images/emoji/gorilla.png
Binary files differ
diff --git a/app/assets/images/emoji/grapes.png b/app/assets/images/emoji/grapes.png
new file mode 100644
index 00000000000..30d22218896
--- /dev/null
+++ b/app/assets/images/emoji/grapes.png
Binary files differ
diff --git a/app/assets/images/emoji/green_apple.png b/app/assets/images/emoji/green_apple.png
new file mode 100644
index 00000000000..5fd51bd3915
--- /dev/null
+++ b/app/assets/images/emoji/green_apple.png
Binary files differ
diff --git a/app/assets/images/emoji/green_book.png b/app/assets/images/emoji/green_book.png
new file mode 100644
index 00000000000..e5e411cf3b5
--- /dev/null
+++ b/app/assets/images/emoji/green_book.png
Binary files differ
diff --git a/app/assets/images/emoji/green_heart.png b/app/assets/images/emoji/green_heart.png
new file mode 100644
index 00000000000..c52d60a58be
--- /dev/null
+++ b/app/assets/images/emoji/green_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/grey_exclamation.png b/app/assets/images/emoji/grey_exclamation.png
new file mode 100644
index 00000000000..9b64da8bf7f
--- /dev/null
+++ b/app/assets/images/emoji/grey_exclamation.png
Binary files differ
diff --git a/app/assets/images/emoji/grey_question.png b/app/assets/images/emoji/grey_question.png
new file mode 100644
index 00000000000..6e7824c75f6
--- /dev/null
+++ b/app/assets/images/emoji/grey_question.png
Binary files differ
diff --git a/app/assets/images/emoji/grimacing.png b/app/assets/images/emoji/grimacing.png
new file mode 100644
index 00000000000..871b2f071c9
--- /dev/null
+++ b/app/assets/images/emoji/grimacing.png
Binary files differ
diff --git a/app/assets/images/emoji/grin.png b/app/assets/images/emoji/grin.png
new file mode 100644
index 00000000000..418d94c811b
--- /dev/null
+++ b/app/assets/images/emoji/grin.png
Binary files differ
diff --git a/app/assets/images/emoji/grinning.png b/app/assets/images/emoji/grinning.png
new file mode 100644
index 00000000000..3e8e0dab78c
--- /dev/null
+++ b/app/assets/images/emoji/grinning.png
Binary files differ
diff --git a/app/assets/images/emoji/guardsman.png b/app/assets/images/emoji/guardsman.png
new file mode 100644
index 00000000000..8d7ab3c473c
--- /dev/null
+++ b/app/assets/images/emoji/guardsman.png
Binary files differ
diff --git a/app/assets/images/emoji/guardsman_tone1.png b/app/assets/images/emoji/guardsman_tone1.png
new file mode 100644
index 00000000000..cea9ba27468
--- /dev/null
+++ b/app/assets/images/emoji/guardsman_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/guardsman_tone2.png b/app/assets/images/emoji/guardsman_tone2.png
new file mode 100644
index 00000000000..037464e4028
--- /dev/null
+++ b/app/assets/images/emoji/guardsman_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/guardsman_tone3.png b/app/assets/images/emoji/guardsman_tone3.png
new file mode 100644
index 00000000000..0f6726fbe87
--- /dev/null
+++ b/app/assets/images/emoji/guardsman_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/guardsman_tone4.png b/app/assets/images/emoji/guardsman_tone4.png
new file mode 100644
index 00000000000..85fcf9a3b97
--- /dev/null
+++ b/app/assets/images/emoji/guardsman_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/guardsman_tone5.png b/app/assets/images/emoji/guardsman_tone5.png
new file mode 100644
index 00000000000..e5f9ca7d5a2
--- /dev/null
+++ b/app/assets/images/emoji/guardsman_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/guitar.png b/app/assets/images/emoji/guitar.png
new file mode 100644
index 00000000000..43d752f1e3d
--- /dev/null
+++ b/app/assets/images/emoji/guitar.png
Binary files differ
diff --git a/app/assets/images/emoji/gun.png b/app/assets/images/emoji/gun.png
new file mode 100644
index 00000000000..89c5c244c7b
--- /dev/null
+++ b/app/assets/images/emoji/gun.png
Binary files differ
diff --git a/app/assets/images/emoji/haircut.png b/app/assets/images/emoji/haircut.png
new file mode 100644
index 00000000000..91266b12930
--- /dev/null
+++ b/app/assets/images/emoji/haircut.png
Binary files differ
diff --git a/app/assets/images/emoji/haircut_tone1.png b/app/assets/images/emoji/haircut_tone1.png
new file mode 100644
index 00000000000..c743b74abeb
--- /dev/null
+++ b/app/assets/images/emoji/haircut_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/haircut_tone2.png b/app/assets/images/emoji/haircut_tone2.png
new file mode 100644
index 00000000000..f144f8e55ce
--- /dev/null
+++ b/app/assets/images/emoji/haircut_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/haircut_tone3.png b/app/assets/images/emoji/haircut_tone3.png
new file mode 100644
index 00000000000..d5ad19563ac
--- /dev/null
+++ b/app/assets/images/emoji/haircut_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/haircut_tone4.png b/app/assets/images/emoji/haircut_tone4.png
new file mode 100644
index 00000000000..244fd3af008
--- /dev/null
+++ b/app/assets/images/emoji/haircut_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/haircut_tone5.png b/app/assets/images/emoji/haircut_tone5.png
new file mode 100644
index 00000000000..20a94a88623
--- /dev/null
+++ b/app/assets/images/emoji/haircut_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/hamburger.png b/app/assets/images/emoji/hamburger.png
new file mode 100644
index 00000000000..3573b28a1fd
--- /dev/null
+++ b/app/assets/images/emoji/hamburger.png
Binary files differ
diff --git a/app/assets/images/emoji/hammer.png b/app/assets/images/emoji/hammer.png
new file mode 100644
index 00000000000..00736cce47d
--- /dev/null
+++ b/app/assets/images/emoji/hammer.png
Binary files differ
diff --git a/app/assets/images/emoji/hammer_pick.png b/app/assets/images/emoji/hammer_pick.png
new file mode 100644
index 00000000000..3bee30ec588
--- /dev/null
+++ b/app/assets/images/emoji/hammer_pick.png
Binary files differ
diff --git a/app/assets/images/emoji/hamster.png b/app/assets/images/emoji/hamster.png
new file mode 100644
index 00000000000..9a04388e4e7
--- /dev/null
+++ b/app/assets/images/emoji/hamster.png
Binary files differ
diff --git a/app/assets/images/emoji/hand_splayed.png b/app/assets/images/emoji/hand_splayed.png
new file mode 100644
index 00000000000..fb5ae8ebb5a
--- /dev/null
+++ b/app/assets/images/emoji/hand_splayed.png
Binary files differ
diff --git a/app/assets/images/emoji/hand_splayed_tone1.png b/app/assets/images/emoji/hand_splayed_tone1.png
new file mode 100644
index 00000000000..a7888e6bd23
--- /dev/null
+++ b/app/assets/images/emoji/hand_splayed_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/hand_splayed_tone2.png b/app/assets/images/emoji/hand_splayed_tone2.png
new file mode 100644
index 00000000000..cc10fbc272d
--- /dev/null
+++ b/app/assets/images/emoji/hand_splayed_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/hand_splayed_tone3.png b/app/assets/images/emoji/hand_splayed_tone3.png
new file mode 100644
index 00000000000..707236ae8a4
--- /dev/null
+++ b/app/assets/images/emoji/hand_splayed_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/hand_splayed_tone4.png b/app/assets/images/emoji/hand_splayed_tone4.png
new file mode 100644
index 00000000000..1430df9c61f
--- /dev/null
+++ b/app/assets/images/emoji/hand_splayed_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/hand_splayed_tone5.png b/app/assets/images/emoji/hand_splayed_tone5.png
new file mode 100644
index 00000000000..80bec971b6b
--- /dev/null
+++ b/app/assets/images/emoji/hand_splayed_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/handbag.png b/app/assets/images/emoji/handbag.png
new file mode 100644
index 00000000000..cbf75c5d25e
--- /dev/null
+++ b/app/assets/images/emoji/handbag.png
Binary files differ
diff --git a/app/assets/images/emoji/handball.png b/app/assets/images/emoji/handball.png
new file mode 100644
index 00000000000..1152f1344c7
--- /dev/null
+++ b/app/assets/images/emoji/handball.png
Binary files differ
diff --git a/app/assets/images/emoji/handball_tone1.png b/app/assets/images/emoji/handball_tone1.png
new file mode 100644
index 00000000000..c26cac2df98
--- /dev/null
+++ b/app/assets/images/emoji/handball_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/handball_tone2.png b/app/assets/images/emoji/handball_tone2.png
new file mode 100644
index 00000000000..7baaf95a9a2
--- /dev/null
+++ b/app/assets/images/emoji/handball_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/handball_tone3.png b/app/assets/images/emoji/handball_tone3.png
new file mode 100644
index 00000000000..0e3a37c3d40
--- /dev/null
+++ b/app/assets/images/emoji/handball_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/handball_tone4.png b/app/assets/images/emoji/handball_tone4.png
new file mode 100644
index 00000000000..e1233f38266
--- /dev/null
+++ b/app/assets/images/emoji/handball_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/handball_tone5.png b/app/assets/images/emoji/handball_tone5.png
new file mode 100644
index 00000000000..6b1eb9b64b0
--- /dev/null
+++ b/app/assets/images/emoji/handball_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/handshake.png b/app/assets/images/emoji/handshake.png
new file mode 100644
index 00000000000..c5d35fd8138
--- /dev/null
+++ b/app/assets/images/emoji/handshake.png
Binary files differ
diff --git a/app/assets/images/emoji/handshake_tone1.png b/app/assets/images/emoji/handshake_tone1.png
new file mode 100644
index 00000000000..8f8fbb9bdca
--- /dev/null
+++ b/app/assets/images/emoji/handshake_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/handshake_tone2.png b/app/assets/images/emoji/handshake_tone2.png
new file mode 100644
index 00000000000..336a77a6d78
--- /dev/null
+++ b/app/assets/images/emoji/handshake_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/handshake_tone3.png b/app/assets/images/emoji/handshake_tone3.png
new file mode 100644
index 00000000000..95f62d4fecd
--- /dev/null
+++ b/app/assets/images/emoji/handshake_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/handshake_tone4.png b/app/assets/images/emoji/handshake_tone4.png
new file mode 100644
index 00000000000..2b0a6433886
--- /dev/null
+++ b/app/assets/images/emoji/handshake_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/handshake_tone5.png b/app/assets/images/emoji/handshake_tone5.png
new file mode 100644
index 00000000000..40189ee68e4
--- /dev/null
+++ b/app/assets/images/emoji/handshake_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/hash.png b/app/assets/images/emoji/hash.png
new file mode 100644
index 00000000000..6e26f0070b0
--- /dev/null
+++ b/app/assets/images/emoji/hash.png
Binary files differ
diff --git a/app/assets/images/emoji/hatched_chick.png b/app/assets/images/emoji/hatched_chick.png
new file mode 100644
index 00000000000..31dfb511e0e
--- /dev/null
+++ b/app/assets/images/emoji/hatched_chick.png
Binary files differ
diff --git a/app/assets/images/emoji/hatching_chick.png b/app/assets/images/emoji/hatching_chick.png
new file mode 100644
index 00000000000..c5b0e8f3bcc
--- /dev/null
+++ b/app/assets/images/emoji/hatching_chick.png
Binary files differ
diff --git a/app/assets/images/emoji/head_bandage.png b/app/assets/images/emoji/head_bandage.png
new file mode 100644
index 00000000000..0be723085e0
--- /dev/null
+++ b/app/assets/images/emoji/head_bandage.png
Binary files differ
diff --git a/app/assets/images/emoji/headphones.png b/app/assets/images/emoji/headphones.png
new file mode 100644
index 00000000000..e9fd34041d8
--- /dev/null
+++ b/app/assets/images/emoji/headphones.png
Binary files differ
diff --git a/app/assets/images/emoji/hear_no_evil.png b/app/assets/images/emoji/hear_no_evil.png
new file mode 100644
index 00000000000..74b6be0c6c5
--- /dev/null
+++ b/app/assets/images/emoji/hear_no_evil.png
Binary files differ
diff --git a/app/assets/images/emoji/heart.png b/app/assets/images/emoji/heart.png
new file mode 100644
index 00000000000..638cb72dc4e
--- /dev/null
+++ b/app/assets/images/emoji/heart.png
Binary files differ
diff --git a/app/assets/images/emoji/heart_decoration.png b/app/assets/images/emoji/heart_decoration.png
new file mode 100644
index 00000000000..5443f60bc63
--- /dev/null
+++ b/app/assets/images/emoji/heart_decoration.png
Binary files differ
diff --git a/app/assets/images/emoji/heart_exclamation.png b/app/assets/images/emoji/heart_exclamation.png
new file mode 100644
index 00000000000..91b520be40b
--- /dev/null
+++ b/app/assets/images/emoji/heart_exclamation.png
Binary files differ
diff --git a/app/assets/images/emoji/heart_eyes.png b/app/assets/images/emoji/heart_eyes.png
new file mode 100644
index 00000000000..73fbee29d4e
--- /dev/null
+++ b/app/assets/images/emoji/heart_eyes.png
Binary files differ
diff --git a/app/assets/images/emoji/heart_eyes_cat.png b/app/assets/images/emoji/heart_eyes_cat.png
new file mode 100644
index 00000000000..bc5a833f9a1
--- /dev/null
+++ b/app/assets/images/emoji/heart_eyes_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/heartbeat.png b/app/assets/images/emoji/heartbeat.png
new file mode 100644
index 00000000000..0bcf2d1d567
--- /dev/null
+++ b/app/assets/images/emoji/heartbeat.png
Binary files differ
diff --git a/app/assets/images/emoji/heartpulse.png b/app/assets/images/emoji/heartpulse.png
new file mode 100644
index 00000000000..d6e694e972f
--- /dev/null
+++ b/app/assets/images/emoji/heartpulse.png
Binary files differ
diff --git a/app/assets/images/emoji/hearts.png b/app/assets/images/emoji/hearts.png
new file mode 100644
index 00000000000..393c3ed5267
--- /dev/null
+++ b/app/assets/images/emoji/hearts.png
Binary files differ
diff --git a/app/assets/images/emoji/heavy_check_mark.png b/app/assets/images/emoji/heavy_check_mark.png
new file mode 100644
index 00000000000..03bd695377e
--- /dev/null
+++ b/app/assets/images/emoji/heavy_check_mark.png
Binary files differ
diff --git a/app/assets/images/emoji/heavy_division_sign.png b/app/assets/images/emoji/heavy_division_sign.png
new file mode 100644
index 00000000000..df32ab21bea
--- /dev/null
+++ b/app/assets/images/emoji/heavy_division_sign.png
Binary files differ
diff --git a/app/assets/images/emoji/heavy_dollar_sign.png b/app/assets/images/emoji/heavy_dollar_sign.png
new file mode 100644
index 00000000000..ef2c2e20590
--- /dev/null
+++ b/app/assets/images/emoji/heavy_dollar_sign.png
Binary files differ
diff --git a/app/assets/images/emoji/heavy_minus_sign.png b/app/assets/images/emoji/heavy_minus_sign.png
new file mode 100644
index 00000000000..054211caf12
--- /dev/null
+++ b/app/assets/images/emoji/heavy_minus_sign.png
Binary files differ
diff --git a/app/assets/images/emoji/heavy_multiplication_x.png b/app/assets/images/emoji/heavy_multiplication_x.png
new file mode 100644
index 00000000000..e47cc1b685d
--- /dev/null
+++ b/app/assets/images/emoji/heavy_multiplication_x.png
Binary files differ
diff --git a/app/assets/images/emoji/heavy_plus_sign.png b/app/assets/images/emoji/heavy_plus_sign.png
new file mode 100644
index 00000000000..40799798aaf
--- /dev/null
+++ b/app/assets/images/emoji/heavy_plus_sign.png
Binary files differ
diff --git a/app/assets/images/emoji/helicopter.png b/app/assets/images/emoji/helicopter.png
new file mode 100644
index 00000000000..7ec5f39a51a
--- /dev/null
+++ b/app/assets/images/emoji/helicopter.png
Binary files differ
diff --git a/app/assets/images/emoji/helmet_with_cross.png b/app/assets/images/emoji/helmet_with_cross.png
new file mode 100644
index 00000000000..7140a676038
--- /dev/null
+++ b/app/assets/images/emoji/helmet_with_cross.png
Binary files differ
diff --git a/app/assets/images/emoji/herb.png b/app/assets/images/emoji/herb.png
new file mode 100644
index 00000000000..d984d1562bb
--- /dev/null
+++ b/app/assets/images/emoji/herb.png
Binary files differ
diff --git a/app/assets/images/emoji/hibiscus.png b/app/assets/images/emoji/hibiscus.png
new file mode 100644
index 00000000000..39dd3524233
--- /dev/null
+++ b/app/assets/images/emoji/hibiscus.png
Binary files differ
diff --git a/app/assets/images/emoji/high_brightness.png b/app/assets/images/emoji/high_brightness.png
new file mode 100644
index 00000000000..c41f2d5fd50
--- /dev/null
+++ b/app/assets/images/emoji/high_brightness.png
Binary files differ
diff --git a/app/assets/images/emoji/high_heel.png b/app/assets/images/emoji/high_heel.png
new file mode 100644
index 00000000000..b331cbccc9d
--- /dev/null
+++ b/app/assets/images/emoji/high_heel.png
Binary files differ
diff --git a/app/assets/images/emoji/hockey.png b/app/assets/images/emoji/hockey.png
new file mode 100644
index 00000000000..be94e9cbf73
--- /dev/null
+++ b/app/assets/images/emoji/hockey.png
Binary files differ
diff --git a/app/assets/images/emoji/hole.png b/app/assets/images/emoji/hole.png
new file mode 100644
index 00000000000..517d2ae0deb
--- /dev/null
+++ b/app/assets/images/emoji/hole.png
Binary files differ
diff --git a/app/assets/images/emoji/homes.png b/app/assets/images/emoji/homes.png
new file mode 100644
index 00000000000..6ab4a2a2651
--- /dev/null
+++ b/app/assets/images/emoji/homes.png
Binary files differ
diff --git a/app/assets/images/emoji/honey_pot.png b/app/assets/images/emoji/honey_pot.png
new file mode 100644
index 00000000000..9d8f592955e
--- /dev/null
+++ b/app/assets/images/emoji/honey_pot.png
Binary files differ
diff --git a/app/assets/images/emoji/horse.png b/app/assets/images/emoji/horse.png
new file mode 100644
index 00000000000..7cb1172f4e4
--- /dev/null
+++ b/app/assets/images/emoji/horse.png
Binary files differ
diff --git a/app/assets/images/emoji/horse_racing.png b/app/assets/images/emoji/horse_racing.png
new file mode 100644
index 00000000000..addf9edac56
--- /dev/null
+++ b/app/assets/images/emoji/horse_racing.png
Binary files differ
diff --git a/app/assets/images/emoji/horse_racing_tone1.png b/app/assets/images/emoji/horse_racing_tone1.png
new file mode 100644
index 00000000000..e9bf4092e98
--- /dev/null
+++ b/app/assets/images/emoji/horse_racing_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/horse_racing_tone2.png b/app/assets/images/emoji/horse_racing_tone2.png
new file mode 100644
index 00000000000..031bbc3d867
--- /dev/null
+++ b/app/assets/images/emoji/horse_racing_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/horse_racing_tone3.png b/app/assets/images/emoji/horse_racing_tone3.png
new file mode 100644
index 00000000000..b40ef891f9b
--- /dev/null
+++ b/app/assets/images/emoji/horse_racing_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/horse_racing_tone4.png b/app/assets/images/emoji/horse_racing_tone4.png
new file mode 100644
index 00000000000..e286cb85065
--- /dev/null
+++ b/app/assets/images/emoji/horse_racing_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/horse_racing_tone5.png b/app/assets/images/emoji/horse_racing_tone5.png
new file mode 100644
index 00000000000..453c51c6007
--- /dev/null
+++ b/app/assets/images/emoji/horse_racing_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/hospital.png b/app/assets/images/emoji/hospital.png
new file mode 100644
index 00000000000..1cbce4ae767
--- /dev/null
+++ b/app/assets/images/emoji/hospital.png
Binary files differ
diff --git a/app/assets/images/emoji/hot_pepper.png b/app/assets/images/emoji/hot_pepper.png
new file mode 100644
index 00000000000..266675bd577
--- /dev/null
+++ b/app/assets/images/emoji/hot_pepper.png
Binary files differ
diff --git a/app/assets/images/emoji/hotdog.png b/app/assets/images/emoji/hotdog.png
new file mode 100644
index 00000000000..3c3354d94cb
--- /dev/null
+++ b/app/assets/images/emoji/hotdog.png
Binary files differ
diff --git a/app/assets/images/emoji/hotel.png b/app/assets/images/emoji/hotel.png
new file mode 100644
index 00000000000..ea8f4c4979a
--- /dev/null
+++ b/app/assets/images/emoji/hotel.png
Binary files differ
diff --git a/app/assets/images/emoji/hotsprings.png b/app/assets/images/emoji/hotsprings.png
new file mode 100644
index 00000000000..3d9df2d9475
--- /dev/null
+++ b/app/assets/images/emoji/hotsprings.png
Binary files differ
diff --git a/app/assets/images/emoji/hourglass.png b/app/assets/images/emoji/hourglass.png
new file mode 100644
index 00000000000..a5db2d1d3f4
--- /dev/null
+++ b/app/assets/images/emoji/hourglass.png
Binary files differ
diff --git a/app/assets/images/emoji/hourglass_flowing_sand.png b/app/assets/images/emoji/hourglass_flowing_sand.png
new file mode 100644
index 00000000000..b93b15ed6d8
--- /dev/null
+++ b/app/assets/images/emoji/hourglass_flowing_sand.png
Binary files differ
diff --git a/app/assets/images/emoji/house.png b/app/assets/images/emoji/house.png
new file mode 100644
index 00000000000..01c98a0ba92
--- /dev/null
+++ b/app/assets/images/emoji/house.png
Binary files differ
diff --git a/app/assets/images/emoji/house_abandoned.png b/app/assets/images/emoji/house_abandoned.png
new file mode 100644
index 00000000000..c55e81de990
--- /dev/null
+++ b/app/assets/images/emoji/house_abandoned.png
Binary files differ
diff --git a/app/assets/images/emoji/house_with_garden.png b/app/assets/images/emoji/house_with_garden.png
new file mode 100644
index 00000000000..0aae41598ef
--- /dev/null
+++ b/app/assets/images/emoji/house_with_garden.png
Binary files differ
diff --git a/app/assets/images/emoji/hugging.png b/app/assets/images/emoji/hugging.png
new file mode 100644
index 00000000000..5bba6dc6d51
--- /dev/null
+++ b/app/assets/images/emoji/hugging.png
Binary files differ
diff --git a/app/assets/images/emoji/hushed.png b/app/assets/images/emoji/hushed.png
new file mode 100644
index 00000000000..cad0e23132e
--- /dev/null
+++ b/app/assets/images/emoji/hushed.png
Binary files differ
diff --git a/app/assets/images/emoji/ice_cream.png b/app/assets/images/emoji/ice_cream.png
new file mode 100644
index 00000000000..94267b9c434
--- /dev/null
+++ b/app/assets/images/emoji/ice_cream.png
Binary files differ
diff --git a/app/assets/images/emoji/ice_skate.png b/app/assets/images/emoji/ice_skate.png
new file mode 100644
index 00000000000..8c449b0c039
--- /dev/null
+++ b/app/assets/images/emoji/ice_skate.png
Binary files differ
diff --git a/app/assets/images/emoji/icecream.png b/app/assets/images/emoji/icecream.png
new file mode 100644
index 00000000000..8f6546e31a5
--- /dev/null
+++ b/app/assets/images/emoji/icecream.png
Binary files differ
diff --git a/app/assets/images/emoji/id.png b/app/assets/images/emoji/id.png
new file mode 100644
index 00000000000..5bf69bf7ba8
--- /dev/null
+++ b/app/assets/images/emoji/id.png
Binary files differ
diff --git a/app/assets/images/emoji/ideograph_advantage.png b/app/assets/images/emoji/ideograph_advantage.png
new file mode 100644
index 00000000000..0c0d589caf0
--- /dev/null
+++ b/app/assets/images/emoji/ideograph_advantage.png
Binary files differ
diff --git a/app/assets/images/emoji/imp.png b/app/assets/images/emoji/imp.png
new file mode 100644
index 00000000000..9f9a9605539
--- /dev/null
+++ b/app/assets/images/emoji/imp.png
Binary files differ
diff --git a/app/assets/images/emoji/inbox_tray.png b/app/assets/images/emoji/inbox_tray.png
new file mode 100644
index 00000000000..41a6be2b0ee
--- /dev/null
+++ b/app/assets/images/emoji/inbox_tray.png
Binary files differ
diff --git a/app/assets/images/emoji/incoming_envelope.png b/app/assets/images/emoji/incoming_envelope.png
new file mode 100644
index 00000000000..fd22e88182e
--- /dev/null
+++ b/app/assets/images/emoji/incoming_envelope.png
Binary files differ
diff --git a/app/assets/images/emoji/information_desk_person.png b/app/assets/images/emoji/information_desk_person.png
new file mode 100644
index 00000000000..55fc6294d25
--- /dev/null
+++ b/app/assets/images/emoji/information_desk_person.png
Binary files differ
diff --git a/app/assets/images/emoji/information_desk_person_tone1.png b/app/assets/images/emoji/information_desk_person_tone1.png
new file mode 100644
index 00000000000..3d9e2247940
--- /dev/null
+++ b/app/assets/images/emoji/information_desk_person_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/information_desk_person_tone2.png b/app/assets/images/emoji/information_desk_person_tone2.png
new file mode 100644
index 00000000000..879e8b7966d
--- /dev/null
+++ b/app/assets/images/emoji/information_desk_person_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/information_desk_person_tone3.png b/app/assets/images/emoji/information_desk_person_tone3.png
new file mode 100644
index 00000000000..307514eab67
--- /dev/null
+++ b/app/assets/images/emoji/information_desk_person_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/information_desk_person_tone4.png b/app/assets/images/emoji/information_desk_person_tone4.png
new file mode 100644
index 00000000000..297395dcb3f
--- /dev/null
+++ b/app/assets/images/emoji/information_desk_person_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/information_desk_person_tone5.png b/app/assets/images/emoji/information_desk_person_tone5.png
new file mode 100644
index 00000000000..26f8f22b28b
--- /dev/null
+++ b/app/assets/images/emoji/information_desk_person_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/information_source.png b/app/assets/images/emoji/information_source.png
new file mode 100644
index 00000000000..871f2db9314
--- /dev/null
+++ b/app/assets/images/emoji/information_source.png
Binary files differ
diff --git a/app/assets/images/emoji/innocent.png b/app/assets/images/emoji/innocent.png
new file mode 100644
index 00000000000..57f5151124f
--- /dev/null
+++ b/app/assets/images/emoji/innocent.png
Binary files differ
diff --git a/app/assets/images/emoji/interrobang.png b/app/assets/images/emoji/interrobang.png
new file mode 100644
index 00000000000..509813e9bb2
--- /dev/null
+++ b/app/assets/images/emoji/interrobang.png
Binary files differ
diff --git a/app/assets/images/emoji/iphone.png b/app/assets/images/emoji/iphone.png
new file mode 100644
index 00000000000..fd377acf872
--- /dev/null
+++ b/app/assets/images/emoji/iphone.png
Binary files differ
diff --git a/app/assets/images/emoji/island.png b/app/assets/images/emoji/island.png
new file mode 100644
index 00000000000..7fd834389b7
--- /dev/null
+++ b/app/assets/images/emoji/island.png
Binary files differ
diff --git a/app/assets/images/emoji/izakaya_lantern.png b/app/assets/images/emoji/izakaya_lantern.png
new file mode 100644
index 00000000000..dfd933f6f36
--- /dev/null
+++ b/app/assets/images/emoji/izakaya_lantern.png
Binary files differ
diff --git a/app/assets/images/emoji/jack_o_lantern.png b/app/assets/images/emoji/jack_o_lantern.png
new file mode 100644
index 00000000000..44c3fc0aec9
--- /dev/null
+++ b/app/assets/images/emoji/jack_o_lantern.png
Binary files differ
diff --git a/app/assets/images/emoji/japan.png b/app/assets/images/emoji/japan.png
new file mode 100644
index 00000000000..d86d0a59e12
--- /dev/null
+++ b/app/assets/images/emoji/japan.png
Binary files differ
diff --git a/app/assets/images/emoji/japanese_castle.png b/app/assets/images/emoji/japanese_castle.png
new file mode 100644
index 00000000000..64b4e33a1ae
--- /dev/null
+++ b/app/assets/images/emoji/japanese_castle.png
Binary files differ
diff --git a/app/assets/images/emoji/japanese_goblin.png b/app/assets/images/emoji/japanese_goblin.png
new file mode 100644
index 00000000000..515c6a2250e
--- /dev/null
+++ b/app/assets/images/emoji/japanese_goblin.png
Binary files differ
diff --git a/app/assets/images/emoji/japanese_ogre.png b/app/assets/images/emoji/japanese_ogre.png
new file mode 100644
index 00000000000..fe8670fdaf1
--- /dev/null
+++ b/app/assets/images/emoji/japanese_ogre.png
Binary files differ
diff --git a/app/assets/images/emoji/jeans.png b/app/assets/images/emoji/jeans.png
new file mode 100644
index 00000000000..2a6869d674c
--- /dev/null
+++ b/app/assets/images/emoji/jeans.png
Binary files differ
diff --git a/app/assets/images/emoji/joy.png b/app/assets/images/emoji/joy.png
new file mode 100644
index 00000000000..0ba3b1859d8
--- /dev/null
+++ b/app/assets/images/emoji/joy.png
Binary files differ
diff --git a/app/assets/images/emoji/joy_cat.png b/app/assets/images/emoji/joy_cat.png
new file mode 100644
index 00000000000..aac353179aa
--- /dev/null
+++ b/app/assets/images/emoji/joy_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/joystick.png b/app/assets/images/emoji/joystick.png
new file mode 100644
index 00000000000..1ee1905434e
--- /dev/null
+++ b/app/assets/images/emoji/joystick.png
Binary files differ
diff --git a/app/assets/images/emoji/juggling.png b/app/assets/images/emoji/juggling.png
new file mode 100644
index 00000000000..a37f6224a42
--- /dev/null
+++ b/app/assets/images/emoji/juggling.png
Binary files differ
diff --git a/app/assets/images/emoji/juggling_tone1.png b/app/assets/images/emoji/juggling_tone1.png
new file mode 100644
index 00000000000..c18eda40031
--- /dev/null
+++ b/app/assets/images/emoji/juggling_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/juggling_tone2.png b/app/assets/images/emoji/juggling_tone2.png
new file mode 100644
index 00000000000..de3b7a555b6
--- /dev/null
+++ b/app/assets/images/emoji/juggling_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/juggling_tone3.png b/app/assets/images/emoji/juggling_tone3.png
new file mode 100644
index 00000000000..74ab6d85458
--- /dev/null
+++ b/app/assets/images/emoji/juggling_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/juggling_tone4.png b/app/assets/images/emoji/juggling_tone4.png
new file mode 100644
index 00000000000..1c57823203f
--- /dev/null
+++ b/app/assets/images/emoji/juggling_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/juggling_tone5.png b/app/assets/images/emoji/juggling_tone5.png
new file mode 100644
index 00000000000..c343d6ee98a
--- /dev/null
+++ b/app/assets/images/emoji/juggling_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/kaaba.png b/app/assets/images/emoji/kaaba.png
new file mode 100644
index 00000000000..1778c1138e4
--- /dev/null
+++ b/app/assets/images/emoji/kaaba.png
Binary files differ
diff --git a/app/assets/images/emoji/key.png b/app/assets/images/emoji/key.png
new file mode 100644
index 00000000000..319cd1b884c
--- /dev/null
+++ b/app/assets/images/emoji/key.png
Binary files differ
diff --git a/app/assets/images/emoji/key2.png b/app/assets/images/emoji/key2.png
new file mode 100644
index 00000000000..e11d706c6c8
--- /dev/null
+++ b/app/assets/images/emoji/key2.png
Binary files differ
diff --git a/app/assets/images/emoji/keyboard.png b/app/assets/images/emoji/keyboard.png
new file mode 100644
index 00000000000..75027cb9af7
--- /dev/null
+++ b/app/assets/images/emoji/keyboard.png
Binary files differ
diff --git a/app/assets/images/emoji/kimono.png b/app/assets/images/emoji/kimono.png
new file mode 100644
index 00000000000..abe851115d1
--- /dev/null
+++ b/app/assets/images/emoji/kimono.png
Binary files differ
diff --git a/app/assets/images/emoji/kiss.png b/app/assets/images/emoji/kiss.png
new file mode 100644
index 00000000000..85e6dcfc4e8
--- /dev/null
+++ b/app/assets/images/emoji/kiss.png
Binary files differ
diff --git a/app/assets/images/emoji/kiss_mm.png b/app/assets/images/emoji/kiss_mm.png
new file mode 100644
index 00000000000..a9a0edae17c
--- /dev/null
+++ b/app/assets/images/emoji/kiss_mm.png
Binary files differ
diff --git a/app/assets/images/emoji/kiss_ww.png b/app/assets/images/emoji/kiss_ww.png
new file mode 100644
index 00000000000..fdac73cbb1d
--- /dev/null
+++ b/app/assets/images/emoji/kiss_ww.png
Binary files differ
diff --git a/app/assets/images/emoji/kissing.png b/app/assets/images/emoji/kissing.png
new file mode 100644
index 00000000000..39d325fd8e3
--- /dev/null
+++ b/app/assets/images/emoji/kissing.png
Binary files differ
diff --git a/app/assets/images/emoji/kissing_cat.png b/app/assets/images/emoji/kissing_cat.png
new file mode 100644
index 00000000000..6e0bcc77540
--- /dev/null
+++ b/app/assets/images/emoji/kissing_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/kissing_closed_eyes.png b/app/assets/images/emoji/kissing_closed_eyes.png
new file mode 100644
index 00000000000..b684d7d4d6c
--- /dev/null
+++ b/app/assets/images/emoji/kissing_closed_eyes.png
Binary files differ
diff --git a/app/assets/images/emoji/kissing_heart.png b/app/assets/images/emoji/kissing_heart.png
new file mode 100644
index 00000000000..0ff808fd614
--- /dev/null
+++ b/app/assets/images/emoji/kissing_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/kissing_smiling_eyes.png b/app/assets/images/emoji/kissing_smiling_eyes.png
new file mode 100644
index 00000000000..e181f17099d
--- /dev/null
+++ b/app/assets/images/emoji/kissing_smiling_eyes.png
Binary files differ
diff --git a/app/assets/images/emoji/kiwi.png b/app/assets/images/emoji/kiwi.png
new file mode 100644
index 00000000000..dfbd8258074
--- /dev/null
+++ b/app/assets/images/emoji/kiwi.png
Binary files differ
diff --git a/app/assets/images/emoji/knife.png b/app/assets/images/emoji/knife.png
new file mode 100644
index 00000000000..1acb9f3077b
--- /dev/null
+++ b/app/assets/images/emoji/knife.png
Binary files differ
diff --git a/app/assets/images/emoji/koala.png b/app/assets/images/emoji/koala.png
new file mode 100644
index 00000000000..a0aa437a98c
--- /dev/null
+++ b/app/assets/images/emoji/koala.png
Binary files differ
diff --git a/app/assets/images/emoji/koko.png b/app/assets/images/emoji/koko.png
new file mode 100644
index 00000000000..6450eb44d90
--- /dev/null
+++ b/app/assets/images/emoji/koko.png
Binary files differ
diff --git a/app/assets/images/emoji/label.png b/app/assets/images/emoji/label.png
new file mode 100644
index 00000000000..d41c9b4f1e1
--- /dev/null
+++ b/app/assets/images/emoji/label.png
Binary files differ
diff --git a/app/assets/images/emoji/large_blue_circle.png b/app/assets/images/emoji/large_blue_circle.png
new file mode 100644
index 00000000000..84078ef3127
--- /dev/null
+++ b/app/assets/images/emoji/large_blue_circle.png
Binary files differ
diff --git a/app/assets/images/emoji/large_blue_diamond.png b/app/assets/images/emoji/large_blue_diamond.png
new file mode 100644
index 00000000000..416a58bd5a8
--- /dev/null
+++ b/app/assets/images/emoji/large_blue_diamond.png
Binary files differ
diff --git a/app/assets/images/emoji/large_orange_diamond.png b/app/assets/images/emoji/large_orange_diamond.png
new file mode 100644
index 00000000000..73ff0ac36c8
--- /dev/null
+++ b/app/assets/images/emoji/large_orange_diamond.png
Binary files differ
diff --git a/app/assets/images/emoji/last_quarter_moon.png b/app/assets/images/emoji/last_quarter_moon.png
new file mode 100644
index 00000000000..0842a0dd408
--- /dev/null
+++ b/app/assets/images/emoji/last_quarter_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/last_quarter_moon_with_face.png b/app/assets/images/emoji/last_quarter_moon_with_face.png
new file mode 100644
index 00000000000..94099343c5d
--- /dev/null
+++ b/app/assets/images/emoji/last_quarter_moon_with_face.png
Binary files differ
diff --git a/app/assets/images/emoji/laughing.png b/app/assets/images/emoji/laughing.png
new file mode 100644
index 00000000000..d94e9505ba1
--- /dev/null
+++ b/app/assets/images/emoji/laughing.png
Binary files differ
diff --git a/app/assets/images/emoji/leaves.png b/app/assets/images/emoji/leaves.png
new file mode 100644
index 00000000000..1e43e1af820
--- /dev/null
+++ b/app/assets/images/emoji/leaves.png
Binary files differ
diff --git a/app/assets/images/emoji/ledger.png b/app/assets/images/emoji/ledger.png
new file mode 100644
index 00000000000..13e7561a4bd
--- /dev/null
+++ b/app/assets/images/emoji/ledger.png
Binary files differ
diff --git a/app/assets/images/emoji/left_facing_fist.png b/app/assets/images/emoji/left_facing_fist.png
new file mode 100644
index 00000000000..a9d9fd8d59c
--- /dev/null
+++ b/app/assets/images/emoji/left_facing_fist.png
Binary files differ
diff --git a/app/assets/images/emoji/left_facing_fist_tone1.png b/app/assets/images/emoji/left_facing_fist_tone1.png
new file mode 100644
index 00000000000..1262a6b4b69
--- /dev/null
+++ b/app/assets/images/emoji/left_facing_fist_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/left_facing_fist_tone2.png b/app/assets/images/emoji/left_facing_fist_tone2.png
new file mode 100644
index 00000000000..40bf70b82b2
--- /dev/null
+++ b/app/assets/images/emoji/left_facing_fist_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/left_facing_fist_tone3.png b/app/assets/images/emoji/left_facing_fist_tone3.png
new file mode 100644
index 00000000000..93f58145111
--- /dev/null
+++ b/app/assets/images/emoji/left_facing_fist_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/left_facing_fist_tone4.png b/app/assets/images/emoji/left_facing_fist_tone4.png
new file mode 100644
index 00000000000..d82b5ec91f0
--- /dev/null
+++ b/app/assets/images/emoji/left_facing_fist_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/left_facing_fist_tone5.png b/app/assets/images/emoji/left_facing_fist_tone5.png
new file mode 100644
index 00000000000..09ae4cd492b
--- /dev/null
+++ b/app/assets/images/emoji/left_facing_fist_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/left_luggage.png b/app/assets/images/emoji/left_luggage.png
new file mode 100644
index 00000000000..887b23f3f25
--- /dev/null
+++ b/app/assets/images/emoji/left_luggage.png
Binary files differ
diff --git a/app/assets/images/emoji/left_right_arrow.png b/app/assets/images/emoji/left_right_arrow.png
new file mode 100644
index 00000000000..7937f24f2ac
--- /dev/null
+++ b/app/assets/images/emoji/left_right_arrow.png
Binary files differ
diff --git a/app/assets/images/emoji/leftwards_arrow_with_hook.png b/app/assets/images/emoji/leftwards_arrow_with_hook.png
new file mode 100644
index 00000000000..ba45c2ad9e9
--- /dev/null
+++ b/app/assets/images/emoji/leftwards_arrow_with_hook.png
Binary files differ
diff --git a/app/assets/images/emoji/lemon.png b/app/assets/images/emoji/lemon.png
new file mode 100644
index 00000000000..9a7d95ca220
--- /dev/null
+++ b/app/assets/images/emoji/lemon.png
Binary files differ
diff --git a/app/assets/images/emoji/leo.png b/app/assets/images/emoji/leo.png
new file mode 100644
index 00000000000..30158d34de9
--- /dev/null
+++ b/app/assets/images/emoji/leo.png
Binary files differ
diff --git a/app/assets/images/emoji/leopard.png b/app/assets/images/emoji/leopard.png
new file mode 100644
index 00000000000..8aac3d49448
--- /dev/null
+++ b/app/assets/images/emoji/leopard.png
Binary files differ
diff --git a/app/assets/images/emoji/level_slider.png b/app/assets/images/emoji/level_slider.png
new file mode 100644
index 00000000000..720a3b34119
--- /dev/null
+++ b/app/assets/images/emoji/level_slider.png
Binary files differ
diff --git a/app/assets/images/emoji/levitate.png b/app/assets/images/emoji/levitate.png
new file mode 100644
index 00000000000..3dc315a3d91
--- /dev/null
+++ b/app/assets/images/emoji/levitate.png
Binary files differ
diff --git a/app/assets/images/emoji/libra.png b/app/assets/images/emoji/libra.png
new file mode 100644
index 00000000000..8fd133a357c
--- /dev/null
+++ b/app/assets/images/emoji/libra.png
Binary files differ
diff --git a/app/assets/images/emoji/lifter.png b/app/assets/images/emoji/lifter.png
new file mode 100644
index 00000000000..afdeaa476af
--- /dev/null
+++ b/app/assets/images/emoji/lifter.png
Binary files differ
diff --git a/app/assets/images/emoji/lifter_tone1.png b/app/assets/images/emoji/lifter_tone1.png
new file mode 100644
index 00000000000..febaad123ec
--- /dev/null
+++ b/app/assets/images/emoji/lifter_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/lifter_tone2.png b/app/assets/images/emoji/lifter_tone2.png
new file mode 100644
index 00000000000..27ae794a18e
--- /dev/null
+++ b/app/assets/images/emoji/lifter_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/lifter_tone3.png b/app/assets/images/emoji/lifter_tone3.png
new file mode 100644
index 00000000000..45c4c22c709
--- /dev/null
+++ b/app/assets/images/emoji/lifter_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/lifter_tone4.png b/app/assets/images/emoji/lifter_tone4.png
new file mode 100644
index 00000000000..67dd21d2464
--- /dev/null
+++ b/app/assets/images/emoji/lifter_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/lifter_tone5.png b/app/assets/images/emoji/lifter_tone5.png
new file mode 100644
index 00000000000..fa0152038b6
--- /dev/null
+++ b/app/assets/images/emoji/lifter_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/light_rail.png b/app/assets/images/emoji/light_rail.png
new file mode 100644
index 00000000000..a64829f5078
--- /dev/null
+++ b/app/assets/images/emoji/light_rail.png
Binary files differ
diff --git a/app/assets/images/emoji/link.png b/app/assets/images/emoji/link.png
new file mode 100644
index 00000000000..ae20f0f8eec
--- /dev/null
+++ b/app/assets/images/emoji/link.png
Binary files differ
diff --git a/app/assets/images/emoji/lion_face.png b/app/assets/images/emoji/lion_face.png
new file mode 100644
index 00000000000..5062ab47ecf
--- /dev/null
+++ b/app/assets/images/emoji/lion_face.png
Binary files differ
diff --git a/app/assets/images/emoji/lips.png b/app/assets/images/emoji/lips.png
new file mode 100644
index 00000000000..35f3cc2006f
--- /dev/null
+++ b/app/assets/images/emoji/lips.png
Binary files differ
diff --git a/app/assets/images/emoji/lipstick.png b/app/assets/images/emoji/lipstick.png
new file mode 100644
index 00000000000..61a0c084c99
--- /dev/null
+++ b/app/assets/images/emoji/lipstick.png
Binary files differ
diff --git a/app/assets/images/emoji/lizard.png b/app/assets/images/emoji/lizard.png
new file mode 100644
index 00000000000..8363876050e
--- /dev/null
+++ b/app/assets/images/emoji/lizard.png
Binary files differ
diff --git a/app/assets/images/emoji/lock.png b/app/assets/images/emoji/lock.png
new file mode 100644
index 00000000000..5a739c46644
--- /dev/null
+++ b/app/assets/images/emoji/lock.png
Binary files differ
diff --git a/app/assets/images/emoji/lock_with_ink_pen.png b/app/assets/images/emoji/lock_with_ink_pen.png
new file mode 100644
index 00000000000..19a07d162fb
--- /dev/null
+++ b/app/assets/images/emoji/lock_with_ink_pen.png
Binary files differ
diff --git a/app/assets/images/emoji/lollipop.png b/app/assets/images/emoji/lollipop.png
new file mode 100644
index 00000000000..ad76d7bf916
--- /dev/null
+++ b/app/assets/images/emoji/lollipop.png
Binary files differ
diff --git a/app/assets/images/emoji/loop.png b/app/assets/images/emoji/loop.png
new file mode 100644
index 00000000000..0b82c8fe315
--- /dev/null
+++ b/app/assets/images/emoji/loop.png
Binary files differ
diff --git a/app/assets/images/emoji/loud_sound.png b/app/assets/images/emoji/loud_sound.png
new file mode 100644
index 00000000000..8370033a539
--- /dev/null
+++ b/app/assets/images/emoji/loud_sound.png
Binary files differ
diff --git a/app/assets/images/emoji/loudspeaker.png b/app/assets/images/emoji/loudspeaker.png
new file mode 100644
index 00000000000..5fd76a95b82
--- /dev/null
+++ b/app/assets/images/emoji/loudspeaker.png
Binary files differ
diff --git a/app/assets/images/emoji/love_hotel.png b/app/assets/images/emoji/love_hotel.png
new file mode 100644
index 00000000000..5e136be6f8b
--- /dev/null
+++ b/app/assets/images/emoji/love_hotel.png
Binary files differ
diff --git a/app/assets/images/emoji/love_letter.png b/app/assets/images/emoji/love_letter.png
new file mode 100644
index 00000000000..3c3c767e784
--- /dev/null
+++ b/app/assets/images/emoji/love_letter.png
Binary files differ
diff --git a/app/assets/images/emoji/low_brightness.png b/app/assets/images/emoji/low_brightness.png
new file mode 100644
index 00000000000..543011d3961
--- /dev/null
+++ b/app/assets/images/emoji/low_brightness.png
Binary files differ
diff --git a/app/assets/images/emoji/lying_face.png b/app/assets/images/emoji/lying_face.png
new file mode 100644
index 00000000000..02827e2628b
--- /dev/null
+++ b/app/assets/images/emoji/lying_face.png
Binary files differ
diff --git a/app/assets/images/emoji/m.png b/app/assets/images/emoji/m.png
new file mode 100644
index 00000000000..8a3506fc1d7
--- /dev/null
+++ b/app/assets/images/emoji/m.png
Binary files differ
diff --git a/app/assets/images/emoji/mag.png b/app/assets/images/emoji/mag.png
new file mode 100644
index 00000000000..55487156ac6
--- /dev/null
+++ b/app/assets/images/emoji/mag.png
Binary files differ
diff --git a/app/assets/images/emoji/mag_right.png b/app/assets/images/emoji/mag_right.png
new file mode 100644
index 00000000000..0f4b1bca876
--- /dev/null
+++ b/app/assets/images/emoji/mag_right.png
Binary files differ
diff --git a/app/assets/images/emoji/mahjong.png b/app/assets/images/emoji/mahjong.png
new file mode 100644
index 00000000000..66fd32025b2
--- /dev/null
+++ b/app/assets/images/emoji/mahjong.png
Binary files differ
diff --git a/app/assets/images/emoji/mailbox.png b/app/assets/images/emoji/mailbox.png
new file mode 100644
index 00000000000..ef5174e40dd
--- /dev/null
+++ b/app/assets/images/emoji/mailbox.png
Binary files differ
diff --git a/app/assets/images/emoji/mailbox_closed.png b/app/assets/images/emoji/mailbox_closed.png
new file mode 100644
index 00000000000..ddc705db0d8
--- /dev/null
+++ b/app/assets/images/emoji/mailbox_closed.png
Binary files differ
diff --git a/app/assets/images/emoji/mailbox_with_mail.png b/app/assets/images/emoji/mailbox_with_mail.png
new file mode 100644
index 00000000000..5460616a5b1
--- /dev/null
+++ b/app/assets/images/emoji/mailbox_with_mail.png
Binary files differ
diff --git a/app/assets/images/emoji/mailbox_with_no_mail.png b/app/assets/images/emoji/mailbox_with_no_mail.png
new file mode 100644
index 00000000000..f9aeee6b15a
--- /dev/null
+++ b/app/assets/images/emoji/mailbox_with_no_mail.png
Binary files differ
diff --git a/app/assets/images/emoji/man.png b/app/assets/images/emoji/man.png
new file mode 100644
index 00000000000..857a02e5146
--- /dev/null
+++ b/app/assets/images/emoji/man.png
Binary files differ
diff --git a/app/assets/images/emoji/man_dancing.png b/app/assets/images/emoji/man_dancing.png
new file mode 100644
index 00000000000..ccff3bede5a
--- /dev/null
+++ b/app/assets/images/emoji/man_dancing.png
Binary files differ
diff --git a/app/assets/images/emoji/man_dancing_tone1.png b/app/assets/images/emoji/man_dancing_tone1.png
new file mode 100644
index 00000000000..e0b9f82d905
--- /dev/null
+++ b/app/assets/images/emoji/man_dancing_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/man_dancing_tone2.png b/app/assets/images/emoji/man_dancing_tone2.png
new file mode 100644
index 00000000000..a5beed56e2e
--- /dev/null
+++ b/app/assets/images/emoji/man_dancing_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/man_dancing_tone3.png b/app/assets/images/emoji/man_dancing_tone3.png
new file mode 100644
index 00000000000..2fa20180a6e
--- /dev/null
+++ b/app/assets/images/emoji/man_dancing_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/man_dancing_tone4.png b/app/assets/images/emoji/man_dancing_tone4.png
new file mode 100644
index 00000000000..bd3528c83ba
--- /dev/null
+++ b/app/assets/images/emoji/man_dancing_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/man_dancing_tone5.png b/app/assets/images/emoji/man_dancing_tone5.png
new file mode 100644
index 00000000000..41fd4f880c9
--- /dev/null
+++ b/app/assets/images/emoji/man_dancing_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/man_in_tuxedo.png b/app/assets/images/emoji/man_in_tuxedo.png
new file mode 100644
index 00000000000..5f7e9303f89
--- /dev/null
+++ b/app/assets/images/emoji/man_in_tuxedo.png
Binary files differ
diff --git a/app/assets/images/emoji/man_in_tuxedo_tone1.png b/app/assets/images/emoji/man_in_tuxedo_tone1.png
new file mode 100644
index 00000000000..7b6b3acd99b
--- /dev/null
+++ b/app/assets/images/emoji/man_in_tuxedo_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/man_in_tuxedo_tone2.png b/app/assets/images/emoji/man_in_tuxedo_tone2.png
new file mode 100644
index 00000000000..7975191b360
--- /dev/null
+++ b/app/assets/images/emoji/man_in_tuxedo_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/man_in_tuxedo_tone3.png b/app/assets/images/emoji/man_in_tuxedo_tone3.png
new file mode 100644
index 00000000000..a2816f600ae
--- /dev/null
+++ b/app/assets/images/emoji/man_in_tuxedo_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/man_in_tuxedo_tone4.png b/app/assets/images/emoji/man_in_tuxedo_tone4.png
new file mode 100644
index 00000000000..ea8291760f9
--- /dev/null
+++ b/app/assets/images/emoji/man_in_tuxedo_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/man_in_tuxedo_tone5.png b/app/assets/images/emoji/man_in_tuxedo_tone5.png
new file mode 100644
index 00000000000..c743e05fc5e
--- /dev/null
+++ b/app/assets/images/emoji/man_in_tuxedo_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/man_tone1.png b/app/assets/images/emoji/man_tone1.png
new file mode 100644
index 00000000000..bb86e963a80
--- /dev/null
+++ b/app/assets/images/emoji/man_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/man_tone2.png b/app/assets/images/emoji/man_tone2.png
new file mode 100644
index 00000000000..fdeeaff46f5
--- /dev/null
+++ b/app/assets/images/emoji/man_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/man_tone3.png b/app/assets/images/emoji/man_tone3.png
new file mode 100644
index 00000000000..7ae0b5df9cf
--- /dev/null
+++ b/app/assets/images/emoji/man_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/man_tone4.png b/app/assets/images/emoji/man_tone4.png
new file mode 100644
index 00000000000..db14cde99b8
--- /dev/null
+++ b/app/assets/images/emoji/man_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/man_tone5.png b/app/assets/images/emoji/man_tone5.png
new file mode 100644
index 00000000000..7c67a70529c
--- /dev/null
+++ b/app/assets/images/emoji/man_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_gua_pi_mao.png b/app/assets/images/emoji/man_with_gua_pi_mao.png
new file mode 100644
index 00000000000..7841e13608d
--- /dev/null
+++ b/app/assets/images/emoji/man_with_gua_pi_mao.png
Binary files differ
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
new file mode 100644
index 00000000000..5b7b3def19c
--- /dev/null
+++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png
Binary files differ
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
new file mode 100644
index 00000000000..c8b9cf87f4b
--- /dev/null
+++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png
Binary files differ
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
new file mode 100644
index 00000000000..effdd0c4c84
--- /dev/null
+++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png
Binary files differ
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
new file mode 100644
index 00000000000..f885ff46fa1
--- /dev/null
+++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png
Binary files differ
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
new file mode 100644
index 00000000000..a6d55ca1380
--- /dev/null
+++ b/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_turban.png b/app/assets/images/emoji/man_with_turban.png
new file mode 100644
index 00000000000..51cf047f966
--- /dev/null
+++ b/app/assets/images/emoji/man_with_turban.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_turban_tone1.png b/app/assets/images/emoji/man_with_turban_tone1.png
new file mode 100644
index 00000000000..1e12ee4b231
--- /dev/null
+++ b/app/assets/images/emoji/man_with_turban_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_turban_tone2.png b/app/assets/images/emoji/man_with_turban_tone2.png
new file mode 100644
index 00000000000..37de4cceb23
--- /dev/null
+++ b/app/assets/images/emoji/man_with_turban_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_turban_tone3.png b/app/assets/images/emoji/man_with_turban_tone3.png
new file mode 100644
index 00000000000..f607afd3450
--- /dev/null
+++ b/app/assets/images/emoji/man_with_turban_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_turban_tone4.png b/app/assets/images/emoji/man_with_turban_tone4.png
new file mode 100644
index 00000000000..c05695888af
--- /dev/null
+++ b/app/assets/images/emoji/man_with_turban_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/man_with_turban_tone5.png b/app/assets/images/emoji/man_with_turban_tone5.png
new file mode 100644
index 00000000000..4b4ff64720b
--- /dev/null
+++ b/app/assets/images/emoji/man_with_turban_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/mans_shoe.png b/app/assets/images/emoji/mans_shoe.png
new file mode 100644
index 00000000000..4bf7541032c
--- /dev/null
+++ b/app/assets/images/emoji/mans_shoe.png
Binary files differ
diff --git a/app/assets/images/emoji/map.png b/app/assets/images/emoji/map.png
new file mode 100644
index 00000000000..15efe32c798
--- /dev/null
+++ b/app/assets/images/emoji/map.png
Binary files differ
diff --git a/app/assets/images/emoji/maple_leaf.png b/app/assets/images/emoji/maple_leaf.png
new file mode 100644
index 00000000000..c49acea67f7
--- /dev/null
+++ b/app/assets/images/emoji/maple_leaf.png
Binary files differ
diff --git a/app/assets/images/emoji/martial_arts_uniform.png b/app/assets/images/emoji/martial_arts_uniform.png
new file mode 100644
index 00000000000..8d6114761f6
--- /dev/null
+++ b/app/assets/images/emoji/martial_arts_uniform.png
Binary files differ
diff --git a/app/assets/images/emoji/mask.png b/app/assets/images/emoji/mask.png
new file mode 100644
index 00000000000..1e800acd1c0
--- /dev/null
+++ b/app/assets/images/emoji/mask.png
Binary files differ
diff --git a/app/assets/images/emoji/massage.png b/app/assets/images/emoji/massage.png
new file mode 100644
index 00000000000..b91d845e374
--- /dev/null
+++ b/app/assets/images/emoji/massage.png
Binary files differ
diff --git a/app/assets/images/emoji/massage_tone1.png b/app/assets/images/emoji/massage_tone1.png
new file mode 100644
index 00000000000..e0f415d3186
--- /dev/null
+++ b/app/assets/images/emoji/massage_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/massage_tone2.png b/app/assets/images/emoji/massage_tone2.png
new file mode 100644
index 00000000000..0bb244a270b
--- /dev/null
+++ b/app/assets/images/emoji/massage_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/massage_tone3.png b/app/assets/images/emoji/massage_tone3.png
new file mode 100644
index 00000000000..a117ee81a22
--- /dev/null
+++ b/app/assets/images/emoji/massage_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/massage_tone4.png b/app/assets/images/emoji/massage_tone4.png
new file mode 100644
index 00000000000..6f42ab017f4
--- /dev/null
+++ b/app/assets/images/emoji/massage_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/massage_tone5.png b/app/assets/images/emoji/massage_tone5.png
new file mode 100644
index 00000000000..6a388c0d0b5
--- /dev/null
+++ b/app/assets/images/emoji/massage_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/meat_on_bone.png b/app/assets/images/emoji/meat_on_bone.png
new file mode 100644
index 00000000000..b20a59d1690
--- /dev/null
+++ b/app/assets/images/emoji/meat_on_bone.png
Binary files differ
diff --git a/app/assets/images/emoji/medal.png b/app/assets/images/emoji/medal.png
new file mode 100644
index 00000000000..b85896b14da
--- /dev/null
+++ b/app/assets/images/emoji/medal.png
Binary files differ
diff --git a/app/assets/images/emoji/mega.png b/app/assets/images/emoji/mega.png
new file mode 100644
index 00000000000..4e6735188e3
--- /dev/null
+++ b/app/assets/images/emoji/mega.png
Binary files differ
diff --git a/app/assets/images/emoji/melon.png b/app/assets/images/emoji/melon.png
new file mode 100644
index 00000000000..c01232d419d
--- /dev/null
+++ b/app/assets/images/emoji/melon.png
Binary files differ
diff --git a/app/assets/images/emoji/menorah.png b/app/assets/images/emoji/menorah.png
new file mode 100644
index 00000000000..b4297362869
--- /dev/null
+++ b/app/assets/images/emoji/menorah.png
Binary files differ
diff --git a/app/assets/images/emoji/mens.png b/app/assets/images/emoji/mens.png
new file mode 100644
index 00000000000..f5a1e1ba0cd
--- /dev/null
+++ b/app/assets/images/emoji/mens.png
Binary files differ
diff --git a/app/assets/images/emoji/metal.png b/app/assets/images/emoji/metal.png
new file mode 100644
index 00000000000..4aa6e7e0a44
--- /dev/null
+++ b/app/assets/images/emoji/metal.png
Binary files differ
diff --git a/app/assets/images/emoji/metal_tone1.png b/app/assets/images/emoji/metal_tone1.png
new file mode 100644
index 00000000000..c080d2addbd
--- /dev/null
+++ b/app/assets/images/emoji/metal_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/metal_tone2.png b/app/assets/images/emoji/metal_tone2.png
new file mode 100644
index 00000000000..12313529bcf
--- /dev/null
+++ b/app/assets/images/emoji/metal_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/metal_tone3.png b/app/assets/images/emoji/metal_tone3.png
new file mode 100644
index 00000000000..ca9be6ae67b
--- /dev/null
+++ b/app/assets/images/emoji/metal_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/metal_tone4.png b/app/assets/images/emoji/metal_tone4.png
new file mode 100644
index 00000000000..abe28cbf890
--- /dev/null
+++ b/app/assets/images/emoji/metal_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/metal_tone5.png b/app/assets/images/emoji/metal_tone5.png
new file mode 100644
index 00000000000..0c6b5dd34ed
--- /dev/null
+++ b/app/assets/images/emoji/metal_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/metro.png b/app/assets/images/emoji/metro.png
new file mode 100644
index 00000000000..1de8f0551f3
--- /dev/null
+++ b/app/assets/images/emoji/metro.png
Binary files differ
diff --git a/app/assets/images/emoji/microphone.png b/app/assets/images/emoji/microphone.png
new file mode 100644
index 00000000000..d4e6b0def25
--- /dev/null
+++ b/app/assets/images/emoji/microphone.png
Binary files differ
diff --git a/app/assets/images/emoji/microphone2.png b/app/assets/images/emoji/microphone2.png
new file mode 100644
index 00000000000..cd9167654ff
--- /dev/null
+++ b/app/assets/images/emoji/microphone2.png
Binary files differ
diff --git a/app/assets/images/emoji/microscope.png b/app/assets/images/emoji/microscope.png
new file mode 100644
index 00000000000..90f5acf6a78
--- /dev/null
+++ b/app/assets/images/emoji/microscope.png
Binary files differ
diff --git a/app/assets/images/emoji/middle_finger.png b/app/assets/images/emoji/middle_finger.png
new file mode 100644
index 00000000000..697f7a25eb2
--- /dev/null
+++ b/app/assets/images/emoji/middle_finger.png
Binary files differ
diff --git a/app/assets/images/emoji/middle_finger_tone1.png b/app/assets/images/emoji/middle_finger_tone1.png
new file mode 100644
index 00000000000..61ef12a1548
--- /dev/null
+++ b/app/assets/images/emoji/middle_finger_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/middle_finger_tone2.png b/app/assets/images/emoji/middle_finger_tone2.png
new file mode 100644
index 00000000000..c31a69be9af
--- /dev/null
+++ b/app/assets/images/emoji/middle_finger_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/middle_finger_tone3.png b/app/assets/images/emoji/middle_finger_tone3.png
new file mode 100644
index 00000000000..73ac216ce63
--- /dev/null
+++ b/app/assets/images/emoji/middle_finger_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/middle_finger_tone4.png b/app/assets/images/emoji/middle_finger_tone4.png
new file mode 100644
index 00000000000..80b8ab7706d
--- /dev/null
+++ b/app/assets/images/emoji/middle_finger_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/middle_finger_tone5.png b/app/assets/images/emoji/middle_finger_tone5.png
new file mode 100644
index 00000000000..a8826b196e8
--- /dev/null
+++ b/app/assets/images/emoji/middle_finger_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/military_medal.png b/app/assets/images/emoji/military_medal.png
new file mode 100644
index 00000000000..ecd3fb03584
--- /dev/null
+++ b/app/assets/images/emoji/military_medal.png
Binary files differ
diff --git a/app/assets/images/emoji/milk.png b/app/assets/images/emoji/milk.png
new file mode 100644
index 00000000000..e4fcf2e64f3
--- /dev/null
+++ b/app/assets/images/emoji/milk.png
Binary files differ
diff --git a/app/assets/images/emoji/milky_way.png b/app/assets/images/emoji/milky_way.png
new file mode 100644
index 00000000000..b2b8ac59c5e
--- /dev/null
+++ b/app/assets/images/emoji/milky_way.png
Binary files differ
diff --git a/app/assets/images/emoji/minibus.png b/app/assets/images/emoji/minibus.png
new file mode 100644
index 00000000000..c60dd8f47ab
--- /dev/null
+++ b/app/assets/images/emoji/minibus.png
Binary files differ
diff --git a/app/assets/images/emoji/minidisc.png b/app/assets/images/emoji/minidisc.png
new file mode 100644
index 00000000000..9fa94cfbe74
--- /dev/null
+++ b/app/assets/images/emoji/minidisc.png
Binary files differ
diff --git a/app/assets/images/emoji/mobile_phone_off.png b/app/assets/images/emoji/mobile_phone_off.png
new file mode 100644
index 00000000000..8b661ec1c94
--- /dev/null
+++ b/app/assets/images/emoji/mobile_phone_off.png
Binary files differ
diff --git a/app/assets/images/emoji/money_mouth.png b/app/assets/images/emoji/money_mouth.png
new file mode 100644
index 00000000000..75fd1e90cb0
--- /dev/null
+++ b/app/assets/images/emoji/money_mouth.png
Binary files differ
diff --git a/app/assets/images/emoji/money_with_wings.png b/app/assets/images/emoji/money_with_wings.png
new file mode 100644
index 00000000000..f022b04b3c2
--- /dev/null
+++ b/app/assets/images/emoji/money_with_wings.png
Binary files differ
diff --git a/app/assets/images/emoji/moneybag.png b/app/assets/images/emoji/moneybag.png
new file mode 100644
index 00000000000..b9296be0902
--- /dev/null
+++ b/app/assets/images/emoji/moneybag.png
Binary files differ
diff --git a/app/assets/images/emoji/monkey.png b/app/assets/images/emoji/monkey.png
new file mode 100644
index 00000000000..9fae29448e3
--- /dev/null
+++ b/app/assets/images/emoji/monkey.png
Binary files differ
diff --git a/app/assets/images/emoji/monkey_face.png b/app/assets/images/emoji/monkey_face.png
new file mode 100644
index 00000000000..7cab9b91a82
--- /dev/null
+++ b/app/assets/images/emoji/monkey_face.png
Binary files differ
diff --git a/app/assets/images/emoji/monorail.png b/app/assets/images/emoji/monorail.png
new file mode 100644
index 00000000000..11eb1f574bf
--- /dev/null
+++ b/app/assets/images/emoji/monorail.png
Binary files differ
diff --git a/app/assets/images/emoji/mortar_board.png b/app/assets/images/emoji/mortar_board.png
new file mode 100644
index 00000000000..8b17ddd9d00
--- /dev/null
+++ b/app/assets/images/emoji/mortar_board.png
Binary files differ
diff --git a/app/assets/images/emoji/mosque.png b/app/assets/images/emoji/mosque.png
new file mode 100644
index 00000000000..ef770b26d96
--- /dev/null
+++ b/app/assets/images/emoji/mosque.png
Binary files differ
diff --git a/app/assets/images/emoji/motor_scooter.png b/app/assets/images/emoji/motor_scooter.png
new file mode 100644
index 00000000000..c5afa72d807
--- /dev/null
+++ b/app/assets/images/emoji/motor_scooter.png
Binary files differ
diff --git a/app/assets/images/emoji/motorboat.png b/app/assets/images/emoji/motorboat.png
new file mode 100644
index 00000000000..0506db1a40f
--- /dev/null
+++ b/app/assets/images/emoji/motorboat.png
Binary files differ
diff --git a/app/assets/images/emoji/motorcycle.png b/app/assets/images/emoji/motorcycle.png
new file mode 100644
index 00000000000..3d1d567e8ec
--- /dev/null
+++ b/app/assets/images/emoji/motorcycle.png
Binary files differ
diff --git a/app/assets/images/emoji/motorway.png b/app/assets/images/emoji/motorway.png
new file mode 100644
index 00000000000..8c3d3d03e3f
--- /dev/null
+++ b/app/assets/images/emoji/motorway.png
Binary files differ
diff --git a/app/assets/images/emoji/mount_fuji.png b/app/assets/images/emoji/mount_fuji.png
new file mode 100644
index 00000000000..88a54752458
--- /dev/null
+++ b/app/assets/images/emoji/mount_fuji.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain.png b/app/assets/images/emoji/mountain.png
new file mode 100644
index 00000000000..6722ebdd294
--- /dev/null
+++ b/app/assets/images/emoji/mountain.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_bicyclist.png b/app/assets/images/emoji/mountain_bicyclist.png
new file mode 100644
index 00000000000..41d3dc3ac6f
--- /dev/null
+++ b/app/assets/images/emoji/mountain_bicyclist.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_bicyclist_tone1.png b/app/assets/images/emoji/mountain_bicyclist_tone1.png
new file mode 100644
index 00000000000..e9f1daf5e40
--- /dev/null
+++ b/app/assets/images/emoji/mountain_bicyclist_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_bicyclist_tone2.png b/app/assets/images/emoji/mountain_bicyclist_tone2.png
new file mode 100644
index 00000000000..555b9e29d4d
--- /dev/null
+++ b/app/assets/images/emoji/mountain_bicyclist_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_bicyclist_tone3.png b/app/assets/images/emoji/mountain_bicyclist_tone3.png
new file mode 100644
index 00000000000..7df5508ec8c
--- /dev/null
+++ b/app/assets/images/emoji/mountain_bicyclist_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_bicyclist_tone4.png b/app/assets/images/emoji/mountain_bicyclist_tone4.png
new file mode 100644
index 00000000000..f94b3450697
--- /dev/null
+++ b/app/assets/images/emoji/mountain_bicyclist_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_bicyclist_tone5.png b/app/assets/images/emoji/mountain_bicyclist_tone5.png
new file mode 100644
index 00000000000..16a45861e1f
--- /dev/null
+++ b/app/assets/images/emoji/mountain_bicyclist_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_cableway.png b/app/assets/images/emoji/mountain_cableway.png
new file mode 100644
index 00000000000..1dea73ca53b
--- /dev/null
+++ b/app/assets/images/emoji/mountain_cableway.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_railway.png b/app/assets/images/emoji/mountain_railway.png
new file mode 100644
index 00000000000..ade2218e469
--- /dev/null
+++ b/app/assets/images/emoji/mountain_railway.png
Binary files differ
diff --git a/app/assets/images/emoji/mountain_snow.png b/app/assets/images/emoji/mountain_snow.png
new file mode 100644
index 00000000000..76e1cfd8313
--- /dev/null
+++ b/app/assets/images/emoji/mountain_snow.png
Binary files differ
diff --git a/app/assets/images/emoji/mouse.png b/app/assets/images/emoji/mouse.png
new file mode 100644
index 00000000000..50afcd3262e
--- /dev/null
+++ b/app/assets/images/emoji/mouse.png
Binary files differ
diff --git a/app/assets/images/emoji/mouse2.png b/app/assets/images/emoji/mouse2.png
new file mode 100644
index 00000000000..20fb041f09f
--- /dev/null
+++ b/app/assets/images/emoji/mouse2.png
Binary files differ
diff --git a/app/assets/images/emoji/mouse_three_button.png b/app/assets/images/emoji/mouse_three_button.png
new file mode 100644
index 00000000000..e84e96ff6e8
--- /dev/null
+++ b/app/assets/images/emoji/mouse_three_button.png
Binary files differ
diff --git a/app/assets/images/emoji/movie_camera.png b/app/assets/images/emoji/movie_camera.png
new file mode 100644
index 00000000000..4e73b130155
--- /dev/null
+++ b/app/assets/images/emoji/movie_camera.png
Binary files differ
diff --git a/app/assets/images/emoji/moyai.png b/app/assets/images/emoji/moyai.png
new file mode 100644
index 00000000000..e6a7779c45b
--- /dev/null
+++ b/app/assets/images/emoji/moyai.png
Binary files differ
diff --git a/app/assets/images/emoji/mrs_claus.png b/app/assets/images/emoji/mrs_claus.png
new file mode 100644
index 00000000000..078f0657f95
--- /dev/null
+++ b/app/assets/images/emoji/mrs_claus.png
Binary files differ
diff --git a/app/assets/images/emoji/mrs_claus_tone1.png b/app/assets/images/emoji/mrs_claus_tone1.png
new file mode 100644
index 00000000000..d8a695d7035
--- /dev/null
+++ b/app/assets/images/emoji/mrs_claus_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/mrs_claus_tone2.png b/app/assets/images/emoji/mrs_claus_tone2.png
new file mode 100644
index 00000000000..0e17e8c51f3
--- /dev/null
+++ b/app/assets/images/emoji/mrs_claus_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/mrs_claus_tone3.png b/app/assets/images/emoji/mrs_claus_tone3.png
new file mode 100644
index 00000000000..c3ee4d1dfae
--- /dev/null
+++ b/app/assets/images/emoji/mrs_claus_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/mrs_claus_tone4.png b/app/assets/images/emoji/mrs_claus_tone4.png
new file mode 100644
index 00000000000..68a556da2fe
--- /dev/null
+++ b/app/assets/images/emoji/mrs_claus_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/mrs_claus_tone5.png b/app/assets/images/emoji/mrs_claus_tone5.png
new file mode 100644
index 00000000000..ccab3c40ff2
--- /dev/null
+++ b/app/assets/images/emoji/mrs_claus_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/muscle.png b/app/assets/images/emoji/muscle.png
new file mode 100644
index 00000000000..7e67c1880f7
--- /dev/null
+++ b/app/assets/images/emoji/muscle.png
Binary files differ
diff --git a/app/assets/images/emoji/muscle_tone1.png b/app/assets/images/emoji/muscle_tone1.png
new file mode 100644
index 00000000000..1522942ce51
--- /dev/null
+++ b/app/assets/images/emoji/muscle_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/muscle_tone2.png b/app/assets/images/emoji/muscle_tone2.png
new file mode 100644
index 00000000000..569c6e832ca
--- /dev/null
+++ b/app/assets/images/emoji/muscle_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/muscle_tone3.png b/app/assets/images/emoji/muscle_tone3.png
new file mode 100644
index 00000000000..0a76b00fa89
--- /dev/null
+++ b/app/assets/images/emoji/muscle_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/muscle_tone4.png b/app/assets/images/emoji/muscle_tone4.png
new file mode 100644
index 00000000000..f0cf31328e0
--- /dev/null
+++ b/app/assets/images/emoji/muscle_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/muscle_tone5.png b/app/assets/images/emoji/muscle_tone5.png
new file mode 100644
index 00000000000..4fda92460e8
--- /dev/null
+++ b/app/assets/images/emoji/muscle_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/mushroom.png b/app/assets/images/emoji/mushroom.png
new file mode 100644
index 00000000000..dd85742ba2c
--- /dev/null
+++ b/app/assets/images/emoji/mushroom.png
Binary files differ
diff --git a/app/assets/images/emoji/musical_keyboard.png b/app/assets/images/emoji/musical_keyboard.png
new file mode 100644
index 00000000000..442b7456842
--- /dev/null
+++ b/app/assets/images/emoji/musical_keyboard.png
Binary files differ
diff --git a/app/assets/images/emoji/musical_note.png b/app/assets/images/emoji/musical_note.png
new file mode 100644
index 00000000000..06691ef61bb
--- /dev/null
+++ b/app/assets/images/emoji/musical_note.png
Binary files differ
diff --git a/app/assets/images/emoji/musical_score.png b/app/assets/images/emoji/musical_score.png
new file mode 100644
index 00000000000..47dc05a8ef5
--- /dev/null
+++ b/app/assets/images/emoji/musical_score.png
Binary files differ
diff --git a/app/assets/images/emoji/mute.png b/app/assets/images/emoji/mute.png
new file mode 100644
index 00000000000..7c1788e5075
--- /dev/null
+++ b/app/assets/images/emoji/mute.png
Binary files differ
diff --git a/app/assets/images/emoji/nail_care.png b/app/assets/images/emoji/nail_care.png
new file mode 100644
index 00000000000..aa52af7050d
--- /dev/null
+++ b/app/assets/images/emoji/nail_care.png
Binary files differ
diff --git a/app/assets/images/emoji/nail_care_tone1.png b/app/assets/images/emoji/nail_care_tone1.png
new file mode 100644
index 00000000000..26e883dd244
--- /dev/null
+++ b/app/assets/images/emoji/nail_care_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/nail_care_tone2.png b/app/assets/images/emoji/nail_care_tone2.png
new file mode 100644
index 00000000000..61257b47ea3
--- /dev/null
+++ b/app/assets/images/emoji/nail_care_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/nail_care_tone3.png b/app/assets/images/emoji/nail_care_tone3.png
new file mode 100644
index 00000000000..29871b05f62
--- /dev/null
+++ b/app/assets/images/emoji/nail_care_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/nail_care_tone4.png b/app/assets/images/emoji/nail_care_tone4.png
new file mode 100644
index 00000000000..2881de0b17d
--- /dev/null
+++ b/app/assets/images/emoji/nail_care_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/nail_care_tone5.png b/app/assets/images/emoji/nail_care_tone5.png
new file mode 100644
index 00000000000..a0b7c0a45a6
--- /dev/null
+++ b/app/assets/images/emoji/nail_care_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/name_badge.png b/app/assets/images/emoji/name_badge.png
new file mode 100644
index 00000000000..ec5ee213e20
--- /dev/null
+++ b/app/assets/images/emoji/name_badge.png
Binary files differ
diff --git a/app/assets/images/emoji/nauseated_face.png b/app/assets/images/emoji/nauseated_face.png
new file mode 100644
index 00000000000..a566c109c28
--- /dev/null
+++ b/app/assets/images/emoji/nauseated_face.png
Binary files differ
diff --git a/app/assets/images/emoji/necktie.png b/app/assets/images/emoji/necktie.png
new file mode 100644
index 00000000000..1804e7f3ff3
--- /dev/null
+++ b/app/assets/images/emoji/necktie.png
Binary files differ
diff --git a/app/assets/images/emoji/negative_squared_cross_mark.png b/app/assets/images/emoji/negative_squared_cross_mark.png
new file mode 100644
index 00000000000..dae487f1f98
--- /dev/null
+++ b/app/assets/images/emoji/negative_squared_cross_mark.png
Binary files differ
diff --git a/app/assets/images/emoji/nerd.png b/app/assets/images/emoji/nerd.png
new file mode 100644
index 00000000000..7820bd581dc
--- /dev/null
+++ b/app/assets/images/emoji/nerd.png
Binary files differ
diff --git a/app/assets/images/emoji/neutral_face.png b/app/assets/images/emoji/neutral_face.png
new file mode 100644
index 00000000000..065d193afe4
--- /dev/null
+++ b/app/assets/images/emoji/neutral_face.png
Binary files differ
diff --git a/app/assets/images/emoji/new.png b/app/assets/images/emoji/new.png
new file mode 100644
index 00000000000..b4f85488d1a
--- /dev/null
+++ b/app/assets/images/emoji/new.png
Binary files differ
diff --git a/app/assets/images/emoji/new_moon.png b/app/assets/images/emoji/new_moon.png
new file mode 100644
index 00000000000..ecff72caa42
--- /dev/null
+++ b/app/assets/images/emoji/new_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/new_moon_with_face.png b/app/assets/images/emoji/new_moon_with_face.png
new file mode 100644
index 00000000000..150dd12400c
--- /dev/null
+++ b/app/assets/images/emoji/new_moon_with_face.png
Binary files differ
diff --git a/app/assets/images/emoji/newspaper.png b/app/assets/images/emoji/newspaper.png
new file mode 100644
index 00000000000..2aa8f060bde
--- /dev/null
+++ b/app/assets/images/emoji/newspaper.png
Binary files differ
diff --git a/app/assets/images/emoji/newspaper2.png b/app/assets/images/emoji/newspaper2.png
new file mode 100644
index 00000000000..f64748df2b2
--- /dev/null
+++ b/app/assets/images/emoji/newspaper2.png
Binary files differ
diff --git a/app/assets/images/emoji/ng.png b/app/assets/images/emoji/ng.png
new file mode 100644
index 00000000000..ee8d20f5ebc
--- /dev/null
+++ b/app/assets/images/emoji/ng.png
Binary files differ
diff --git a/app/assets/images/emoji/night_with_stars.png b/app/assets/images/emoji/night_with_stars.png
new file mode 100644
index 00000000000..ca2018f456d
--- /dev/null
+++ b/app/assets/images/emoji/night_with_stars.png
Binary files differ
diff --git a/app/assets/images/emoji/nine.png b/app/assets/images/emoji/nine.png
new file mode 100644
index 00000000000..9fce3d1eca9
--- /dev/null
+++ b/app/assets/images/emoji/nine.png
Binary files differ
diff --git a/app/assets/images/emoji/no_bell.png b/app/assets/images/emoji/no_bell.png
new file mode 100644
index 00000000000..15cb38dd1e7
--- /dev/null
+++ b/app/assets/images/emoji/no_bell.png
Binary files differ
diff --git a/app/assets/images/emoji/no_bicycles.png b/app/assets/images/emoji/no_bicycles.png
new file mode 100644
index 00000000000..19c85421ce9
--- /dev/null
+++ b/app/assets/images/emoji/no_bicycles.png
Binary files differ
diff --git a/app/assets/images/emoji/no_entry.png b/app/assets/images/emoji/no_entry.png
new file mode 100644
index 00000000000..476800fc5c6
--- /dev/null
+++ b/app/assets/images/emoji/no_entry.png
Binary files differ
diff --git a/app/assets/images/emoji/no_entry_sign.png b/app/assets/images/emoji/no_entry_sign.png
new file mode 100644
index 00000000000..d2efd65e74b
--- /dev/null
+++ b/app/assets/images/emoji/no_entry_sign.png
Binary files differ
diff --git a/app/assets/images/emoji/no_good.png b/app/assets/images/emoji/no_good.png
new file mode 100644
index 00000000000..ed577100322
--- /dev/null
+++ b/app/assets/images/emoji/no_good.png
Binary files differ
diff --git a/app/assets/images/emoji/no_good_tone1.png b/app/assets/images/emoji/no_good_tone1.png
new file mode 100644
index 00000000000..5c1a3cbb884
--- /dev/null
+++ b/app/assets/images/emoji/no_good_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/no_good_tone2.png b/app/assets/images/emoji/no_good_tone2.png
new file mode 100644
index 00000000000..80d8021f8fe
--- /dev/null
+++ b/app/assets/images/emoji/no_good_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/no_good_tone3.png b/app/assets/images/emoji/no_good_tone3.png
new file mode 100644
index 00000000000..635e6a00815
--- /dev/null
+++ b/app/assets/images/emoji/no_good_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/no_good_tone4.png b/app/assets/images/emoji/no_good_tone4.png
new file mode 100644
index 00000000000..b96e412a374
--- /dev/null
+++ b/app/assets/images/emoji/no_good_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/no_good_tone5.png b/app/assets/images/emoji/no_good_tone5.png
new file mode 100644
index 00000000000..9a7084afa0a
--- /dev/null
+++ b/app/assets/images/emoji/no_good_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/no_mobile_phones.png b/app/assets/images/emoji/no_mobile_phones.png
new file mode 100644
index 00000000000..7b1ae6ea579
--- /dev/null
+++ b/app/assets/images/emoji/no_mobile_phones.png
Binary files differ
diff --git a/app/assets/images/emoji/no_mouth.png b/app/assets/images/emoji/no_mouth.png
new file mode 100644
index 00000000000..b642f6c1172
--- /dev/null
+++ b/app/assets/images/emoji/no_mouth.png
Binary files differ
diff --git a/app/assets/images/emoji/no_pedestrians.png b/app/assets/images/emoji/no_pedestrians.png
new file mode 100644
index 00000000000..286aa577a23
--- /dev/null
+++ b/app/assets/images/emoji/no_pedestrians.png
Binary files differ
diff --git a/app/assets/images/emoji/no_smoking.png b/app/assets/images/emoji/no_smoking.png
new file mode 100644
index 00000000000..586b8d29d05
--- /dev/null
+++ b/app/assets/images/emoji/no_smoking.png
Binary files differ
diff --git a/app/assets/images/emoji/non-potable_water.png b/app/assets/images/emoji/non-potable_water.png
new file mode 100644
index 00000000000..827d4193f4e
--- /dev/null
+++ b/app/assets/images/emoji/non-potable_water.png
Binary files differ
diff --git a/app/assets/images/emoji/nose.png b/app/assets/images/emoji/nose.png
new file mode 100644
index 00000000000..2f04ac5f98f
--- /dev/null
+++ b/app/assets/images/emoji/nose.png
Binary files differ
diff --git a/app/assets/images/emoji/nose_tone1.png b/app/assets/images/emoji/nose_tone1.png
new file mode 100644
index 00000000000..8008d17506e
--- /dev/null
+++ b/app/assets/images/emoji/nose_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/nose_tone2.png b/app/assets/images/emoji/nose_tone2.png
new file mode 100644
index 00000000000..ac17f26e827
--- /dev/null
+++ b/app/assets/images/emoji/nose_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/nose_tone3.png b/app/assets/images/emoji/nose_tone3.png
new file mode 100644
index 00000000000..d8b6cbe0f8e
--- /dev/null
+++ b/app/assets/images/emoji/nose_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/nose_tone4.png b/app/assets/images/emoji/nose_tone4.png
new file mode 100644
index 00000000000..004b2631e2e
--- /dev/null
+++ b/app/assets/images/emoji/nose_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/nose_tone5.png b/app/assets/images/emoji/nose_tone5.png
new file mode 100644
index 00000000000..7b33821f6c9
--- /dev/null
+++ b/app/assets/images/emoji/nose_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/notebook.png b/app/assets/images/emoji/notebook.png
new file mode 100644
index 00000000000..f6c28b4915d
--- /dev/null
+++ b/app/assets/images/emoji/notebook.png
Binary files differ
diff --git a/app/assets/images/emoji/notebook_with_decorative_cover.png b/app/assets/images/emoji/notebook_with_decorative_cover.png
new file mode 100644
index 00000000000..03f566b6d2c
--- /dev/null
+++ b/app/assets/images/emoji/notebook_with_decorative_cover.png
Binary files differ
diff --git a/app/assets/images/emoji/notepad_spiral.png b/app/assets/images/emoji/notepad_spiral.png
new file mode 100644
index 00000000000..85faa10d8ea
--- /dev/null
+++ b/app/assets/images/emoji/notepad_spiral.png
Binary files differ
diff --git a/app/assets/images/emoji/notes.png b/app/assets/images/emoji/notes.png
new file mode 100644
index 00000000000..57d499aa181
--- /dev/null
+++ b/app/assets/images/emoji/notes.png
Binary files differ
diff --git a/app/assets/images/emoji/nut_and_bolt.png b/app/assets/images/emoji/nut_and_bolt.png
new file mode 100644
index 00000000000..4b9ae155319
--- /dev/null
+++ b/app/assets/images/emoji/nut_and_bolt.png
Binary files differ
diff --git a/app/assets/images/emoji/o.png b/app/assets/images/emoji/o.png
new file mode 100644
index 00000000000..3fe75ce4675
--- /dev/null
+++ b/app/assets/images/emoji/o.png
Binary files differ
diff --git a/app/assets/images/emoji/o2.png b/app/assets/images/emoji/o2.png
new file mode 100644
index 00000000000..73278ba194a
--- /dev/null
+++ b/app/assets/images/emoji/o2.png
Binary files differ
diff --git a/app/assets/images/emoji/ocean.png b/app/assets/images/emoji/ocean.png
new file mode 100644
index 00000000000..45ff1e87703
--- /dev/null
+++ b/app/assets/images/emoji/ocean.png
Binary files differ
diff --git a/app/assets/images/emoji/octagonal_sign.png b/app/assets/images/emoji/octagonal_sign.png
new file mode 100644
index 00000000000..5ed61004045
--- /dev/null
+++ b/app/assets/images/emoji/octagonal_sign.png
Binary files differ
diff --git a/app/assets/images/emoji/octopus.png b/app/assets/images/emoji/octopus.png
new file mode 100644
index 00000000000..72c84074aac
--- /dev/null
+++ b/app/assets/images/emoji/octopus.png
Binary files differ
diff --git a/app/assets/images/emoji/oden.png b/app/assets/images/emoji/oden.png
new file mode 100644
index 00000000000..d38a849fece
--- /dev/null
+++ b/app/assets/images/emoji/oden.png
Binary files differ
diff --git a/app/assets/images/emoji/office.png b/app/assets/images/emoji/office.png
new file mode 100644
index 00000000000..7eee927d1b0
--- /dev/null
+++ b/app/assets/images/emoji/office.png
Binary files differ
diff --git a/app/assets/images/emoji/oil.png b/app/assets/images/emoji/oil.png
new file mode 100644
index 00000000000..c4c4d42da8b
--- /dev/null
+++ b/app/assets/images/emoji/oil.png
Binary files differ
diff --git a/app/assets/images/emoji/ok.png b/app/assets/images/emoji/ok.png
new file mode 100644
index 00000000000..d0d775532ff
--- /dev/null
+++ b/app/assets/images/emoji/ok.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_hand.png b/app/assets/images/emoji/ok_hand.png
new file mode 100644
index 00000000000..028d69b0de3
--- /dev/null
+++ b/app/assets/images/emoji/ok_hand.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_hand_tone1.png b/app/assets/images/emoji/ok_hand_tone1.png
new file mode 100644
index 00000000000..cecf7b2ab5a
--- /dev/null
+++ b/app/assets/images/emoji/ok_hand_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_hand_tone2.png b/app/assets/images/emoji/ok_hand_tone2.png
new file mode 100644
index 00000000000..c19239bcd3d
--- /dev/null
+++ b/app/assets/images/emoji/ok_hand_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_hand_tone3.png b/app/assets/images/emoji/ok_hand_tone3.png
new file mode 100644
index 00000000000..94b65b03ecd
--- /dev/null
+++ b/app/assets/images/emoji/ok_hand_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_hand_tone4.png b/app/assets/images/emoji/ok_hand_tone4.png
new file mode 100644
index 00000000000..03d26f08e6a
--- /dev/null
+++ b/app/assets/images/emoji/ok_hand_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_hand_tone5.png b/app/assets/images/emoji/ok_hand_tone5.png
new file mode 100644
index 00000000000..d4b24086364
--- /dev/null
+++ b/app/assets/images/emoji/ok_hand_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_woman.png b/app/assets/images/emoji/ok_woman.png
new file mode 100644
index 00000000000..90a2c7469c4
--- /dev/null
+++ b/app/assets/images/emoji/ok_woman.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_woman_tone1.png b/app/assets/images/emoji/ok_woman_tone1.png
new file mode 100644
index 00000000000..c99543e785b
--- /dev/null
+++ b/app/assets/images/emoji/ok_woman_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_woman_tone2.png b/app/assets/images/emoji/ok_woman_tone2.png
new file mode 100644
index 00000000000..ad5fae813db
--- /dev/null
+++ b/app/assets/images/emoji/ok_woman_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_woman_tone3.png b/app/assets/images/emoji/ok_woman_tone3.png
new file mode 100644
index 00000000000..51bf4fab406
--- /dev/null
+++ b/app/assets/images/emoji/ok_woman_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_woman_tone4.png b/app/assets/images/emoji/ok_woman_tone4.png
new file mode 100644
index 00000000000..ee3f9dc640a
--- /dev/null
+++ b/app/assets/images/emoji/ok_woman_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/ok_woman_tone5.png b/app/assets/images/emoji/ok_woman_tone5.png
new file mode 100644
index 00000000000..62a9d9237f7
--- /dev/null
+++ b/app/assets/images/emoji/ok_woman_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/older_man.png b/app/assets/images/emoji/older_man.png
new file mode 100644
index 00000000000..4ace4e6f308
--- /dev/null
+++ b/app/assets/images/emoji/older_man.png
Binary files differ
diff --git a/app/assets/images/emoji/older_man_tone1.png b/app/assets/images/emoji/older_man_tone1.png
new file mode 100644
index 00000000000..ab459baace8
--- /dev/null
+++ b/app/assets/images/emoji/older_man_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/older_man_tone2.png b/app/assets/images/emoji/older_man_tone2.png
new file mode 100644
index 00000000000..f4dfc7694ea
--- /dev/null
+++ b/app/assets/images/emoji/older_man_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/older_man_tone3.png b/app/assets/images/emoji/older_man_tone3.png
new file mode 100644
index 00000000000..5ffd11792f4
--- /dev/null
+++ b/app/assets/images/emoji/older_man_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/older_man_tone4.png b/app/assets/images/emoji/older_man_tone4.png
new file mode 100644
index 00000000000..b350a764bfd
--- /dev/null
+++ b/app/assets/images/emoji/older_man_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/older_man_tone5.png b/app/assets/images/emoji/older_man_tone5.png
new file mode 100644
index 00000000000..05fe24a1708
--- /dev/null
+++ b/app/assets/images/emoji/older_man_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/older_woman.png b/app/assets/images/emoji/older_woman.png
new file mode 100644
index 00000000000..52dc4987143
--- /dev/null
+++ b/app/assets/images/emoji/older_woman.png
Binary files differ
diff --git a/app/assets/images/emoji/older_woman_tone1.png b/app/assets/images/emoji/older_woman_tone1.png
new file mode 100644
index 00000000000..b49e821402c
--- /dev/null
+++ b/app/assets/images/emoji/older_woman_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/older_woman_tone2.png b/app/assets/images/emoji/older_woman_tone2.png
new file mode 100644
index 00000000000..e86bf5ab3b7
--- /dev/null
+++ b/app/assets/images/emoji/older_woman_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/older_woman_tone3.png b/app/assets/images/emoji/older_woman_tone3.png
new file mode 100644
index 00000000000..83fc14b0874
--- /dev/null
+++ b/app/assets/images/emoji/older_woman_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/older_woman_tone4.png b/app/assets/images/emoji/older_woman_tone4.png
new file mode 100644
index 00000000000..e4aa8a424d4
--- /dev/null
+++ b/app/assets/images/emoji/older_woman_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/older_woman_tone5.png b/app/assets/images/emoji/older_woman_tone5.png
new file mode 100644
index 00000000000..4009012bb0a
--- /dev/null
+++ b/app/assets/images/emoji/older_woman_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/om_symbol.png b/app/assets/images/emoji/om_symbol.png
new file mode 100644
index 00000000000..a35c63c459c
--- /dev/null
+++ b/app/assets/images/emoji/om_symbol.png
Binary files differ
diff --git a/app/assets/images/emoji/on.png b/app/assets/images/emoji/on.png
new file mode 100644
index 00000000000..a0c371ae21e
--- /dev/null
+++ b/app/assets/images/emoji/on.png
Binary files differ
diff --git a/app/assets/images/emoji/oncoming_automobile.png b/app/assets/images/emoji/oncoming_automobile.png
new file mode 100644
index 00000000000..3c7e1d52e63
--- /dev/null
+++ b/app/assets/images/emoji/oncoming_automobile.png
Binary files differ
diff --git a/app/assets/images/emoji/oncoming_bus.png b/app/assets/images/emoji/oncoming_bus.png
new file mode 100644
index 00000000000..ad91e256c7f
--- /dev/null
+++ b/app/assets/images/emoji/oncoming_bus.png
Binary files differ
diff --git a/app/assets/images/emoji/oncoming_police_car.png b/app/assets/images/emoji/oncoming_police_car.png
new file mode 100644
index 00000000000..c9109c85b5d
--- /dev/null
+++ b/app/assets/images/emoji/oncoming_police_car.png
Binary files differ
diff --git a/app/assets/images/emoji/oncoming_taxi.png b/app/assets/images/emoji/oncoming_taxi.png
new file mode 100644
index 00000000000..fea14e45846
--- /dev/null
+++ b/app/assets/images/emoji/oncoming_taxi.png
Binary files differ
diff --git a/app/assets/images/emoji/one.png b/app/assets/images/emoji/one.png
new file mode 100644
index 00000000000..e6d84b80128
--- /dev/null
+++ b/app/assets/images/emoji/one.png
Binary files differ
diff --git a/app/assets/images/emoji/open_file_folder.png b/app/assets/images/emoji/open_file_folder.png
new file mode 100644
index 00000000000..3993b09222f
--- /dev/null
+++ b/app/assets/images/emoji/open_file_folder.png
Binary files differ
diff --git a/app/assets/images/emoji/open_hands.png b/app/assets/images/emoji/open_hands.png
new file mode 100644
index 00000000000..1cf75c9101e
--- /dev/null
+++ b/app/assets/images/emoji/open_hands.png
Binary files differ
diff --git a/app/assets/images/emoji/open_hands_tone1.png b/app/assets/images/emoji/open_hands_tone1.png
new file mode 100644
index 00000000000..352d2614f11
--- /dev/null
+++ b/app/assets/images/emoji/open_hands_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/open_hands_tone2.png b/app/assets/images/emoji/open_hands_tone2.png
new file mode 100644
index 00000000000..70824a50c73
--- /dev/null
+++ b/app/assets/images/emoji/open_hands_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/open_hands_tone3.png b/app/assets/images/emoji/open_hands_tone3.png
new file mode 100644
index 00000000000..d7d136bd3db
--- /dev/null
+++ b/app/assets/images/emoji/open_hands_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/open_hands_tone4.png b/app/assets/images/emoji/open_hands_tone4.png
new file mode 100644
index 00000000000..df4eaa711e7
--- /dev/null
+++ b/app/assets/images/emoji/open_hands_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/open_hands_tone5.png b/app/assets/images/emoji/open_hands_tone5.png
new file mode 100644
index 00000000000..7dc04eaebd8
--- /dev/null
+++ b/app/assets/images/emoji/open_hands_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/open_mouth.png b/app/assets/images/emoji/open_mouth.png
new file mode 100644
index 00000000000..a62cd27e148
--- /dev/null
+++ b/app/assets/images/emoji/open_mouth.png
Binary files differ
diff --git a/app/assets/images/emoji/ophiuchus.png b/app/assets/images/emoji/ophiuchus.png
new file mode 100644
index 00000000000..0a780a700da
--- /dev/null
+++ b/app/assets/images/emoji/ophiuchus.png
Binary files differ
diff --git a/app/assets/images/emoji/orange_book.png b/app/assets/images/emoji/orange_book.png
new file mode 100644
index 00000000000..ab40e6ae6a2
--- /dev/null
+++ b/app/assets/images/emoji/orange_book.png
Binary files differ
diff --git a/app/assets/images/emoji/orthodox_cross.png b/app/assets/images/emoji/orthodox_cross.png
new file mode 100644
index 00000000000..0530e33a4d4
--- /dev/null
+++ b/app/assets/images/emoji/orthodox_cross.png
Binary files differ
diff --git a/app/assets/images/emoji/outbox_tray.png b/app/assets/images/emoji/outbox_tray.png
new file mode 100644
index 00000000000..46493ed5b2c
--- /dev/null
+++ b/app/assets/images/emoji/outbox_tray.png
Binary files differ
diff --git a/app/assets/images/emoji/owl.png b/app/assets/images/emoji/owl.png
new file mode 100644
index 00000000000..fa6815480c3
--- /dev/null
+++ b/app/assets/images/emoji/owl.png
Binary files differ
diff --git a/app/assets/images/emoji/ox.png b/app/assets/images/emoji/ox.png
new file mode 100644
index 00000000000..badf5708f2f
--- /dev/null
+++ b/app/assets/images/emoji/ox.png
Binary files differ
diff --git a/app/assets/images/emoji/package.png b/app/assets/images/emoji/package.png
new file mode 100644
index 00000000000..85431756ad8
--- /dev/null
+++ b/app/assets/images/emoji/package.png
Binary files differ
diff --git a/app/assets/images/emoji/page_facing_up.png b/app/assets/images/emoji/page_facing_up.png
new file mode 100644
index 00000000000..ba4ed757e01
--- /dev/null
+++ b/app/assets/images/emoji/page_facing_up.png
Binary files differ
diff --git a/app/assets/images/emoji/page_with_curl.png b/app/assets/images/emoji/page_with_curl.png
new file mode 100644
index 00000000000..06355319c74
--- /dev/null
+++ b/app/assets/images/emoji/page_with_curl.png
Binary files differ
diff --git a/app/assets/images/emoji/pager.png b/app/assets/images/emoji/pager.png
new file mode 100644
index 00000000000..b24b99306a2
--- /dev/null
+++ b/app/assets/images/emoji/pager.png
Binary files differ
diff --git a/app/assets/images/emoji/paintbrush.png b/app/assets/images/emoji/paintbrush.png
new file mode 100644
index 00000000000..28bffbaa3c9
--- /dev/null
+++ b/app/assets/images/emoji/paintbrush.png
Binary files differ
diff --git a/app/assets/images/emoji/palm_tree.png b/app/assets/images/emoji/palm_tree.png
new file mode 100644
index 00000000000..4bbb10f4f19
--- /dev/null
+++ b/app/assets/images/emoji/palm_tree.png
Binary files differ
diff --git a/app/assets/images/emoji/pancakes.png b/app/assets/images/emoji/pancakes.png
new file mode 100644
index 00000000000..6223d1a28e9
--- /dev/null
+++ b/app/assets/images/emoji/pancakes.png
Binary files differ
diff --git a/app/assets/images/emoji/panda_face.png b/app/assets/images/emoji/panda_face.png
new file mode 100644
index 00000000000..978382775ce
--- /dev/null
+++ b/app/assets/images/emoji/panda_face.png
Binary files differ
diff --git a/app/assets/images/emoji/paperclip.png b/app/assets/images/emoji/paperclip.png
new file mode 100644
index 00000000000..8cd8d4f8750
--- /dev/null
+++ b/app/assets/images/emoji/paperclip.png
Binary files differ
diff --git a/app/assets/images/emoji/paperclips.png b/app/assets/images/emoji/paperclips.png
new file mode 100644
index 00000000000..76021e8c705
--- /dev/null
+++ b/app/assets/images/emoji/paperclips.png
Binary files differ
diff --git a/app/assets/images/emoji/park.png b/app/assets/images/emoji/park.png
new file mode 100644
index 00000000000..63ec7016301
--- /dev/null
+++ b/app/assets/images/emoji/park.png
Binary files differ
diff --git a/app/assets/images/emoji/parking.png b/app/assets/images/emoji/parking.png
new file mode 100644
index 00000000000..7be7dac27e8
--- /dev/null
+++ b/app/assets/images/emoji/parking.png
Binary files differ
diff --git a/app/assets/images/emoji/part_alternation_mark.png b/app/assets/images/emoji/part_alternation_mark.png
new file mode 100644
index 00000000000..70453d41528
--- /dev/null
+++ b/app/assets/images/emoji/part_alternation_mark.png
Binary files differ
diff --git a/app/assets/images/emoji/partly_sunny.png b/app/assets/images/emoji/partly_sunny.png
new file mode 100644
index 00000000000..a55e59c344c
--- /dev/null
+++ b/app/assets/images/emoji/partly_sunny.png
Binary files differ
diff --git a/app/assets/images/emoji/passport_control.png b/app/assets/images/emoji/passport_control.png
new file mode 100644
index 00000000000..079e34ee4d4
--- /dev/null
+++ b/app/assets/images/emoji/passport_control.png
Binary files differ
diff --git a/app/assets/images/emoji/pause_button.png b/app/assets/images/emoji/pause_button.png
new file mode 100644
index 00000000000..4f07e7ebfd7
--- /dev/null
+++ b/app/assets/images/emoji/pause_button.png
Binary files differ
diff --git a/app/assets/images/emoji/peace.png b/app/assets/images/emoji/peace.png
new file mode 100644
index 00000000000..86033faf477
--- /dev/null
+++ b/app/assets/images/emoji/peace.png
Binary files differ
diff --git a/app/assets/images/emoji/peach.png b/app/assets/images/emoji/peach.png
new file mode 100644
index 00000000000..9ab57cbb758
--- /dev/null
+++ b/app/assets/images/emoji/peach.png
Binary files differ
diff --git a/app/assets/images/emoji/peanuts.png b/app/assets/images/emoji/peanuts.png
new file mode 100644
index 00000000000..b64fadad010
--- /dev/null
+++ b/app/assets/images/emoji/peanuts.png
Binary files differ
diff --git a/app/assets/images/emoji/pear.png b/app/assets/images/emoji/pear.png
new file mode 100644
index 00000000000..3869f718bcf
--- /dev/null
+++ b/app/assets/images/emoji/pear.png
Binary files differ
diff --git a/app/assets/images/emoji/pen_ballpoint.png b/app/assets/images/emoji/pen_ballpoint.png
new file mode 100644
index 00000000000..6ef7a342433
--- /dev/null
+++ b/app/assets/images/emoji/pen_ballpoint.png
Binary files differ
diff --git a/app/assets/images/emoji/pen_fountain.png b/app/assets/images/emoji/pen_fountain.png
new file mode 100644
index 00000000000..3ca4bd2c231
--- /dev/null
+++ b/app/assets/images/emoji/pen_fountain.png
Binary files differ
diff --git a/app/assets/images/emoji/pencil.png b/app/assets/images/emoji/pencil.png
new file mode 100644
index 00000000000..edc6155e168
--- /dev/null
+++ b/app/assets/images/emoji/pencil.png
Binary files differ
diff --git a/app/assets/images/emoji/pencil2.png b/app/assets/images/emoji/pencil2.png
new file mode 100644
index 00000000000..3833d590fa2
--- /dev/null
+++ b/app/assets/images/emoji/pencil2.png
Binary files differ
diff --git a/app/assets/images/emoji/penguin.png b/app/assets/images/emoji/penguin.png
new file mode 100644
index 00000000000..c0064fb9734
--- /dev/null
+++ b/app/assets/images/emoji/penguin.png
Binary files differ
diff --git a/app/assets/images/emoji/pensive.png b/app/assets/images/emoji/pensive.png
new file mode 100644
index 00000000000..490fb566954
--- /dev/null
+++ b/app/assets/images/emoji/pensive.png
Binary files differ
diff --git a/app/assets/images/emoji/performing_arts.png b/app/assets/images/emoji/performing_arts.png
new file mode 100644
index 00000000000..685441fdaa1
--- /dev/null
+++ b/app/assets/images/emoji/performing_arts.png
Binary files differ
diff --git a/app/assets/images/emoji/persevere.png b/app/assets/images/emoji/persevere.png
new file mode 100644
index 00000000000..646a05fe908
--- /dev/null
+++ b/app/assets/images/emoji/persevere.png
Binary files differ
diff --git a/app/assets/images/emoji/person_frowning.png b/app/assets/images/emoji/person_frowning.png
new file mode 100644
index 00000000000..579324959a1
--- /dev/null
+++ b/app/assets/images/emoji/person_frowning.png
Binary files differ
diff --git a/app/assets/images/emoji/person_frowning_tone1.png b/app/assets/images/emoji/person_frowning_tone1.png
new file mode 100644
index 00000000000..21d3bb43923
--- /dev/null
+++ b/app/assets/images/emoji/person_frowning_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/person_frowning_tone2.png b/app/assets/images/emoji/person_frowning_tone2.png
new file mode 100644
index 00000000000..973f5fc8382
--- /dev/null
+++ b/app/assets/images/emoji/person_frowning_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/person_frowning_tone3.png b/app/assets/images/emoji/person_frowning_tone3.png
new file mode 100644
index 00000000000..41fbcc78816
--- /dev/null
+++ b/app/assets/images/emoji/person_frowning_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/person_frowning_tone4.png b/app/assets/images/emoji/person_frowning_tone4.png
new file mode 100644
index 00000000000..5a37c741030
--- /dev/null
+++ b/app/assets/images/emoji/person_frowning_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/person_frowning_tone5.png b/app/assets/images/emoji/person_frowning_tone5.png
new file mode 100644
index 00000000000..e08141f3efe
--- /dev/null
+++ b/app/assets/images/emoji/person_frowning_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_blond_hair.png b/app/assets/images/emoji/person_with_blond_hair.png
new file mode 100644
index 00000000000..ad6f01a7dda
--- /dev/null
+++ b/app/assets/images/emoji/person_with_blond_hair.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_blond_hair_tone1.png b/app/assets/images/emoji/person_with_blond_hair_tone1.png
new file mode 100644
index 00000000000..7d18ef24445
--- /dev/null
+++ b/app/assets/images/emoji/person_with_blond_hair_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_blond_hair_tone2.png b/app/assets/images/emoji/person_with_blond_hair_tone2.png
new file mode 100644
index 00000000000..dae1307315c
--- /dev/null
+++ b/app/assets/images/emoji/person_with_blond_hair_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_blond_hair_tone3.png b/app/assets/images/emoji/person_with_blond_hair_tone3.png
new file mode 100644
index 00000000000..684677e8e5a
--- /dev/null
+++ b/app/assets/images/emoji/person_with_blond_hair_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_blond_hair_tone4.png b/app/assets/images/emoji/person_with_blond_hair_tone4.png
new file mode 100644
index 00000000000..012be0b51f8
--- /dev/null
+++ b/app/assets/images/emoji/person_with_blond_hair_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_blond_hair_tone5.png b/app/assets/images/emoji/person_with_blond_hair_tone5.png
new file mode 100644
index 00000000000..d4ecc4cf44b
--- /dev/null
+++ b/app/assets/images/emoji/person_with_blond_hair_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_pouting_face.png b/app/assets/images/emoji/person_with_pouting_face.png
new file mode 100644
index 00000000000..10eb0571078
--- /dev/null
+++ b/app/assets/images/emoji/person_with_pouting_face.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_pouting_face_tone1.png b/app/assets/images/emoji/person_with_pouting_face_tone1.png
new file mode 100644
index 00000000000..57e826b75a4
--- /dev/null
+++ b/app/assets/images/emoji/person_with_pouting_face_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_pouting_face_tone2.png b/app/assets/images/emoji/person_with_pouting_face_tone2.png
new file mode 100644
index 00000000000..3f317c0c25f
--- /dev/null
+++ b/app/assets/images/emoji/person_with_pouting_face_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_pouting_face_tone3.png b/app/assets/images/emoji/person_with_pouting_face_tone3.png
new file mode 100644
index 00000000000..d2fbb6c20bf
--- /dev/null
+++ b/app/assets/images/emoji/person_with_pouting_face_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_pouting_face_tone4.png b/app/assets/images/emoji/person_with_pouting_face_tone4.png
new file mode 100644
index 00000000000..643ceb4a5c5
--- /dev/null
+++ b/app/assets/images/emoji/person_with_pouting_face_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/person_with_pouting_face_tone5.png b/app/assets/images/emoji/person_with_pouting_face_tone5.png
new file mode 100644
index 00000000000..b2eb6859c32
--- /dev/null
+++ b/app/assets/images/emoji/person_with_pouting_face_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/pick.png b/app/assets/images/emoji/pick.png
new file mode 100644
index 00000000000..6370fe6d791
--- /dev/null
+++ b/app/assets/images/emoji/pick.png
Binary files differ
diff --git a/app/assets/images/emoji/pig.png b/app/assets/images/emoji/pig.png
new file mode 100644
index 00000000000..afe05ca1676
--- /dev/null
+++ b/app/assets/images/emoji/pig.png
Binary files differ
diff --git a/app/assets/images/emoji/pig2.png b/app/assets/images/emoji/pig2.png
new file mode 100644
index 00000000000..5f31c1a2d75
--- /dev/null
+++ b/app/assets/images/emoji/pig2.png
Binary files differ
diff --git a/app/assets/images/emoji/pig_nose.png b/app/assets/images/emoji/pig_nose.png
new file mode 100644
index 00000000000..3610ae4a910
--- /dev/null
+++ b/app/assets/images/emoji/pig_nose.png
Binary files differ
diff --git a/app/assets/images/emoji/pill.png b/app/assets/images/emoji/pill.png
new file mode 100644
index 00000000000..1d4530e77a3
--- /dev/null
+++ b/app/assets/images/emoji/pill.png
Binary files differ
diff --git a/app/assets/images/emoji/pineapple.png b/app/assets/images/emoji/pineapple.png
new file mode 100644
index 00000000000..c89a1606462
--- /dev/null
+++ b/app/assets/images/emoji/pineapple.png
Binary files differ
diff --git a/app/assets/images/emoji/ping_pong.png b/app/assets/images/emoji/ping_pong.png
new file mode 100644
index 00000000000..ff3c51727d1
--- /dev/null
+++ b/app/assets/images/emoji/ping_pong.png
Binary files differ
diff --git a/app/assets/images/emoji/pisces.png b/app/assets/images/emoji/pisces.png
new file mode 100644
index 00000000000..7f6f646a95c
--- /dev/null
+++ b/app/assets/images/emoji/pisces.png
Binary files differ
diff --git a/app/assets/images/emoji/pizza.png b/app/assets/images/emoji/pizza.png
new file mode 100644
index 00000000000..e07365cb398
--- /dev/null
+++ b/app/assets/images/emoji/pizza.png
Binary files differ
diff --git a/app/assets/images/emoji/place_of_worship.png b/app/assets/images/emoji/place_of_worship.png
new file mode 100644
index 00000000000..207d59cce85
--- /dev/null
+++ b/app/assets/images/emoji/place_of_worship.png
Binary files differ
diff --git a/app/assets/images/emoji/play_pause.png b/app/assets/images/emoji/play_pause.png
new file mode 100644
index 00000000000..a9f857139ac
--- /dev/null
+++ b/app/assets/images/emoji/play_pause.png
Binary files differ
diff --git a/app/assets/images/emoji/point_down.png b/app/assets/images/emoji/point_down.png
new file mode 100644
index 00000000000..00d3d13ab5c
--- /dev/null
+++ b/app/assets/images/emoji/point_down.png
Binary files differ
diff --git a/app/assets/images/emoji/point_down_tone1.png b/app/assets/images/emoji/point_down_tone1.png
new file mode 100644
index 00000000000..140f157d8c7
--- /dev/null
+++ b/app/assets/images/emoji/point_down_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/point_down_tone2.png b/app/assets/images/emoji/point_down_tone2.png
new file mode 100644
index 00000000000..d518544f7fa
--- /dev/null
+++ b/app/assets/images/emoji/point_down_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/point_down_tone3.png b/app/assets/images/emoji/point_down_tone3.png
new file mode 100644
index 00000000000..018b688b8b7
--- /dev/null
+++ b/app/assets/images/emoji/point_down_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/point_down_tone4.png b/app/assets/images/emoji/point_down_tone4.png
new file mode 100644
index 00000000000..98845bf6f72
--- /dev/null
+++ b/app/assets/images/emoji/point_down_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/point_down_tone5.png b/app/assets/images/emoji/point_down_tone5.png
new file mode 100644
index 00000000000..9a9b039a9fc
--- /dev/null
+++ b/app/assets/images/emoji/point_down_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/point_left.png b/app/assets/images/emoji/point_left.png
new file mode 100644
index 00000000000..599fa2e3cf1
--- /dev/null
+++ b/app/assets/images/emoji/point_left.png
Binary files differ
diff --git a/app/assets/images/emoji/point_left_tone1.png b/app/assets/images/emoji/point_left_tone1.png
new file mode 100644
index 00000000000..88e2c306076
--- /dev/null
+++ b/app/assets/images/emoji/point_left_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/point_left_tone2.png b/app/assets/images/emoji/point_left_tone2.png
new file mode 100644
index 00000000000..d3c89d87c5f
--- /dev/null
+++ b/app/assets/images/emoji/point_left_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/point_left_tone3.png b/app/assets/images/emoji/point_left_tone3.png
new file mode 100644
index 00000000000..b23b9167358
--- /dev/null
+++ b/app/assets/images/emoji/point_left_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/point_left_tone4.png b/app/assets/images/emoji/point_left_tone4.png
new file mode 100644
index 00000000000..3093f325c27
--- /dev/null
+++ b/app/assets/images/emoji/point_left_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/point_left_tone5.png b/app/assets/images/emoji/point_left_tone5.png
new file mode 100644
index 00000000000..2b4cbfa120c
--- /dev/null
+++ b/app/assets/images/emoji/point_left_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/point_right.png b/app/assets/images/emoji/point_right.png
new file mode 100644
index 00000000000..93a3cd34aa5
--- /dev/null
+++ b/app/assets/images/emoji/point_right.png
Binary files differ
diff --git a/app/assets/images/emoji/point_right_tone1.png b/app/assets/images/emoji/point_right_tone1.png
new file mode 100644
index 00000000000..4a28c6bbc89
--- /dev/null
+++ b/app/assets/images/emoji/point_right_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/point_right_tone2.png b/app/assets/images/emoji/point_right_tone2.png
new file mode 100644
index 00000000000..7cb13231733
--- /dev/null
+++ b/app/assets/images/emoji/point_right_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/point_right_tone3.png b/app/assets/images/emoji/point_right_tone3.png
new file mode 100644
index 00000000000..5514807d71a
--- /dev/null
+++ b/app/assets/images/emoji/point_right_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/point_right_tone4.png b/app/assets/images/emoji/point_right_tone4.png
new file mode 100644
index 00000000000..b8541d6440d
--- /dev/null
+++ b/app/assets/images/emoji/point_right_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/point_right_tone5.png b/app/assets/images/emoji/point_right_tone5.png
new file mode 100644
index 00000000000..1b7aab07bb1
--- /dev/null
+++ b/app/assets/images/emoji/point_right_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up.png b/app/assets/images/emoji/point_up.png
new file mode 100644
index 00000000000..f4978ff0f00
--- /dev/null
+++ b/app/assets/images/emoji/point_up.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_2.png b/app/assets/images/emoji/point_up_2.png
new file mode 100644
index 00000000000..bc496dfeae4
--- /dev/null
+++ b/app/assets/images/emoji/point_up_2.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_2_tone1.png b/app/assets/images/emoji/point_up_2_tone1.png
new file mode 100644
index 00000000000..a12a7e78430
--- /dev/null
+++ b/app/assets/images/emoji/point_up_2_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_2_tone2.png b/app/assets/images/emoji/point_up_2_tone2.png
new file mode 100644
index 00000000000..cdff40ceab0
--- /dev/null
+++ b/app/assets/images/emoji/point_up_2_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_2_tone3.png b/app/assets/images/emoji/point_up_2_tone3.png
new file mode 100644
index 00000000000..a07ce9e5ae8
--- /dev/null
+++ b/app/assets/images/emoji/point_up_2_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_2_tone4.png b/app/assets/images/emoji/point_up_2_tone4.png
new file mode 100644
index 00000000000..4f86c88ba42
--- /dev/null
+++ b/app/assets/images/emoji/point_up_2_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_2_tone5.png b/app/assets/images/emoji/point_up_2_tone5.png
new file mode 100644
index 00000000000..ed1b26c35d3
--- /dev/null
+++ b/app/assets/images/emoji/point_up_2_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_tone1.png b/app/assets/images/emoji/point_up_tone1.png
new file mode 100644
index 00000000000..6a9db21d64c
--- /dev/null
+++ b/app/assets/images/emoji/point_up_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_tone2.png b/app/assets/images/emoji/point_up_tone2.png
new file mode 100644
index 00000000000..15aa9ea0e05
--- /dev/null
+++ b/app/assets/images/emoji/point_up_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_tone3.png b/app/assets/images/emoji/point_up_tone3.png
new file mode 100644
index 00000000000..652b73a9c5d
--- /dev/null
+++ b/app/assets/images/emoji/point_up_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_tone4.png b/app/assets/images/emoji/point_up_tone4.png
new file mode 100644
index 00000000000..692bad926e9
--- /dev/null
+++ b/app/assets/images/emoji/point_up_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/point_up_tone5.png b/app/assets/images/emoji/point_up_tone5.png
new file mode 100644
index 00000000000..1e1b10fb71c
--- /dev/null
+++ b/app/assets/images/emoji/point_up_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/police_car.png b/app/assets/images/emoji/police_car.png
new file mode 100644
index 00000000000..3da4253de7e
--- /dev/null
+++ b/app/assets/images/emoji/police_car.png
Binary files differ
diff --git a/app/assets/images/emoji/poodle.png b/app/assets/images/emoji/poodle.png
new file mode 100644
index 00000000000..8ec39e396af
--- /dev/null
+++ b/app/assets/images/emoji/poodle.png
Binary files differ
diff --git a/app/assets/images/emoji/poop.png b/app/assets/images/emoji/poop.png
new file mode 100644
index 00000000000..10b15e72d56
--- /dev/null
+++ b/app/assets/images/emoji/poop.png
Binary files differ
diff --git a/app/assets/images/emoji/popcorn.png b/app/assets/images/emoji/popcorn.png
new file mode 100644
index 00000000000..36853e381d4
--- /dev/null
+++ b/app/assets/images/emoji/popcorn.png
Binary files differ
diff --git a/app/assets/images/emoji/post_office.png b/app/assets/images/emoji/post_office.png
new file mode 100644
index 00000000000..a23848f9aa0
--- /dev/null
+++ b/app/assets/images/emoji/post_office.png
Binary files differ
diff --git a/app/assets/images/emoji/postal_horn.png b/app/assets/images/emoji/postal_horn.png
new file mode 100644
index 00000000000..c173b8dbd67
--- /dev/null
+++ b/app/assets/images/emoji/postal_horn.png
Binary files differ
diff --git a/app/assets/images/emoji/postbox.png b/app/assets/images/emoji/postbox.png
new file mode 100644
index 00000000000..07c9c4ab3d6
--- /dev/null
+++ b/app/assets/images/emoji/postbox.png
Binary files differ
diff --git a/app/assets/images/emoji/potable_water.png b/app/assets/images/emoji/potable_water.png
new file mode 100644
index 00000000000..2c610049459
--- /dev/null
+++ b/app/assets/images/emoji/potable_water.png
Binary files differ
diff --git a/app/assets/images/emoji/potato.png b/app/assets/images/emoji/potato.png
new file mode 100644
index 00000000000..70350ca2c0a
--- /dev/null
+++ b/app/assets/images/emoji/potato.png
Binary files differ
diff --git a/app/assets/images/emoji/pouch.png b/app/assets/images/emoji/pouch.png
new file mode 100644
index 00000000000..8795c6c66ff
--- /dev/null
+++ b/app/assets/images/emoji/pouch.png
Binary files differ
diff --git a/app/assets/images/emoji/poultry_leg.png b/app/assets/images/emoji/poultry_leg.png
new file mode 100644
index 00000000000..eea4a53a2f9
--- /dev/null
+++ b/app/assets/images/emoji/poultry_leg.png
Binary files differ
diff --git a/app/assets/images/emoji/pound.png b/app/assets/images/emoji/pound.png
new file mode 100644
index 00000000000..a0d4c4099e9
--- /dev/null
+++ b/app/assets/images/emoji/pound.png
Binary files differ
diff --git a/app/assets/images/emoji/pouting_cat.png b/app/assets/images/emoji/pouting_cat.png
new file mode 100644
index 00000000000..41ddfeab42b
--- /dev/null
+++ b/app/assets/images/emoji/pouting_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/pray.png b/app/assets/images/emoji/pray.png
new file mode 100644
index 00000000000..8347f2435be
--- /dev/null
+++ b/app/assets/images/emoji/pray.png
Binary files differ
diff --git a/app/assets/images/emoji/pray_tone1.png b/app/assets/images/emoji/pray_tone1.png
new file mode 100644
index 00000000000..060ef257172
--- /dev/null
+++ b/app/assets/images/emoji/pray_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/pray_tone2.png b/app/assets/images/emoji/pray_tone2.png
new file mode 100644
index 00000000000..56dc607c07a
--- /dev/null
+++ b/app/assets/images/emoji/pray_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/pray_tone3.png b/app/assets/images/emoji/pray_tone3.png
new file mode 100644
index 00000000000..0f33b862008
--- /dev/null
+++ b/app/assets/images/emoji/pray_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/pray_tone4.png b/app/assets/images/emoji/pray_tone4.png
new file mode 100644
index 00000000000..2ea8dc11657
--- /dev/null
+++ b/app/assets/images/emoji/pray_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/pray_tone5.png b/app/assets/images/emoji/pray_tone5.png
new file mode 100644
index 00000000000..2128a6c4703
--- /dev/null
+++ b/app/assets/images/emoji/pray_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/prayer_beads.png b/app/assets/images/emoji/prayer_beads.png
new file mode 100644
index 00000000000..a4b6dfcc62e
--- /dev/null
+++ b/app/assets/images/emoji/prayer_beads.png
Binary files differ
diff --git a/app/assets/images/emoji/pregnant_woman.png b/app/assets/images/emoji/pregnant_woman.png
new file mode 100644
index 00000000000..084e83a414a
--- /dev/null
+++ b/app/assets/images/emoji/pregnant_woman.png
Binary files differ
diff --git a/app/assets/images/emoji/pregnant_woman_tone1.png b/app/assets/images/emoji/pregnant_woman_tone1.png
new file mode 100644
index 00000000000..a78703b33aa
--- /dev/null
+++ b/app/assets/images/emoji/pregnant_woman_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/pregnant_woman_tone2.png b/app/assets/images/emoji/pregnant_woman_tone2.png
new file mode 100644
index 00000000000..0068c6c4a77
--- /dev/null
+++ b/app/assets/images/emoji/pregnant_woman_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/pregnant_woman_tone3.png b/app/assets/images/emoji/pregnant_woman_tone3.png
new file mode 100644
index 00000000000..3206296b684
--- /dev/null
+++ b/app/assets/images/emoji/pregnant_woman_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/pregnant_woman_tone4.png b/app/assets/images/emoji/pregnant_woman_tone4.png
new file mode 100644
index 00000000000..120fda5cd8c
--- /dev/null
+++ b/app/assets/images/emoji/pregnant_woman_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/pregnant_woman_tone5.png b/app/assets/images/emoji/pregnant_woman_tone5.png
new file mode 100644
index 00000000000..569bfdf05ce
--- /dev/null
+++ b/app/assets/images/emoji/pregnant_woman_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/prince.png b/app/assets/images/emoji/prince.png
new file mode 100644
index 00000000000..38d69344c84
--- /dev/null
+++ b/app/assets/images/emoji/prince.png
Binary files differ
diff --git a/app/assets/images/emoji/prince_tone1.png b/app/assets/images/emoji/prince_tone1.png
new file mode 100644
index 00000000000..849930c8887
--- /dev/null
+++ b/app/assets/images/emoji/prince_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/prince_tone2.png b/app/assets/images/emoji/prince_tone2.png
new file mode 100644
index 00000000000..23d8b3b1285
--- /dev/null
+++ b/app/assets/images/emoji/prince_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/prince_tone3.png b/app/assets/images/emoji/prince_tone3.png
new file mode 100644
index 00000000000..db6dfff0647
--- /dev/null
+++ b/app/assets/images/emoji/prince_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/prince_tone4.png b/app/assets/images/emoji/prince_tone4.png
new file mode 100644
index 00000000000..8e10f8be6a8
--- /dev/null
+++ b/app/assets/images/emoji/prince_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/prince_tone5.png b/app/assets/images/emoji/prince_tone5.png
new file mode 100644
index 00000000000..138d4ea7048
--- /dev/null
+++ b/app/assets/images/emoji/prince_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/princess.png b/app/assets/images/emoji/princess.png
new file mode 100644
index 00000000000..879e9fa8c5d
--- /dev/null
+++ b/app/assets/images/emoji/princess.png
Binary files differ
diff --git a/app/assets/images/emoji/princess_tone1.png b/app/assets/images/emoji/princess_tone1.png
new file mode 100644
index 00000000000..c28078cdc36
--- /dev/null
+++ b/app/assets/images/emoji/princess_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/princess_tone2.png b/app/assets/images/emoji/princess_tone2.png
new file mode 100644
index 00000000000..dcd20e6ecd4
--- /dev/null
+++ b/app/assets/images/emoji/princess_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/princess_tone3.png b/app/assets/images/emoji/princess_tone3.png
new file mode 100644
index 00000000000..cde6f315c56
--- /dev/null
+++ b/app/assets/images/emoji/princess_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/princess_tone4.png b/app/assets/images/emoji/princess_tone4.png
new file mode 100644
index 00000000000..c71e69caaef
--- /dev/null
+++ b/app/assets/images/emoji/princess_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/princess_tone5.png b/app/assets/images/emoji/princess_tone5.png
new file mode 100644
index 00000000000..063e2645910
--- /dev/null
+++ b/app/assets/images/emoji/princess_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/printer.png b/app/assets/images/emoji/printer.png
new file mode 100644
index 00000000000..027c830f0fe
--- /dev/null
+++ b/app/assets/images/emoji/printer.png
Binary files differ
diff --git a/app/assets/images/emoji/projector.png b/app/assets/images/emoji/projector.png
new file mode 100644
index 00000000000..ce9ab0daa28
--- /dev/null
+++ b/app/assets/images/emoji/projector.png
Binary files differ
diff --git a/app/assets/images/emoji/punch.png b/app/assets/images/emoji/punch.png
new file mode 100644
index 00000000000..b14ca5f5211
--- /dev/null
+++ b/app/assets/images/emoji/punch.png
Binary files differ
diff --git a/app/assets/images/emoji/punch_tone1.png b/app/assets/images/emoji/punch_tone1.png
new file mode 100644
index 00000000000..93c7d17fb47
--- /dev/null
+++ b/app/assets/images/emoji/punch_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/punch_tone2.png b/app/assets/images/emoji/punch_tone2.png
new file mode 100644
index 00000000000..c0a1af6e10a
--- /dev/null
+++ b/app/assets/images/emoji/punch_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/punch_tone3.png b/app/assets/images/emoji/punch_tone3.png
new file mode 100644
index 00000000000..1458b021201
--- /dev/null
+++ b/app/assets/images/emoji/punch_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/punch_tone4.png b/app/assets/images/emoji/punch_tone4.png
new file mode 100644
index 00000000000..c1466bfcdef
--- /dev/null
+++ b/app/assets/images/emoji/punch_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/punch_tone5.png b/app/assets/images/emoji/punch_tone5.png
new file mode 100644
index 00000000000..00b4ddb8953
--- /dev/null
+++ b/app/assets/images/emoji/punch_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/purple_heart.png b/app/assets/images/emoji/purple_heart.png
new file mode 100644
index 00000000000..95c53a9ade6
--- /dev/null
+++ b/app/assets/images/emoji/purple_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/purse.png b/app/assets/images/emoji/purse.png
new file mode 100644
index 00000000000..981346193c5
--- /dev/null
+++ b/app/assets/images/emoji/purse.png
Binary files differ
diff --git a/app/assets/images/emoji/pushpin.png b/app/assets/images/emoji/pushpin.png
new file mode 100644
index 00000000000..57e07d7f4cc
--- /dev/null
+++ b/app/assets/images/emoji/pushpin.png
Binary files differ
diff --git a/app/assets/images/emoji/put_litter_in_its_place.png b/app/assets/images/emoji/put_litter_in_its_place.png
new file mode 100644
index 00000000000..82a84f9a375
--- /dev/null
+++ b/app/assets/images/emoji/put_litter_in_its_place.png
Binary files differ
diff --git a/app/assets/images/emoji/question.png b/app/assets/images/emoji/question.png
new file mode 100644
index 00000000000..5a58f3458aa
--- /dev/null
+++ b/app/assets/images/emoji/question.png
Binary files differ
diff --git a/app/assets/images/emoji/rabbit.png b/app/assets/images/emoji/rabbit.png
new file mode 100644
index 00000000000..ea75ab0426e
--- /dev/null
+++ b/app/assets/images/emoji/rabbit.png
Binary files differ
diff --git a/app/assets/images/emoji/rabbit2.png b/app/assets/images/emoji/rabbit2.png
new file mode 100644
index 00000000000..2c8a29c642f
--- /dev/null
+++ b/app/assets/images/emoji/rabbit2.png
Binary files differ
diff --git a/app/assets/images/emoji/race_car.png b/app/assets/images/emoji/race_car.png
new file mode 100644
index 00000000000..fe3f045f446
--- /dev/null
+++ b/app/assets/images/emoji/race_car.png
Binary files differ
diff --git a/app/assets/images/emoji/racehorse.png b/app/assets/images/emoji/racehorse.png
new file mode 100644
index 00000000000..b3e73cc8903
--- /dev/null
+++ b/app/assets/images/emoji/racehorse.png
Binary files differ
diff --git a/app/assets/images/emoji/radio.png b/app/assets/images/emoji/radio.png
new file mode 100644
index 00000000000..dec381fa242
--- /dev/null
+++ b/app/assets/images/emoji/radio.png
Binary files differ
diff --git a/app/assets/images/emoji/radio_button.png b/app/assets/images/emoji/radio_button.png
new file mode 100644
index 00000000000..3a23449d917
--- /dev/null
+++ b/app/assets/images/emoji/radio_button.png
Binary files differ
diff --git a/app/assets/images/emoji/radioactive.png b/app/assets/images/emoji/radioactive.png
new file mode 100644
index 00000000000..3b46199fe37
--- /dev/null
+++ b/app/assets/images/emoji/radioactive.png
Binary files differ
diff --git a/app/assets/images/emoji/rage.png b/app/assets/images/emoji/rage.png
new file mode 100644
index 00000000000..9d739bd40ad
--- /dev/null
+++ b/app/assets/images/emoji/rage.png
Binary files differ
diff --git a/app/assets/images/emoji/railway_car.png b/app/assets/images/emoji/railway_car.png
new file mode 100644
index 00000000000..a9acbf13008
--- /dev/null
+++ b/app/assets/images/emoji/railway_car.png
Binary files differ
diff --git a/app/assets/images/emoji/railway_track.png b/app/assets/images/emoji/railway_track.png
new file mode 100644
index 00000000000..e1a7a0d1430
--- /dev/null
+++ b/app/assets/images/emoji/railway_track.png
Binary files differ
diff --git a/app/assets/images/emoji/rainbow.png b/app/assets/images/emoji/rainbow.png
new file mode 100644
index 00000000000..154735d7147
--- /dev/null
+++ b/app/assets/images/emoji/rainbow.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_back_of_hand.png b/app/assets/images/emoji/raised_back_of_hand.png
new file mode 100644
index 00000000000..479234294b4
--- /dev/null
+++ b/app/assets/images/emoji/raised_back_of_hand.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_back_of_hand_tone1.png b/app/assets/images/emoji/raised_back_of_hand_tone1.png
new file mode 100644
index 00000000000..813d28499b5
--- /dev/null
+++ b/app/assets/images/emoji/raised_back_of_hand_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_back_of_hand_tone2.png b/app/assets/images/emoji/raised_back_of_hand_tone2.png
new file mode 100644
index 00000000000..192ff795e37
--- /dev/null
+++ b/app/assets/images/emoji/raised_back_of_hand_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_back_of_hand_tone3.png b/app/assets/images/emoji/raised_back_of_hand_tone3.png
new file mode 100644
index 00000000000..61a727abe6b
--- /dev/null
+++ b/app/assets/images/emoji/raised_back_of_hand_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_back_of_hand_tone4.png b/app/assets/images/emoji/raised_back_of_hand_tone4.png
new file mode 100644
index 00000000000..2e83da511f5
--- /dev/null
+++ b/app/assets/images/emoji/raised_back_of_hand_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_back_of_hand_tone5.png b/app/assets/images/emoji/raised_back_of_hand_tone5.png
new file mode 100644
index 00000000000..d7a5b95a02c
--- /dev/null
+++ b/app/assets/images/emoji/raised_back_of_hand_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hand.png b/app/assets/images/emoji/raised_hand.png
new file mode 100644
index 00000000000..6b2954315d1
--- /dev/null
+++ b/app/assets/images/emoji/raised_hand.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hand_tone1.png b/app/assets/images/emoji/raised_hand_tone1.png
new file mode 100644
index 00000000000..3b752902c07
--- /dev/null
+++ b/app/assets/images/emoji/raised_hand_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hand_tone2.png b/app/assets/images/emoji/raised_hand_tone2.png
new file mode 100644
index 00000000000..44e2a514c60
--- /dev/null
+++ b/app/assets/images/emoji/raised_hand_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hand_tone3.png b/app/assets/images/emoji/raised_hand_tone3.png
new file mode 100644
index 00000000000..5bb62a7528a
--- /dev/null
+++ b/app/assets/images/emoji/raised_hand_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hand_tone4.png b/app/assets/images/emoji/raised_hand_tone4.png
new file mode 100644
index 00000000000..c7f8c9ec270
--- /dev/null
+++ b/app/assets/images/emoji/raised_hand_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hand_tone5.png b/app/assets/images/emoji/raised_hand_tone5.png
new file mode 100644
index 00000000000..c601b58a73e
--- /dev/null
+++ b/app/assets/images/emoji/raised_hand_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hands.png b/app/assets/images/emoji/raised_hands.png
new file mode 100644
index 00000000000..c0155f728e7
--- /dev/null
+++ b/app/assets/images/emoji/raised_hands.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hands_tone1.png b/app/assets/images/emoji/raised_hands_tone1.png
new file mode 100644
index 00000000000..1168b8236b6
--- /dev/null
+++ b/app/assets/images/emoji/raised_hands_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hands_tone2.png b/app/assets/images/emoji/raised_hands_tone2.png
new file mode 100644
index 00000000000..322de622903
--- /dev/null
+++ b/app/assets/images/emoji/raised_hands_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hands_tone3.png b/app/assets/images/emoji/raised_hands_tone3.png
new file mode 100644
index 00000000000..2aa24e05ae1
--- /dev/null
+++ b/app/assets/images/emoji/raised_hands_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hands_tone4.png b/app/assets/images/emoji/raised_hands_tone4.png
new file mode 100644
index 00000000000..f31bf0db992
--- /dev/null
+++ b/app/assets/images/emoji/raised_hands_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/raised_hands_tone5.png b/app/assets/images/emoji/raised_hands_tone5.png
new file mode 100644
index 00000000000..5e95067f98b
--- /dev/null
+++ b/app/assets/images/emoji/raised_hands_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/raising_hand.png b/app/assets/images/emoji/raising_hand.png
new file mode 100644
index 00000000000..2880708c0cc
--- /dev/null
+++ b/app/assets/images/emoji/raising_hand.png
Binary files differ
diff --git a/app/assets/images/emoji/raising_hand_tone1.png b/app/assets/images/emoji/raising_hand_tone1.png
new file mode 100644
index 00000000000..1c90e3e2689
--- /dev/null
+++ b/app/assets/images/emoji/raising_hand_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/raising_hand_tone2.png b/app/assets/images/emoji/raising_hand_tone2.png
new file mode 100644
index 00000000000..82c3ef2bfc5
--- /dev/null
+++ b/app/assets/images/emoji/raising_hand_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/raising_hand_tone3.png b/app/assets/images/emoji/raising_hand_tone3.png
new file mode 100644
index 00000000000..1b1da2aa0ca
--- /dev/null
+++ b/app/assets/images/emoji/raising_hand_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/raising_hand_tone4.png b/app/assets/images/emoji/raising_hand_tone4.png
new file mode 100644
index 00000000000..e453855c01f
--- /dev/null
+++ b/app/assets/images/emoji/raising_hand_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/raising_hand_tone5.png b/app/assets/images/emoji/raising_hand_tone5.png
new file mode 100644
index 00000000000..b86200fd844
--- /dev/null
+++ b/app/assets/images/emoji/raising_hand_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/ram.png b/app/assets/images/emoji/ram.png
new file mode 100644
index 00000000000..52a44464c9b
--- /dev/null
+++ b/app/assets/images/emoji/ram.png
Binary files differ
diff --git a/app/assets/images/emoji/ramen.png b/app/assets/images/emoji/ramen.png
new file mode 100644
index 00000000000..c1cb7cd7384
--- /dev/null
+++ b/app/assets/images/emoji/ramen.png
Binary files differ
diff --git a/app/assets/images/emoji/rat.png b/app/assets/images/emoji/rat.png
new file mode 100644
index 00000000000..86219144f10
--- /dev/null
+++ b/app/assets/images/emoji/rat.png
Binary files differ
diff --git a/app/assets/images/emoji/record_button.png b/app/assets/images/emoji/record_button.png
new file mode 100644
index 00000000000..ada52830fce
--- /dev/null
+++ b/app/assets/images/emoji/record_button.png
Binary files differ
diff --git a/app/assets/images/emoji/recycle.png b/app/assets/images/emoji/recycle.png
new file mode 100644
index 00000000000..9221f095c37
--- /dev/null
+++ b/app/assets/images/emoji/recycle.png
Binary files differ
diff --git a/app/assets/images/emoji/red_car.png b/app/assets/images/emoji/red_car.png
new file mode 100644
index 00000000000..b3e6a774dea
--- /dev/null
+++ b/app/assets/images/emoji/red_car.png
Binary files differ
diff --git a/app/assets/images/emoji/red_circle.png b/app/assets/images/emoji/red_circle.png
new file mode 100644
index 00000000000..4bef930d92f
--- /dev/null
+++ b/app/assets/images/emoji/red_circle.png
Binary files differ
diff --git a/app/assets/images/emoji/registered.png b/app/assets/images/emoji/registered.png
new file mode 100644
index 00000000000..53ef9f2d4e6
--- /dev/null
+++ b/app/assets/images/emoji/registered.png
Binary files differ
diff --git a/app/assets/images/emoji/relaxed.png b/app/assets/images/emoji/relaxed.png
new file mode 100644
index 00000000000..e9e53c03d45
--- /dev/null
+++ b/app/assets/images/emoji/relaxed.png
Binary files differ
diff --git a/app/assets/images/emoji/relieved.png b/app/assets/images/emoji/relieved.png
new file mode 100644
index 00000000000..715ad0bf53f
--- /dev/null
+++ b/app/assets/images/emoji/relieved.png
Binary files differ
diff --git a/app/assets/images/emoji/reminder_ribbon.png b/app/assets/images/emoji/reminder_ribbon.png
new file mode 100644
index 00000000000..3988bbd094c
--- /dev/null
+++ b/app/assets/images/emoji/reminder_ribbon.png
Binary files differ
diff --git a/app/assets/images/emoji/repeat.png b/app/assets/images/emoji/repeat.png
new file mode 100644
index 00000000000..540ce4e0fba
--- /dev/null
+++ b/app/assets/images/emoji/repeat.png
Binary files differ
diff --git a/app/assets/images/emoji/repeat_one.png b/app/assets/images/emoji/repeat_one.png
new file mode 100644
index 00000000000..9567e83337f
--- /dev/null
+++ b/app/assets/images/emoji/repeat_one.png
Binary files differ
diff --git a/app/assets/images/emoji/restroom.png b/app/assets/images/emoji/restroom.png
new file mode 100644
index 00000000000..9588e0f0ef7
--- /dev/null
+++ b/app/assets/images/emoji/restroom.png
Binary files differ
diff --git a/app/assets/images/emoji/revolving_hearts.png b/app/assets/images/emoji/revolving_hearts.png
new file mode 100644
index 00000000000..7b9d1948f73
--- /dev/null
+++ b/app/assets/images/emoji/revolving_hearts.png
Binary files differ
diff --git a/app/assets/images/emoji/rewind.png b/app/assets/images/emoji/rewind.png
new file mode 100644
index 00000000000..e22e2bd3da5
--- /dev/null
+++ b/app/assets/images/emoji/rewind.png
Binary files differ
diff --git a/app/assets/images/emoji/rhino.png b/app/assets/images/emoji/rhino.png
new file mode 100644
index 00000000000..12f4e0d9d9b
--- /dev/null
+++ b/app/assets/images/emoji/rhino.png
Binary files differ
diff --git a/app/assets/images/emoji/ribbon.png b/app/assets/images/emoji/ribbon.png
new file mode 100644
index 00000000000..0f253c3d8c8
--- /dev/null
+++ b/app/assets/images/emoji/ribbon.png
Binary files differ
diff --git a/app/assets/images/emoji/rice.png b/app/assets/images/emoji/rice.png
new file mode 100644
index 00000000000..6e3ac7956b1
--- /dev/null
+++ b/app/assets/images/emoji/rice.png
Binary files differ
diff --git a/app/assets/images/emoji/rice_ball.png b/app/assets/images/emoji/rice_ball.png
new file mode 100644
index 00000000000..d3d8ee25cb8
--- /dev/null
+++ b/app/assets/images/emoji/rice_ball.png
Binary files differ
diff --git a/app/assets/images/emoji/rice_cracker.png b/app/assets/images/emoji/rice_cracker.png
new file mode 100644
index 00000000000..7fbd08e4ff9
--- /dev/null
+++ b/app/assets/images/emoji/rice_cracker.png
Binary files differ
diff --git a/app/assets/images/emoji/rice_scene.png b/app/assets/images/emoji/rice_scene.png
new file mode 100644
index 00000000000..1a28426592a
--- /dev/null
+++ b/app/assets/images/emoji/rice_scene.png
Binary files differ
diff --git a/app/assets/images/emoji/right_facing_fist.png b/app/assets/images/emoji/right_facing_fist.png
new file mode 100644
index 00000000000..754ed066d2c
--- /dev/null
+++ b/app/assets/images/emoji/right_facing_fist.png
Binary files differ
diff --git a/app/assets/images/emoji/right_facing_fist_tone1.png b/app/assets/images/emoji/right_facing_fist_tone1.png
new file mode 100644
index 00000000000..33ded2f61a6
--- /dev/null
+++ b/app/assets/images/emoji/right_facing_fist_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/right_facing_fist_tone2.png b/app/assets/images/emoji/right_facing_fist_tone2.png
new file mode 100644
index 00000000000..88054e335c7
--- /dev/null
+++ b/app/assets/images/emoji/right_facing_fist_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/right_facing_fist_tone3.png b/app/assets/images/emoji/right_facing_fist_tone3.png
new file mode 100644
index 00000000000..84b9f5da7f7
--- /dev/null
+++ b/app/assets/images/emoji/right_facing_fist_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/right_facing_fist_tone4.png b/app/assets/images/emoji/right_facing_fist_tone4.png
new file mode 100644
index 00000000000..e741cfea68b
--- /dev/null
+++ b/app/assets/images/emoji/right_facing_fist_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/right_facing_fist_tone5.png b/app/assets/images/emoji/right_facing_fist_tone5.png
new file mode 100644
index 00000000000..cf66d760c1f
--- /dev/null
+++ b/app/assets/images/emoji/right_facing_fist_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/ring.png b/app/assets/images/emoji/ring.png
new file mode 100644
index 00000000000..87d227adb74
--- /dev/null
+++ b/app/assets/images/emoji/ring.png
Binary files differ
diff --git a/app/assets/images/emoji/robot.png b/app/assets/images/emoji/robot.png
new file mode 100644
index 00000000000..7cc62612c6a
--- /dev/null
+++ b/app/assets/images/emoji/robot.png
Binary files differ
diff --git a/app/assets/images/emoji/rocket.png b/app/assets/images/emoji/rocket.png
new file mode 100644
index 00000000000..0d8da089a37
--- /dev/null
+++ b/app/assets/images/emoji/rocket.png
Binary files differ
diff --git a/app/assets/images/emoji/rofl.png b/app/assets/images/emoji/rofl.png
new file mode 100644
index 00000000000..b1736fedfeb
--- /dev/null
+++ b/app/assets/images/emoji/rofl.png
Binary files differ
diff --git a/app/assets/images/emoji/roller_coaster.png b/app/assets/images/emoji/roller_coaster.png
new file mode 100644
index 00000000000..5b849e071e8
--- /dev/null
+++ b/app/assets/images/emoji/roller_coaster.png
Binary files differ
diff --git a/app/assets/images/emoji/rolling_eyes.png b/app/assets/images/emoji/rolling_eyes.png
new file mode 100644
index 00000000000..2f77b9fc3b9
--- /dev/null
+++ b/app/assets/images/emoji/rolling_eyes.png
Binary files differ
diff --git a/app/assets/images/emoji/rooster.png b/app/assets/images/emoji/rooster.png
new file mode 100644
index 00000000000..bbf2bbff97a
--- /dev/null
+++ b/app/assets/images/emoji/rooster.png
Binary files differ
diff --git a/app/assets/images/emoji/rose.png b/app/assets/images/emoji/rose.png
new file mode 100644
index 00000000000..52c286d31ce
--- /dev/null
+++ b/app/assets/images/emoji/rose.png
Binary files differ
diff --git a/app/assets/images/emoji/rosette.png b/app/assets/images/emoji/rosette.png
new file mode 100644
index 00000000000..8030e494bcf
--- /dev/null
+++ b/app/assets/images/emoji/rosette.png
Binary files differ
diff --git a/app/assets/images/emoji/rotating_light.png b/app/assets/images/emoji/rotating_light.png
new file mode 100644
index 00000000000..cad66b0afef
--- /dev/null
+++ b/app/assets/images/emoji/rotating_light.png
Binary files differ
diff --git a/app/assets/images/emoji/round_pushpin.png b/app/assets/images/emoji/round_pushpin.png
new file mode 100644
index 00000000000..28b9d72866e
--- /dev/null
+++ b/app/assets/images/emoji/round_pushpin.png
Binary files differ
diff --git a/app/assets/images/emoji/rowboat.png b/app/assets/images/emoji/rowboat.png
new file mode 100644
index 00000000000..dd4dfc095d9
--- /dev/null
+++ b/app/assets/images/emoji/rowboat.png
Binary files differ
diff --git a/app/assets/images/emoji/rowboat_tone1.png b/app/assets/images/emoji/rowboat_tone1.png
new file mode 100644
index 00000000000..5e5d18548cb
--- /dev/null
+++ b/app/assets/images/emoji/rowboat_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/rowboat_tone2.png b/app/assets/images/emoji/rowboat_tone2.png
new file mode 100644
index 00000000000..9b123ef8871
--- /dev/null
+++ b/app/assets/images/emoji/rowboat_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/rowboat_tone3.png b/app/assets/images/emoji/rowboat_tone3.png
new file mode 100644
index 00000000000..8ebd89a55f5
--- /dev/null
+++ b/app/assets/images/emoji/rowboat_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/rowboat_tone4.png b/app/assets/images/emoji/rowboat_tone4.png
new file mode 100644
index 00000000000..2b0d04f8725
--- /dev/null
+++ b/app/assets/images/emoji/rowboat_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/rowboat_tone5.png b/app/assets/images/emoji/rowboat_tone5.png
new file mode 100644
index 00000000000..b346f2dfc84
--- /dev/null
+++ b/app/assets/images/emoji/rowboat_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/rugby_football.png b/app/assets/images/emoji/rugby_football.png
new file mode 100644
index 00000000000..b1872273436
--- /dev/null
+++ b/app/assets/images/emoji/rugby_football.png
Binary files differ
diff --git a/app/assets/images/emoji/runner.png b/app/assets/images/emoji/runner.png
new file mode 100644
index 00000000000..e914915976a
--- /dev/null
+++ b/app/assets/images/emoji/runner.png
Binary files differ
diff --git a/app/assets/images/emoji/runner_tone1.png b/app/assets/images/emoji/runner_tone1.png
new file mode 100644
index 00000000000..9355239a52d
--- /dev/null
+++ b/app/assets/images/emoji/runner_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/runner_tone2.png b/app/assets/images/emoji/runner_tone2.png
new file mode 100644
index 00000000000..6112fd5c376
--- /dev/null
+++ b/app/assets/images/emoji/runner_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/runner_tone3.png b/app/assets/images/emoji/runner_tone3.png
new file mode 100644
index 00000000000..625ec708f48
--- /dev/null
+++ b/app/assets/images/emoji/runner_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/runner_tone4.png b/app/assets/images/emoji/runner_tone4.png
new file mode 100644
index 00000000000..242f1b56337
--- /dev/null
+++ b/app/assets/images/emoji/runner_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/runner_tone5.png b/app/assets/images/emoji/runner_tone5.png
new file mode 100644
index 00000000000..2976c6f019f
--- /dev/null
+++ b/app/assets/images/emoji/runner_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/running_shirt_with_sash.png b/app/assets/images/emoji/running_shirt_with_sash.png
new file mode 100644
index 00000000000..6d83c06b803
--- /dev/null
+++ b/app/assets/images/emoji/running_shirt_with_sash.png
Binary files differ
diff --git a/app/assets/images/emoji/sa.png b/app/assets/images/emoji/sa.png
new file mode 100644
index 00000000000..900f9633247
--- /dev/null
+++ b/app/assets/images/emoji/sa.png
Binary files differ
diff --git a/app/assets/images/emoji/sagittarius.png b/app/assets/images/emoji/sagittarius.png
new file mode 100644
index 00000000000..f8d94ff2923
--- /dev/null
+++ b/app/assets/images/emoji/sagittarius.png
Binary files differ
diff --git a/app/assets/images/emoji/sailboat.png b/app/assets/images/emoji/sailboat.png
new file mode 100644
index 00000000000..772ef11da5d
--- /dev/null
+++ b/app/assets/images/emoji/sailboat.png
Binary files differ
diff --git a/app/assets/images/emoji/sake.png b/app/assets/images/emoji/sake.png
new file mode 100644
index 00000000000..2933f5672c4
--- /dev/null
+++ b/app/assets/images/emoji/sake.png
Binary files differ
diff --git a/app/assets/images/emoji/salad.png b/app/assets/images/emoji/salad.png
new file mode 100644
index 00000000000..c89f9341158
--- /dev/null
+++ b/app/assets/images/emoji/salad.png
Binary files differ
diff --git a/app/assets/images/emoji/sandal.png b/app/assets/images/emoji/sandal.png
new file mode 100644
index 00000000000..9d9f5122b7a
--- /dev/null
+++ b/app/assets/images/emoji/sandal.png
Binary files differ
diff --git a/app/assets/images/emoji/santa.png b/app/assets/images/emoji/santa.png
new file mode 100644
index 00000000000..bc83ab80d52
--- /dev/null
+++ b/app/assets/images/emoji/santa.png
Binary files differ
diff --git a/app/assets/images/emoji/santa_tone1.png b/app/assets/images/emoji/santa_tone1.png
new file mode 100644
index 00000000000..5233ffb7174
--- /dev/null
+++ b/app/assets/images/emoji/santa_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/santa_tone2.png b/app/assets/images/emoji/santa_tone2.png
new file mode 100644
index 00000000000..4e845438197
--- /dev/null
+++ b/app/assets/images/emoji/santa_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/santa_tone3.png b/app/assets/images/emoji/santa_tone3.png
new file mode 100644
index 00000000000..7fc4f33b60f
--- /dev/null
+++ b/app/assets/images/emoji/santa_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/santa_tone4.png b/app/assets/images/emoji/santa_tone4.png
new file mode 100644
index 00000000000..d1d5a15132d
--- /dev/null
+++ b/app/assets/images/emoji/santa_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/santa_tone5.png b/app/assets/images/emoji/santa_tone5.png
new file mode 100644
index 00000000000..4d697a01f24
--- /dev/null
+++ b/app/assets/images/emoji/santa_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/satellite.png b/app/assets/images/emoji/satellite.png
new file mode 100644
index 00000000000..db0372795f4
--- /dev/null
+++ b/app/assets/images/emoji/satellite.png
Binary files differ
diff --git a/app/assets/images/emoji/satellite_orbital.png b/app/assets/images/emoji/satellite_orbital.png
new file mode 100644
index 00000000000..4ba55d6e297
--- /dev/null
+++ b/app/assets/images/emoji/satellite_orbital.png
Binary files differ
diff --git a/app/assets/images/emoji/saxophone.png b/app/assets/images/emoji/saxophone.png
new file mode 100644
index 00000000000..a392faec291
--- /dev/null
+++ b/app/assets/images/emoji/saxophone.png
Binary files differ
diff --git a/app/assets/images/emoji/scales.png b/app/assets/images/emoji/scales.png
new file mode 100644
index 00000000000..0757eda1684
--- /dev/null
+++ b/app/assets/images/emoji/scales.png
Binary files differ
diff --git a/app/assets/images/emoji/school.png b/app/assets/images/emoji/school.png
new file mode 100644
index 00000000000..269759534f0
--- /dev/null
+++ b/app/assets/images/emoji/school.png
Binary files differ
diff --git a/app/assets/images/emoji/school_satchel.png b/app/assets/images/emoji/school_satchel.png
new file mode 100644
index 00000000000..9997c86e7dc
--- /dev/null
+++ b/app/assets/images/emoji/school_satchel.png
Binary files differ
diff --git a/app/assets/images/emoji/scissors.png b/app/assets/images/emoji/scissors.png
new file mode 100644
index 00000000000..270571c8cdd
--- /dev/null
+++ b/app/assets/images/emoji/scissors.png
Binary files differ
diff --git a/app/assets/images/emoji/scooter.png b/app/assets/images/emoji/scooter.png
new file mode 100644
index 00000000000..4ab7ef59cd2
--- /dev/null
+++ b/app/assets/images/emoji/scooter.png
Binary files differ
diff --git a/app/assets/images/emoji/scorpion.png b/app/assets/images/emoji/scorpion.png
new file mode 100644
index 00000000000..449a6b281c9
--- /dev/null
+++ b/app/assets/images/emoji/scorpion.png
Binary files differ
diff --git a/app/assets/images/emoji/scorpius.png b/app/assets/images/emoji/scorpius.png
new file mode 100644
index 00000000000..c31a9920455
--- /dev/null
+++ b/app/assets/images/emoji/scorpius.png
Binary files differ
diff --git a/app/assets/images/emoji/scream.png b/app/assets/images/emoji/scream.png
new file mode 100644
index 00000000000..c3bea9f2510
--- /dev/null
+++ b/app/assets/images/emoji/scream.png
Binary files differ
diff --git a/app/assets/images/emoji/scream_cat.png b/app/assets/images/emoji/scream_cat.png
new file mode 100644
index 00000000000..15803ad8e6e
--- /dev/null
+++ b/app/assets/images/emoji/scream_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/scroll.png b/app/assets/images/emoji/scroll.png
new file mode 100644
index 00000000000..50ee5dcd4b9
--- /dev/null
+++ b/app/assets/images/emoji/scroll.png
Binary files differ
diff --git a/app/assets/images/emoji/seat.png b/app/assets/images/emoji/seat.png
new file mode 100644
index 00000000000..a6d72d95adb
--- /dev/null
+++ b/app/assets/images/emoji/seat.png
Binary files differ
diff --git a/app/assets/images/emoji/second_place.png b/app/assets/images/emoji/second_place.png
new file mode 100644
index 00000000000..17b011268b6
--- /dev/null
+++ b/app/assets/images/emoji/second_place.png
Binary files differ
diff --git a/app/assets/images/emoji/secret.png b/app/assets/images/emoji/secret.png
new file mode 100644
index 00000000000..5fd72608e60
--- /dev/null
+++ b/app/assets/images/emoji/secret.png
Binary files differ
diff --git a/app/assets/images/emoji/see_no_evil.png b/app/assets/images/emoji/see_no_evil.png
new file mode 100644
index 00000000000..5187e474531
--- /dev/null
+++ b/app/assets/images/emoji/see_no_evil.png
Binary files differ
diff --git a/app/assets/images/emoji/seedling.png b/app/assets/images/emoji/seedling.png
new file mode 100644
index 00000000000..ae0948bcfd6
--- /dev/null
+++ b/app/assets/images/emoji/seedling.png
Binary files differ
diff --git a/app/assets/images/emoji/selfie.png b/app/assets/images/emoji/selfie.png
new file mode 100644
index 00000000000..6a1ba75c7e3
--- /dev/null
+++ b/app/assets/images/emoji/selfie.png
Binary files differ
diff --git a/app/assets/images/emoji/selfie_tone1.png b/app/assets/images/emoji/selfie_tone1.png
new file mode 100644
index 00000000000..290e075b56f
--- /dev/null
+++ b/app/assets/images/emoji/selfie_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/selfie_tone2.png b/app/assets/images/emoji/selfie_tone2.png
new file mode 100644
index 00000000000..fcd9595b643
--- /dev/null
+++ b/app/assets/images/emoji/selfie_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/selfie_tone3.png b/app/assets/images/emoji/selfie_tone3.png
new file mode 100644
index 00000000000..f3a22fdf435
--- /dev/null
+++ b/app/assets/images/emoji/selfie_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/selfie_tone4.png b/app/assets/images/emoji/selfie_tone4.png
new file mode 100644
index 00000000000..cdecf6d9f4e
--- /dev/null
+++ b/app/assets/images/emoji/selfie_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/selfie_tone5.png b/app/assets/images/emoji/selfie_tone5.png
new file mode 100644
index 00000000000..86acbb6c202
--- /dev/null
+++ b/app/assets/images/emoji/selfie_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/seven.png b/app/assets/images/emoji/seven.png
new file mode 100644
index 00000000000..9b3476ae7c7
--- /dev/null
+++ b/app/assets/images/emoji/seven.png
Binary files differ
diff --git a/app/assets/images/emoji/shallow_pan_of_food.png b/app/assets/images/emoji/shallow_pan_of_food.png
new file mode 100644
index 00000000000..663a1006acd
--- /dev/null
+++ b/app/assets/images/emoji/shallow_pan_of_food.png
Binary files differ
diff --git a/app/assets/images/emoji/shamrock.png b/app/assets/images/emoji/shamrock.png
new file mode 100644
index 00000000000..f202aecfe6f
--- /dev/null
+++ b/app/assets/images/emoji/shamrock.png
Binary files differ
diff --git a/app/assets/images/emoji/shark.png b/app/assets/images/emoji/shark.png
new file mode 100644
index 00000000000..c75076d57d8
--- /dev/null
+++ b/app/assets/images/emoji/shark.png
Binary files differ
diff --git a/app/assets/images/emoji/shaved_ice.png b/app/assets/images/emoji/shaved_ice.png
new file mode 100644
index 00000000000..36dfb53ca93
--- /dev/null
+++ b/app/assets/images/emoji/shaved_ice.png
Binary files differ
diff --git a/app/assets/images/emoji/sheep.png b/app/assets/images/emoji/sheep.png
new file mode 100644
index 00000000000..102b8a52b28
--- /dev/null
+++ b/app/assets/images/emoji/sheep.png
Binary files differ
diff --git a/app/assets/images/emoji/shell.png b/app/assets/images/emoji/shell.png
new file mode 100644
index 00000000000..55721629f62
--- /dev/null
+++ b/app/assets/images/emoji/shell.png
Binary files differ
diff --git a/app/assets/images/emoji/shield.png b/app/assets/images/emoji/shield.png
new file mode 100644
index 00000000000..610bf033ce0
--- /dev/null
+++ b/app/assets/images/emoji/shield.png
Binary files differ
diff --git a/app/assets/images/emoji/shinto_shrine.png b/app/assets/images/emoji/shinto_shrine.png
new file mode 100644
index 00000000000..5a344975bf3
--- /dev/null
+++ b/app/assets/images/emoji/shinto_shrine.png
Binary files differ
diff --git a/app/assets/images/emoji/ship.png b/app/assets/images/emoji/ship.png
new file mode 100644
index 00000000000..62d54f7d6c9
--- /dev/null
+++ b/app/assets/images/emoji/ship.png
Binary files differ
diff --git a/app/assets/images/emoji/shirt.png b/app/assets/images/emoji/shirt.png
new file mode 100644
index 00000000000..af08dec8b59
--- /dev/null
+++ b/app/assets/images/emoji/shirt.png
Binary files differ
diff --git a/app/assets/images/emoji/shopping_bags.png b/app/assets/images/emoji/shopping_bags.png
new file mode 100644
index 00000000000..99f2a2b13ac
--- /dev/null
+++ b/app/assets/images/emoji/shopping_bags.png
Binary files differ
diff --git a/app/assets/images/emoji/shopping_cart.png b/app/assets/images/emoji/shopping_cart.png
new file mode 100644
index 00000000000..1086fe6e456
--- /dev/null
+++ b/app/assets/images/emoji/shopping_cart.png
Binary files differ
diff --git a/app/assets/images/emoji/shower.png b/app/assets/images/emoji/shower.png
new file mode 100644
index 00000000000..156776a2e52
--- /dev/null
+++ b/app/assets/images/emoji/shower.png
Binary files differ
diff --git a/app/assets/images/emoji/shrimp.png b/app/assets/images/emoji/shrimp.png
new file mode 100644
index 00000000000..49eff28a71e
--- /dev/null
+++ b/app/assets/images/emoji/shrimp.png
Binary files differ
diff --git a/app/assets/images/emoji/shrug.png b/app/assets/images/emoji/shrug.png
new file mode 100644
index 00000000000..76e63bfac77
--- /dev/null
+++ b/app/assets/images/emoji/shrug.png
Binary files differ
diff --git a/app/assets/images/emoji/shrug_tone1.png b/app/assets/images/emoji/shrug_tone1.png
new file mode 100644
index 00000000000..1c895e64468
--- /dev/null
+++ b/app/assets/images/emoji/shrug_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/shrug_tone2.png b/app/assets/images/emoji/shrug_tone2.png
new file mode 100644
index 00000000000..4e3ca8f8bac
--- /dev/null
+++ b/app/assets/images/emoji/shrug_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/shrug_tone3.png b/app/assets/images/emoji/shrug_tone3.png
new file mode 100644
index 00000000000..d1b16a19bb5
--- /dev/null
+++ b/app/assets/images/emoji/shrug_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/shrug_tone4.png b/app/assets/images/emoji/shrug_tone4.png
new file mode 100644
index 00000000000..5fbef3f2255
--- /dev/null
+++ b/app/assets/images/emoji/shrug_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/shrug_tone5.png b/app/assets/images/emoji/shrug_tone5.png
new file mode 100644
index 00000000000..4af2e28bc5c
--- /dev/null
+++ b/app/assets/images/emoji/shrug_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/signal_strength.png b/app/assets/images/emoji/signal_strength.png
new file mode 100644
index 00000000000..ee2b5a4b519
--- /dev/null
+++ b/app/assets/images/emoji/signal_strength.png
Binary files differ
diff --git a/app/assets/images/emoji/six.png b/app/assets/images/emoji/six.png
new file mode 100644
index 00000000000..371b3acef2c
--- /dev/null
+++ b/app/assets/images/emoji/six.png
Binary files differ
diff --git a/app/assets/images/emoji/six_pointed_star.png b/app/assets/images/emoji/six_pointed_star.png
new file mode 100644
index 00000000000..2eb1707458b
--- /dev/null
+++ b/app/assets/images/emoji/six_pointed_star.png
Binary files differ
diff --git a/app/assets/images/emoji/ski.png b/app/assets/images/emoji/ski.png
new file mode 100644
index 00000000000..4a2d2c12306
--- /dev/null
+++ b/app/assets/images/emoji/ski.png
Binary files differ
diff --git a/app/assets/images/emoji/skier.png b/app/assets/images/emoji/skier.png
new file mode 100644
index 00000000000..2eb3bdce2af
--- /dev/null
+++ b/app/assets/images/emoji/skier.png
Binary files differ
diff --git a/app/assets/images/emoji/skull.png b/app/assets/images/emoji/skull.png
new file mode 100644
index 00000000000..26abb17296a
--- /dev/null
+++ b/app/assets/images/emoji/skull.png
Binary files differ
diff --git a/app/assets/images/emoji/skull_crossbones.png b/app/assets/images/emoji/skull_crossbones.png
new file mode 100644
index 00000000000..b459df9227a
--- /dev/null
+++ b/app/assets/images/emoji/skull_crossbones.png
Binary files differ
diff --git a/app/assets/images/emoji/sleeping.png b/app/assets/images/emoji/sleeping.png
new file mode 100644
index 00000000000..9ecf600d6d8
--- /dev/null
+++ b/app/assets/images/emoji/sleeping.png
Binary files differ
diff --git a/app/assets/images/emoji/sleeping_accommodation.png b/app/assets/images/emoji/sleeping_accommodation.png
new file mode 100644
index 00000000000..c739e7fb69b
--- /dev/null
+++ b/app/assets/images/emoji/sleeping_accommodation.png
Binary files differ
diff --git a/app/assets/images/emoji/sleepy.png b/app/assets/images/emoji/sleepy.png
new file mode 100644
index 00000000000..836b4107717
--- /dev/null
+++ b/app/assets/images/emoji/sleepy.png
Binary files differ
diff --git a/app/assets/images/emoji/slight_frown.png b/app/assets/images/emoji/slight_frown.png
new file mode 100644
index 00000000000..b2f1d983d36
--- /dev/null
+++ b/app/assets/images/emoji/slight_frown.png
Binary files differ
diff --git a/app/assets/images/emoji/slight_smile.png b/app/assets/images/emoji/slight_smile.png
new file mode 100644
index 00000000000..ddd7d65dd3d
--- /dev/null
+++ b/app/assets/images/emoji/slight_smile.png
Binary files differ
diff --git a/app/assets/images/emoji/slot_machine.png b/app/assets/images/emoji/slot_machine.png
new file mode 100644
index 00000000000..ee71b6c268c
--- /dev/null
+++ b/app/assets/images/emoji/slot_machine.png
Binary files differ
diff --git a/app/assets/images/emoji/small_blue_diamond.png b/app/assets/images/emoji/small_blue_diamond.png
new file mode 100644
index 00000000000..b86b5bc4db3
--- /dev/null
+++ b/app/assets/images/emoji/small_blue_diamond.png
Binary files differ
diff --git a/app/assets/images/emoji/small_orange_diamond.png b/app/assets/images/emoji/small_orange_diamond.png
new file mode 100644
index 00000000000..e1c6ed9b2f8
--- /dev/null
+++ b/app/assets/images/emoji/small_orange_diamond.png
Binary files differ
diff --git a/app/assets/images/emoji/small_red_triangle.png b/app/assets/images/emoji/small_red_triangle.png
new file mode 100644
index 00000000000..785887c195a
--- /dev/null
+++ b/app/assets/images/emoji/small_red_triangle.png
Binary files differ
diff --git a/app/assets/images/emoji/small_red_triangle_down.png b/app/assets/images/emoji/small_red_triangle_down.png
new file mode 100644
index 00000000000..a83beff1914
--- /dev/null
+++ b/app/assets/images/emoji/small_red_triangle_down.png
Binary files differ
diff --git a/app/assets/images/emoji/smile.png b/app/assets/images/emoji/smile.png
new file mode 100644
index 00000000000..aa47ffe978c
--- /dev/null
+++ b/app/assets/images/emoji/smile.png
Binary files differ
diff --git a/app/assets/images/emoji/smile_cat.png b/app/assets/images/emoji/smile_cat.png
new file mode 100644
index 00000000000..6f25f11dd3a
--- /dev/null
+++ b/app/assets/images/emoji/smile_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/smiley.png b/app/assets/images/emoji/smiley.png
new file mode 100644
index 00000000000..30957a65968
--- /dev/null
+++ b/app/assets/images/emoji/smiley.png
Binary files differ
diff --git a/app/assets/images/emoji/smiley_cat.png b/app/assets/images/emoji/smiley_cat.png
new file mode 100644
index 00000000000..163b57a3427
--- /dev/null
+++ b/app/assets/images/emoji/smiley_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/smiling_imp.png b/app/assets/images/emoji/smiling_imp.png
new file mode 100644
index 00000000000..cc2c5f1ec72
--- /dev/null
+++ b/app/assets/images/emoji/smiling_imp.png
Binary files differ
diff --git a/app/assets/images/emoji/smirk.png b/app/assets/images/emoji/smirk.png
new file mode 100644
index 00000000000..87852109988
--- /dev/null
+++ b/app/assets/images/emoji/smirk.png
Binary files differ
diff --git a/app/assets/images/emoji/smirk_cat.png b/app/assets/images/emoji/smirk_cat.png
new file mode 100644
index 00000000000..9ac5954c199
--- /dev/null
+++ b/app/assets/images/emoji/smirk_cat.png
Binary files differ
diff --git a/app/assets/images/emoji/smoking.png b/app/assets/images/emoji/smoking.png
new file mode 100644
index 00000000000..910f648c8f9
--- /dev/null
+++ b/app/assets/images/emoji/smoking.png
Binary files differ
diff --git a/app/assets/images/emoji/snail.png b/app/assets/images/emoji/snail.png
new file mode 100644
index 00000000000..f4ea071e2d3
--- /dev/null
+++ b/app/assets/images/emoji/snail.png
Binary files differ
diff --git a/app/assets/images/emoji/snake.png b/app/assets/images/emoji/snake.png
new file mode 100644
index 00000000000..d0278a28d8c
--- /dev/null
+++ b/app/assets/images/emoji/snake.png
Binary files differ
diff --git a/app/assets/images/emoji/sneezing_face.png b/app/assets/images/emoji/sneezing_face.png
new file mode 100644
index 00000000000..ccf07d4b64d
--- /dev/null
+++ b/app/assets/images/emoji/sneezing_face.png
Binary files differ
diff --git a/app/assets/images/emoji/snowboarder.png b/app/assets/images/emoji/snowboarder.png
new file mode 100644
index 00000000000..6361c0f2c9d
--- /dev/null
+++ b/app/assets/images/emoji/snowboarder.png
Binary files differ
diff --git a/app/assets/images/emoji/snowflake.png b/app/assets/images/emoji/snowflake.png
new file mode 100644
index 00000000000..db319a77ec6
--- /dev/null
+++ b/app/assets/images/emoji/snowflake.png
Binary files differ
diff --git a/app/assets/images/emoji/snowman.png b/app/assets/images/emoji/snowman.png
new file mode 100644
index 00000000000..20c177c2aff
--- /dev/null
+++ b/app/assets/images/emoji/snowman.png
Binary files differ
diff --git a/app/assets/images/emoji/snowman2.png b/app/assets/images/emoji/snowman2.png
new file mode 100644
index 00000000000..896f28502af
--- /dev/null
+++ b/app/assets/images/emoji/snowman2.png
Binary files differ
diff --git a/app/assets/images/emoji/sob.png b/app/assets/images/emoji/sob.png
new file mode 100644
index 00000000000..52e3517a1ee
--- /dev/null
+++ b/app/assets/images/emoji/sob.png
Binary files differ
diff --git a/app/assets/images/emoji/soccer.png b/app/assets/images/emoji/soccer.png
new file mode 100644
index 00000000000..28cfa218d6d
--- /dev/null
+++ b/app/assets/images/emoji/soccer.png
Binary files differ
diff --git a/app/assets/images/emoji/soon.png b/app/assets/images/emoji/soon.png
new file mode 100644
index 00000000000..8cdfd86690d
--- /dev/null
+++ b/app/assets/images/emoji/soon.png
Binary files differ
diff --git a/app/assets/images/emoji/sos.png b/app/assets/images/emoji/sos.png
new file mode 100644
index 00000000000..d7d8c9953e4
--- /dev/null
+++ b/app/assets/images/emoji/sos.png
Binary files differ
diff --git a/app/assets/images/emoji/sound.png b/app/assets/images/emoji/sound.png
new file mode 100644
index 00000000000..e75ddca53ba
--- /dev/null
+++ b/app/assets/images/emoji/sound.png
Binary files differ
diff --git a/app/assets/images/emoji/space_invader.png b/app/assets/images/emoji/space_invader.png
new file mode 100644
index 00000000000..2e73f5f32e5
--- /dev/null
+++ b/app/assets/images/emoji/space_invader.png
Binary files differ
diff --git a/app/assets/images/emoji/spades.png b/app/assets/images/emoji/spades.png
new file mode 100644
index 00000000000..f822f184cb0
--- /dev/null
+++ b/app/assets/images/emoji/spades.png
Binary files differ
diff --git a/app/assets/images/emoji/spaghetti.png b/app/assets/images/emoji/spaghetti.png
new file mode 100644
index 00000000000..89c24a321f1
--- /dev/null
+++ b/app/assets/images/emoji/spaghetti.png
Binary files differ
diff --git a/app/assets/images/emoji/sparkle.png b/app/assets/images/emoji/sparkle.png
new file mode 100644
index 00000000000..6aa7b6ec9cf
--- /dev/null
+++ b/app/assets/images/emoji/sparkle.png
Binary files differ
diff --git a/app/assets/images/emoji/sparkler.png b/app/assets/images/emoji/sparkler.png
new file mode 100644
index 00000000000..30339cd6e09
--- /dev/null
+++ b/app/assets/images/emoji/sparkler.png
Binary files differ
diff --git a/app/assets/images/emoji/sparkles.png b/app/assets/images/emoji/sparkles.png
new file mode 100644
index 00000000000..169bc10b023
--- /dev/null
+++ b/app/assets/images/emoji/sparkles.png
Binary files differ
diff --git a/app/assets/images/emoji/sparkling_heart.png b/app/assets/images/emoji/sparkling_heart.png
new file mode 100644
index 00000000000..6709269454e
--- /dev/null
+++ b/app/assets/images/emoji/sparkling_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/speak_no_evil.png b/app/assets/images/emoji/speak_no_evil.png
new file mode 100644
index 00000000000..9d9e07c974b
--- /dev/null
+++ b/app/assets/images/emoji/speak_no_evil.png
Binary files differ
diff --git a/app/assets/images/emoji/speaker.png b/app/assets/images/emoji/speaker.png
new file mode 100644
index 00000000000..7bcffb8fc43
--- /dev/null
+++ b/app/assets/images/emoji/speaker.png
Binary files differ
diff --git a/app/assets/images/emoji/speaking_head.png b/app/assets/images/emoji/speaking_head.png
new file mode 100644
index 00000000000..2df93aaae09
--- /dev/null
+++ b/app/assets/images/emoji/speaking_head.png
Binary files differ
diff --git a/app/assets/images/emoji/speech_balloon.png b/app/assets/images/emoji/speech_balloon.png
new file mode 100644
index 00000000000..a34ef741733
--- /dev/null
+++ b/app/assets/images/emoji/speech_balloon.png
Binary files differ
diff --git a/app/assets/images/emoji/speedboat.png b/app/assets/images/emoji/speedboat.png
new file mode 100644
index 00000000000..74059d12de1
--- /dev/null
+++ b/app/assets/images/emoji/speedboat.png
Binary files differ
diff --git a/app/assets/images/emoji/spider.png b/app/assets/images/emoji/spider.png
new file mode 100644
index 00000000000..3849fa90b94
--- /dev/null
+++ b/app/assets/images/emoji/spider.png
Binary files differ
diff --git a/app/assets/images/emoji/spider_web.png b/app/assets/images/emoji/spider_web.png
new file mode 100644
index 00000000000..ba448ee7fba
--- /dev/null
+++ b/app/assets/images/emoji/spider_web.png
Binary files differ
diff --git a/app/assets/images/emoji/spoon.png b/app/assets/images/emoji/spoon.png
new file mode 100644
index 00000000000..3c4da766aee
--- /dev/null
+++ b/app/assets/images/emoji/spoon.png
Binary files differ
diff --git a/app/assets/images/emoji/spy.png b/app/assets/images/emoji/spy.png
new file mode 100644
index 00000000000..a729e9584d6
--- /dev/null
+++ b/app/assets/images/emoji/spy.png
Binary files differ
diff --git a/app/assets/images/emoji/spy_tone1.png b/app/assets/images/emoji/spy_tone1.png
new file mode 100644
index 00000000000..2d1c022caee
--- /dev/null
+++ b/app/assets/images/emoji/spy_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/spy_tone2.png b/app/assets/images/emoji/spy_tone2.png
new file mode 100644
index 00000000000..548b9c26f5d
--- /dev/null
+++ b/app/assets/images/emoji/spy_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/spy_tone3.png b/app/assets/images/emoji/spy_tone3.png
new file mode 100644
index 00000000000..b023f4b18e1
--- /dev/null
+++ b/app/assets/images/emoji/spy_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/spy_tone4.png b/app/assets/images/emoji/spy_tone4.png
new file mode 100644
index 00000000000..d8300af492d
--- /dev/null
+++ b/app/assets/images/emoji/spy_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/spy_tone5.png b/app/assets/images/emoji/spy_tone5.png
new file mode 100644
index 00000000000..ca1462595fa
--- /dev/null
+++ b/app/assets/images/emoji/spy_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/squid.png b/app/assets/images/emoji/squid.png
new file mode 100644
index 00000000000..d2af223f0cb
--- /dev/null
+++ b/app/assets/images/emoji/squid.png
Binary files differ
diff --git a/app/assets/images/emoji/stadium.png b/app/assets/images/emoji/stadium.png
new file mode 100644
index 00000000000..00cd6db5e29
--- /dev/null
+++ b/app/assets/images/emoji/stadium.png
Binary files differ
diff --git a/app/assets/images/emoji/star.png b/app/assets/images/emoji/star.png
new file mode 100644
index 00000000000..c930947076e
--- /dev/null
+++ b/app/assets/images/emoji/star.png
Binary files differ
diff --git a/app/assets/images/emoji/star2.png b/app/assets/images/emoji/star2.png
new file mode 100644
index 00000000000..2f5cba592db
--- /dev/null
+++ b/app/assets/images/emoji/star2.png
Binary files differ
diff --git a/app/assets/images/emoji/star_and_crescent.png b/app/assets/images/emoji/star_and_crescent.png
new file mode 100644
index 00000000000..e182636457d
--- /dev/null
+++ b/app/assets/images/emoji/star_and_crescent.png
Binary files differ
diff --git a/app/assets/images/emoji/star_of_david.png b/app/assets/images/emoji/star_of_david.png
new file mode 100644
index 00000000000..fc59d0dde24
--- /dev/null
+++ b/app/assets/images/emoji/star_of_david.png
Binary files differ
diff --git a/app/assets/images/emoji/stars.png b/app/assets/images/emoji/stars.png
new file mode 100644
index 00000000000..aa45384d1c6
--- /dev/null
+++ b/app/assets/images/emoji/stars.png
Binary files differ
diff --git a/app/assets/images/emoji/station.png b/app/assets/images/emoji/station.png
new file mode 100644
index 00000000000..5c26fee529c
--- /dev/null
+++ b/app/assets/images/emoji/station.png
Binary files differ
diff --git a/app/assets/images/emoji/statue_of_liberty.png b/app/assets/images/emoji/statue_of_liberty.png
new file mode 100644
index 00000000000..05df8289b59
--- /dev/null
+++ b/app/assets/images/emoji/statue_of_liberty.png
Binary files differ
diff --git a/app/assets/images/emoji/steam_locomotive.png b/app/assets/images/emoji/steam_locomotive.png
new file mode 100644
index 00000000000..9ac0d999c4c
--- /dev/null
+++ b/app/assets/images/emoji/steam_locomotive.png
Binary files differ
diff --git a/app/assets/images/emoji/stew.png b/app/assets/images/emoji/stew.png
new file mode 100644
index 00000000000..6b3f010c17a
--- /dev/null
+++ b/app/assets/images/emoji/stew.png
Binary files differ
diff --git a/app/assets/images/emoji/stop_button.png b/app/assets/images/emoji/stop_button.png
new file mode 100644
index 00000000000..cfa99988ac2
--- /dev/null
+++ b/app/assets/images/emoji/stop_button.png
Binary files differ
diff --git a/app/assets/images/emoji/stopwatch.png b/app/assets/images/emoji/stopwatch.png
new file mode 100644
index 00000000000..8fae1c9a898
--- /dev/null
+++ b/app/assets/images/emoji/stopwatch.png
Binary files differ
diff --git a/app/assets/images/emoji/straight_ruler.png b/app/assets/images/emoji/straight_ruler.png
new file mode 100644
index 00000000000..1017b7433a1
--- /dev/null
+++ b/app/assets/images/emoji/straight_ruler.png
Binary files differ
diff --git a/app/assets/images/emoji/strawberry.png b/app/assets/images/emoji/strawberry.png
new file mode 100644
index 00000000000..7bb86f0b29c
--- /dev/null
+++ b/app/assets/images/emoji/strawberry.png
Binary files differ
diff --git a/app/assets/images/emoji/stuck_out_tongue.png b/app/assets/images/emoji/stuck_out_tongue.png
new file mode 100644
index 00000000000..25757341f96
--- /dev/null
+++ b/app/assets/images/emoji/stuck_out_tongue.png
Binary files differ
diff --git a/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png b/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png
new file mode 100644
index 00000000000..5c0401e9b1d
--- /dev/null
+++ b/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png
Binary files differ
diff --git a/app/assets/images/emoji/stuck_out_tongue_winking_eye.png b/app/assets/images/emoji/stuck_out_tongue_winking_eye.png
new file mode 100644
index 00000000000..4817eaa3dc6
--- /dev/null
+++ b/app/assets/images/emoji/stuck_out_tongue_winking_eye.png
Binary files differ
diff --git a/app/assets/images/emoji/stuffed_flatbread.png b/app/assets/images/emoji/stuffed_flatbread.png
new file mode 100644
index 00000000000..a2e10df40a5
--- /dev/null
+++ b/app/assets/images/emoji/stuffed_flatbread.png
Binary files differ
diff --git a/app/assets/images/emoji/sun_with_face.png b/app/assets/images/emoji/sun_with_face.png
new file mode 100644
index 00000000000..14a4ea971db
--- /dev/null
+++ b/app/assets/images/emoji/sun_with_face.png
Binary files differ
diff --git a/app/assets/images/emoji/sunflower.png b/app/assets/images/emoji/sunflower.png
new file mode 100644
index 00000000000..08cc07761ea
--- /dev/null
+++ b/app/assets/images/emoji/sunflower.png
Binary files differ
diff --git a/app/assets/images/emoji/sunglasses.png b/app/assets/images/emoji/sunglasses.png
new file mode 100644
index 00000000000..20011735110
--- /dev/null
+++ b/app/assets/images/emoji/sunglasses.png
Binary files differ
diff --git a/app/assets/images/emoji/sunny.png b/app/assets/images/emoji/sunny.png
new file mode 100644
index 00000000000..fd521ae31a7
--- /dev/null
+++ b/app/assets/images/emoji/sunny.png
Binary files differ
diff --git a/app/assets/images/emoji/sunrise.png b/app/assets/images/emoji/sunrise.png
new file mode 100644
index 00000000000..4ad36003c20
--- /dev/null
+++ b/app/assets/images/emoji/sunrise.png
Binary files differ
diff --git a/app/assets/images/emoji/sunrise_over_mountains.png b/app/assets/images/emoji/sunrise_over_mountains.png
new file mode 100644
index 00000000000..2b99307344d
--- /dev/null
+++ b/app/assets/images/emoji/sunrise_over_mountains.png
Binary files differ
diff --git a/app/assets/images/emoji/surfer.png b/app/assets/images/emoji/surfer.png
new file mode 100644
index 00000000000..3ab017adf4b
--- /dev/null
+++ b/app/assets/images/emoji/surfer.png
Binary files differ
diff --git a/app/assets/images/emoji/surfer_tone1.png b/app/assets/images/emoji/surfer_tone1.png
new file mode 100644
index 00000000000..b5faaa524cc
--- /dev/null
+++ b/app/assets/images/emoji/surfer_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/surfer_tone2.png b/app/assets/images/emoji/surfer_tone2.png
new file mode 100644
index 00000000000..6d92e412ff1
--- /dev/null
+++ b/app/assets/images/emoji/surfer_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/surfer_tone3.png b/app/assets/images/emoji/surfer_tone3.png
new file mode 100644
index 00000000000..f05ef59496e
--- /dev/null
+++ b/app/assets/images/emoji/surfer_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/surfer_tone4.png b/app/assets/images/emoji/surfer_tone4.png
new file mode 100644
index 00000000000..35e143d19dc
--- /dev/null
+++ b/app/assets/images/emoji/surfer_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/surfer_tone5.png b/app/assets/images/emoji/surfer_tone5.png
new file mode 100644
index 00000000000..38917658eac
--- /dev/null
+++ b/app/assets/images/emoji/surfer_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/sushi.png b/app/assets/images/emoji/sushi.png
new file mode 100644
index 00000000000..f171fd2f7a1
--- /dev/null
+++ b/app/assets/images/emoji/sushi.png
Binary files differ
diff --git a/app/assets/images/emoji/suspension_railway.png b/app/assets/images/emoji/suspension_railway.png
new file mode 100644
index 00000000000..a59d5f48c24
--- /dev/null
+++ b/app/assets/images/emoji/suspension_railway.png
Binary files differ
diff --git a/app/assets/images/emoji/sweat.png b/app/assets/images/emoji/sweat.png
new file mode 100644
index 00000000000..f0dae7b7893
--- /dev/null
+++ b/app/assets/images/emoji/sweat.png
Binary files differ
diff --git a/app/assets/images/emoji/sweat_drops.png b/app/assets/images/emoji/sweat_drops.png
new file mode 100644
index 00000000000..4106117ebc8
--- /dev/null
+++ b/app/assets/images/emoji/sweat_drops.png
Binary files differ
diff --git a/app/assets/images/emoji/sweat_smile.png b/app/assets/images/emoji/sweat_smile.png
new file mode 100644
index 00000000000..cb18d9c899b
--- /dev/null
+++ b/app/assets/images/emoji/sweat_smile.png
Binary files differ
diff --git a/app/assets/images/emoji/sweet_potato.png b/app/assets/images/emoji/sweet_potato.png
new file mode 100644
index 00000000000..92a425f2e20
--- /dev/null
+++ b/app/assets/images/emoji/sweet_potato.png
Binary files differ
diff --git a/app/assets/images/emoji/swimmer.png b/app/assets/images/emoji/swimmer.png
new file mode 100644
index 00000000000..55b4d72f9a7
--- /dev/null
+++ b/app/assets/images/emoji/swimmer.png
Binary files differ
diff --git a/app/assets/images/emoji/swimmer_tone1.png b/app/assets/images/emoji/swimmer_tone1.png
new file mode 100644
index 00000000000..38441c9ca9a
--- /dev/null
+++ b/app/assets/images/emoji/swimmer_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/swimmer_tone2.png b/app/assets/images/emoji/swimmer_tone2.png
new file mode 100644
index 00000000000..b0d43112444
--- /dev/null
+++ b/app/assets/images/emoji/swimmer_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/swimmer_tone3.png b/app/assets/images/emoji/swimmer_tone3.png
new file mode 100644
index 00000000000..211e77e2aa0
--- /dev/null
+++ b/app/assets/images/emoji/swimmer_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/swimmer_tone4.png b/app/assets/images/emoji/swimmer_tone4.png
new file mode 100644
index 00000000000..f34c34db9d2
--- /dev/null
+++ b/app/assets/images/emoji/swimmer_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/swimmer_tone5.png b/app/assets/images/emoji/swimmer_tone5.png
new file mode 100644
index 00000000000..3e9231ff868
--- /dev/null
+++ b/app/assets/images/emoji/swimmer_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/symbols.png b/app/assets/images/emoji/symbols.png
new file mode 100644
index 00000000000..ac2fc1f358f
--- /dev/null
+++ b/app/assets/images/emoji/symbols.png
Binary files differ
diff --git a/app/assets/images/emoji/synagogue.png b/app/assets/images/emoji/synagogue.png
new file mode 100644
index 00000000000..ee347904c80
--- /dev/null
+++ b/app/assets/images/emoji/synagogue.png
Binary files differ
diff --git a/app/assets/images/emoji/syringe.png b/app/assets/images/emoji/syringe.png
new file mode 100644
index 00000000000..71c1a9528d5
--- /dev/null
+++ b/app/assets/images/emoji/syringe.png
Binary files differ
diff --git a/app/assets/images/emoji/taco.png b/app/assets/images/emoji/taco.png
new file mode 100644
index 00000000000..10e847a4619
--- /dev/null
+++ b/app/assets/images/emoji/taco.png
Binary files differ
diff --git a/app/assets/images/emoji/tada.png b/app/assets/images/emoji/tada.png
new file mode 100644
index 00000000000..0244d60f269
--- /dev/null
+++ b/app/assets/images/emoji/tada.png
Binary files differ
diff --git a/app/assets/images/emoji/tanabata_tree.png b/app/assets/images/emoji/tanabata_tree.png
new file mode 100644
index 00000000000..46fcb3a1aac
--- /dev/null
+++ b/app/assets/images/emoji/tanabata_tree.png
Binary files differ
diff --git a/app/assets/images/emoji/tangerine.png b/app/assets/images/emoji/tangerine.png
new file mode 100644
index 00000000000..ab14e5378db
--- /dev/null
+++ b/app/assets/images/emoji/tangerine.png
Binary files differ
diff --git a/app/assets/images/emoji/taurus.png b/app/assets/images/emoji/taurus.png
new file mode 100644
index 00000000000..b2a370df42b
--- /dev/null
+++ b/app/assets/images/emoji/taurus.png
Binary files differ
diff --git a/app/assets/images/emoji/taxi.png b/app/assets/images/emoji/taxi.png
new file mode 100644
index 00000000000..55f4cc84797
--- /dev/null
+++ b/app/assets/images/emoji/taxi.png
Binary files differ
diff --git a/app/assets/images/emoji/tea.png b/app/assets/images/emoji/tea.png
new file mode 100644
index 00000000000..b53b98f0c45
--- /dev/null
+++ b/app/assets/images/emoji/tea.png
Binary files differ
diff --git a/app/assets/images/emoji/telephone.png b/app/assets/images/emoji/telephone.png
new file mode 100644
index 00000000000..a1e69f566bc
--- /dev/null
+++ b/app/assets/images/emoji/telephone.png
Binary files differ
diff --git a/app/assets/images/emoji/telephone_receiver.png b/app/assets/images/emoji/telephone_receiver.png
new file mode 100644
index 00000000000..69388316c35
--- /dev/null
+++ b/app/assets/images/emoji/telephone_receiver.png
Binary files differ
diff --git a/app/assets/images/emoji/telescope.png b/app/assets/images/emoji/telescope.png
new file mode 100644
index 00000000000..d63154614b5
--- /dev/null
+++ b/app/assets/images/emoji/telescope.png
Binary files differ
diff --git a/app/assets/images/emoji/ten.png b/app/assets/images/emoji/ten.png
new file mode 100644
index 00000000000..782d4004962
--- /dev/null
+++ b/app/assets/images/emoji/ten.png
Binary files differ
diff --git a/app/assets/images/emoji/tennis.png b/app/assets/images/emoji/tennis.png
new file mode 100644
index 00000000000..7e68ba8f301
--- /dev/null
+++ b/app/assets/images/emoji/tennis.png
Binary files differ
diff --git a/app/assets/images/emoji/tent.png b/app/assets/images/emoji/tent.png
new file mode 100644
index 00000000000..3fddcfc56eb
--- /dev/null
+++ b/app/assets/images/emoji/tent.png
Binary files differ
diff --git a/app/assets/images/emoji/thermometer.png b/app/assets/images/emoji/thermometer.png
new file mode 100644
index 00000000000..b1147392426
--- /dev/null
+++ b/app/assets/images/emoji/thermometer.png
Binary files differ
diff --git a/app/assets/images/emoji/thermometer_face.png b/app/assets/images/emoji/thermometer_face.png
new file mode 100644
index 00000000000..8fc57387563
--- /dev/null
+++ b/app/assets/images/emoji/thermometer_face.png
Binary files differ
diff --git a/app/assets/images/emoji/thinking.png b/app/assets/images/emoji/thinking.png
new file mode 100644
index 00000000000..c18f6fd14ad
--- /dev/null
+++ b/app/assets/images/emoji/thinking.png
Binary files differ
diff --git a/app/assets/images/emoji/third_place.png b/app/assets/images/emoji/third_place.png
new file mode 100644
index 00000000000..636e04a5950
--- /dev/null
+++ b/app/assets/images/emoji/third_place.png
Binary files differ
diff --git a/app/assets/images/emoji/thought_balloon.png b/app/assets/images/emoji/thought_balloon.png
new file mode 100644
index 00000000000..72fe8fa7022
--- /dev/null
+++ b/app/assets/images/emoji/thought_balloon.png
Binary files differ
diff --git a/app/assets/images/emoji/three.png b/app/assets/images/emoji/three.png
new file mode 100644
index 00000000000..dbaa6183e72
--- /dev/null
+++ b/app/assets/images/emoji/three.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsdown.png b/app/assets/images/emoji/thumbsdown.png
new file mode 100644
index 00000000000..b63da2f20a8
--- /dev/null
+++ b/app/assets/images/emoji/thumbsdown.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsdown_tone1.png b/app/assets/images/emoji/thumbsdown_tone1.png
new file mode 100644
index 00000000000..a1631af8e92
--- /dev/null
+++ b/app/assets/images/emoji/thumbsdown_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsdown_tone2.png b/app/assets/images/emoji/thumbsdown_tone2.png
new file mode 100644
index 00000000000..85fff82d595
--- /dev/null
+++ b/app/assets/images/emoji/thumbsdown_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsdown_tone3.png b/app/assets/images/emoji/thumbsdown_tone3.png
new file mode 100644
index 00000000000..eeba3be80fd
--- /dev/null
+++ b/app/assets/images/emoji/thumbsdown_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsdown_tone4.png b/app/assets/images/emoji/thumbsdown_tone4.png
new file mode 100644
index 00000000000..1addafdaed0
--- /dev/null
+++ b/app/assets/images/emoji/thumbsdown_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsdown_tone5.png b/app/assets/images/emoji/thumbsdown_tone5.png
new file mode 100644
index 00000000000..37ec07b5721
--- /dev/null
+++ b/app/assets/images/emoji/thumbsdown_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsup.png b/app/assets/images/emoji/thumbsup.png
new file mode 100644
index 00000000000..f9e6f13a34f
--- /dev/null
+++ b/app/assets/images/emoji/thumbsup.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsup_tone1.png b/app/assets/images/emoji/thumbsup_tone1.png
new file mode 100644
index 00000000000..39684cd5cc7
--- /dev/null
+++ b/app/assets/images/emoji/thumbsup_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsup_tone2.png b/app/assets/images/emoji/thumbsup_tone2.png
new file mode 100644
index 00000000000..a9b59723573
--- /dev/null
+++ b/app/assets/images/emoji/thumbsup_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsup_tone3.png b/app/assets/images/emoji/thumbsup_tone3.png
new file mode 100644
index 00000000000..c5e29167015
--- /dev/null
+++ b/app/assets/images/emoji/thumbsup_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsup_tone4.png b/app/assets/images/emoji/thumbsup_tone4.png
new file mode 100644
index 00000000000..5bf4857a884
--- /dev/null
+++ b/app/assets/images/emoji/thumbsup_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/thumbsup_tone5.png b/app/assets/images/emoji/thumbsup_tone5.png
new file mode 100644
index 00000000000..d829f787c61
--- /dev/null
+++ b/app/assets/images/emoji/thumbsup_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/thunder_cloud_rain.png b/app/assets/images/emoji/thunder_cloud_rain.png
new file mode 100644
index 00000000000..31a26a1b6ee
--- /dev/null
+++ b/app/assets/images/emoji/thunder_cloud_rain.png
Binary files differ
diff --git a/app/assets/images/emoji/ticket.png b/app/assets/images/emoji/ticket.png
new file mode 100644
index 00000000000..605936bb6b3
--- /dev/null
+++ b/app/assets/images/emoji/ticket.png
Binary files differ
diff --git a/app/assets/images/emoji/tickets.png b/app/assets/images/emoji/tickets.png
new file mode 100644
index 00000000000..e510f4a7a50
--- /dev/null
+++ b/app/assets/images/emoji/tickets.png
Binary files differ
diff --git a/app/assets/images/emoji/tiger.png b/app/assets/images/emoji/tiger.png
new file mode 100644
index 00000000000..a4d3ef086d4
--- /dev/null
+++ b/app/assets/images/emoji/tiger.png
Binary files differ
diff --git a/app/assets/images/emoji/tiger2.png b/app/assets/images/emoji/tiger2.png
new file mode 100644
index 00000000000..871a8b74d56
--- /dev/null
+++ b/app/assets/images/emoji/tiger2.png
Binary files differ
diff --git a/app/assets/images/emoji/timer.png b/app/assets/images/emoji/timer.png
new file mode 100644
index 00000000000..8a3be574c24
--- /dev/null
+++ b/app/assets/images/emoji/timer.png
Binary files differ
diff --git a/app/assets/images/emoji/tired_face.png b/app/assets/images/emoji/tired_face.png
new file mode 100644
index 00000000000..4e01eff5b23
--- /dev/null
+++ b/app/assets/images/emoji/tired_face.png
Binary files differ
diff --git a/app/assets/images/emoji/tm.png b/app/assets/images/emoji/tm.png
new file mode 100644
index 00000000000..7a0c44a2c2b
--- /dev/null
+++ b/app/assets/images/emoji/tm.png
Binary files differ
diff --git a/app/assets/images/emoji/toilet.png b/app/assets/images/emoji/toilet.png
new file mode 100644
index 00000000000..1392f761835
--- /dev/null
+++ b/app/assets/images/emoji/toilet.png
Binary files differ
diff --git a/app/assets/images/emoji/tokyo_tower.png b/app/assets/images/emoji/tokyo_tower.png
new file mode 100644
index 00000000000..37df7fc65b1
--- /dev/null
+++ b/app/assets/images/emoji/tokyo_tower.png
Binary files differ
diff --git a/app/assets/images/emoji/tomato.png b/app/assets/images/emoji/tomato.png
new file mode 100644
index 00000000000..497da8f6b22
--- /dev/null
+++ b/app/assets/images/emoji/tomato.png
Binary files differ
diff --git a/app/assets/images/emoji/tone1.png b/app/assets/images/emoji/tone1.png
new file mode 100644
index 00000000000..c395f3d0d68
--- /dev/null
+++ b/app/assets/images/emoji/tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/tone2.png b/app/assets/images/emoji/tone2.png
new file mode 100644
index 00000000000..080847431c1
--- /dev/null
+++ b/app/assets/images/emoji/tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/tone3.png b/app/assets/images/emoji/tone3.png
new file mode 100644
index 00000000000..482dd403475
--- /dev/null
+++ b/app/assets/images/emoji/tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/tone4.png b/app/assets/images/emoji/tone4.png
new file mode 100644
index 00000000000..5cae8bb20b0
--- /dev/null
+++ b/app/assets/images/emoji/tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/tone5.png b/app/assets/images/emoji/tone5.png
new file mode 100644
index 00000000000..49d1a8c3a64
--- /dev/null
+++ b/app/assets/images/emoji/tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/tongue.png b/app/assets/images/emoji/tongue.png
new file mode 100644
index 00000000000..70ce9c1225f
--- /dev/null
+++ b/app/assets/images/emoji/tongue.png
Binary files differ
diff --git a/app/assets/images/emoji/tools.png b/app/assets/images/emoji/tools.png
new file mode 100644
index 00000000000..3c6049273a9
--- /dev/null
+++ b/app/assets/images/emoji/tools.png
Binary files differ
diff --git a/app/assets/images/emoji/top.png b/app/assets/images/emoji/top.png
new file mode 100644
index 00000000000..49dea8c08b5
--- /dev/null
+++ b/app/assets/images/emoji/top.png
Binary files differ
diff --git a/app/assets/images/emoji/tophat.png b/app/assets/images/emoji/tophat.png
new file mode 100644
index 00000000000..131b657b109
--- /dev/null
+++ b/app/assets/images/emoji/tophat.png
Binary files differ
diff --git a/app/assets/images/emoji/track_next.png b/app/assets/images/emoji/track_next.png
new file mode 100644
index 00000000000..f8880d33bab
--- /dev/null
+++ b/app/assets/images/emoji/track_next.png
Binary files differ
diff --git a/app/assets/images/emoji/track_previous.png b/app/assets/images/emoji/track_previous.png
new file mode 100644
index 00000000000..1ffd0566cfc
--- /dev/null
+++ b/app/assets/images/emoji/track_previous.png
Binary files differ
diff --git a/app/assets/images/emoji/trackball.png b/app/assets/images/emoji/trackball.png
new file mode 100644
index 00000000000..3bea84ad7ce
--- /dev/null
+++ b/app/assets/images/emoji/trackball.png
Binary files differ
diff --git a/app/assets/images/emoji/tractor.png b/app/assets/images/emoji/tractor.png
new file mode 100644
index 00000000000..c1bf8cae44f
--- /dev/null
+++ b/app/assets/images/emoji/tractor.png
Binary files differ
diff --git a/app/assets/images/emoji/traffic_light.png b/app/assets/images/emoji/traffic_light.png
new file mode 100644
index 00000000000..6b312285b00
--- /dev/null
+++ b/app/assets/images/emoji/traffic_light.png
Binary files differ
diff --git a/app/assets/images/emoji/train.png b/app/assets/images/emoji/train.png
new file mode 100644
index 00000000000..3c80321f7e8
--- /dev/null
+++ b/app/assets/images/emoji/train.png
Binary files differ
diff --git a/app/assets/images/emoji/train2.png b/app/assets/images/emoji/train2.png
new file mode 100644
index 00000000000..367c7bc5d39
--- /dev/null
+++ b/app/assets/images/emoji/train2.png
Binary files differ
diff --git a/app/assets/images/emoji/tram.png b/app/assets/images/emoji/tram.png
new file mode 100644
index 00000000000..b6f0e69038f
--- /dev/null
+++ b/app/assets/images/emoji/tram.png
Binary files differ
diff --git a/app/assets/images/emoji/triangular_flag_on_post.png b/app/assets/images/emoji/triangular_flag_on_post.png
new file mode 100644
index 00000000000..c12d8b06886
--- /dev/null
+++ b/app/assets/images/emoji/triangular_flag_on_post.png
Binary files differ
diff --git a/app/assets/images/emoji/triangular_ruler.png b/app/assets/images/emoji/triangular_ruler.png
new file mode 100644
index 00000000000..77dee9ee843
--- /dev/null
+++ b/app/assets/images/emoji/triangular_ruler.png
Binary files differ
diff --git a/app/assets/images/emoji/trident.png b/app/assets/images/emoji/trident.png
new file mode 100644
index 00000000000..777a1dad121
--- /dev/null
+++ b/app/assets/images/emoji/trident.png
Binary files differ
diff --git a/app/assets/images/emoji/triumph.png b/app/assets/images/emoji/triumph.png
new file mode 100644
index 00000000000..0be7a501969
--- /dev/null
+++ b/app/assets/images/emoji/triumph.png
Binary files differ
diff --git a/app/assets/images/emoji/trolleybus.png b/app/assets/images/emoji/trolleybus.png
new file mode 100644
index 00000000000..139a9931b52
--- /dev/null
+++ b/app/assets/images/emoji/trolleybus.png
Binary files differ
diff --git a/app/assets/images/emoji/trophy.png b/app/assets/images/emoji/trophy.png
new file mode 100644
index 00000000000..ac2895c1896
--- /dev/null
+++ b/app/assets/images/emoji/trophy.png
Binary files differ
diff --git a/app/assets/images/emoji/tropical_drink.png b/app/assets/images/emoji/tropical_drink.png
new file mode 100644
index 00000000000..cd714f81b36
--- /dev/null
+++ b/app/assets/images/emoji/tropical_drink.png
Binary files differ
diff --git a/app/assets/images/emoji/tropical_fish.png b/app/assets/images/emoji/tropical_fish.png
new file mode 100644
index 00000000000..252105235a6
--- /dev/null
+++ b/app/assets/images/emoji/tropical_fish.png
Binary files differ
diff --git a/app/assets/images/emoji/truck.png b/app/assets/images/emoji/truck.png
new file mode 100644
index 00000000000..130de047f8b
--- /dev/null
+++ b/app/assets/images/emoji/truck.png
Binary files differ
diff --git a/app/assets/images/emoji/trumpet.png b/app/assets/images/emoji/trumpet.png
new file mode 100644
index 00000000000..864ccbcd04a
--- /dev/null
+++ b/app/assets/images/emoji/trumpet.png
Binary files differ
diff --git a/app/assets/images/emoji/tulip.png b/app/assets/images/emoji/tulip.png
new file mode 100644
index 00000000000..f799d75c182
--- /dev/null
+++ b/app/assets/images/emoji/tulip.png
Binary files differ
diff --git a/app/assets/images/emoji/tumbler_glass.png b/app/assets/images/emoji/tumbler_glass.png
new file mode 100644
index 00000000000..7bf09229879
--- /dev/null
+++ b/app/assets/images/emoji/tumbler_glass.png
Binary files differ
diff --git a/app/assets/images/emoji/turkey.png b/app/assets/images/emoji/turkey.png
new file mode 100644
index 00000000000..344af94c9ec
--- /dev/null
+++ b/app/assets/images/emoji/turkey.png
Binary files differ
diff --git a/app/assets/images/emoji/turtle.png b/app/assets/images/emoji/turtle.png
new file mode 100644
index 00000000000..c22f7519fe8
--- /dev/null
+++ b/app/assets/images/emoji/turtle.png
Binary files differ
diff --git a/app/assets/images/emoji/tv.png b/app/assets/images/emoji/tv.png
new file mode 100644
index 00000000000..999f1fb5c6d
--- /dev/null
+++ b/app/assets/images/emoji/tv.png
Binary files differ
diff --git a/app/assets/images/emoji/twisted_rightwards_arrows.png b/app/assets/images/emoji/twisted_rightwards_arrows.png
new file mode 100644
index 00000000000..5904badde65
--- /dev/null
+++ b/app/assets/images/emoji/twisted_rightwards_arrows.png
Binary files differ
diff --git a/app/assets/images/emoji/two.png b/app/assets/images/emoji/two.png
new file mode 100644
index 00000000000..927339c9bff
--- /dev/null
+++ b/app/assets/images/emoji/two.png
Binary files differ
diff --git a/app/assets/images/emoji/two_hearts.png b/app/assets/images/emoji/two_hearts.png
new file mode 100644
index 00000000000..4d8c3386042
--- /dev/null
+++ b/app/assets/images/emoji/two_hearts.png
Binary files differ
diff --git a/app/assets/images/emoji/two_men_holding_hands.png b/app/assets/images/emoji/two_men_holding_hands.png
new file mode 100644
index 00000000000..a511fda822a
--- /dev/null
+++ b/app/assets/images/emoji/two_men_holding_hands.png
Binary files differ
diff --git a/app/assets/images/emoji/two_women_holding_hands.png b/app/assets/images/emoji/two_women_holding_hands.png
new file mode 100644
index 00000000000..b077cd3e40f
--- /dev/null
+++ b/app/assets/images/emoji/two_women_holding_hands.png
Binary files differ
diff --git a/app/assets/images/emoji/u5272.png b/app/assets/images/emoji/u5272.png
new file mode 100644
index 00000000000..c4f837fe684
--- /dev/null
+++ b/app/assets/images/emoji/u5272.png
Binary files differ
diff --git a/app/assets/images/emoji/u5408.png b/app/assets/images/emoji/u5408.png
new file mode 100644
index 00000000000..8375ad9d9af
--- /dev/null
+++ b/app/assets/images/emoji/u5408.png
Binary files differ
diff --git a/app/assets/images/emoji/u55b6.png b/app/assets/images/emoji/u55b6.png
new file mode 100644
index 00000000000..d21cb30eaf3
--- /dev/null
+++ b/app/assets/images/emoji/u55b6.png
Binary files differ
diff --git a/app/assets/images/emoji/u6307.png b/app/assets/images/emoji/u6307.png
new file mode 100644
index 00000000000..078e23e4ff3
--- /dev/null
+++ b/app/assets/images/emoji/u6307.png
Binary files differ
diff --git a/app/assets/images/emoji/u6708.png b/app/assets/images/emoji/u6708.png
new file mode 100644
index 00000000000..c41bd36a26a
--- /dev/null
+++ b/app/assets/images/emoji/u6708.png
Binary files differ
diff --git a/app/assets/images/emoji/u6709.png b/app/assets/images/emoji/u6709.png
new file mode 100644
index 00000000000..a4510de41c0
--- /dev/null
+++ b/app/assets/images/emoji/u6709.png
Binary files differ
diff --git a/app/assets/images/emoji/u6e80.png b/app/assets/images/emoji/u6e80.png
new file mode 100644
index 00000000000..f9dea8b8833
--- /dev/null
+++ b/app/assets/images/emoji/u6e80.png
Binary files differ
diff --git a/app/assets/images/emoji/u7121.png b/app/assets/images/emoji/u7121.png
new file mode 100644
index 00000000000..d3a19b420de
--- /dev/null
+++ b/app/assets/images/emoji/u7121.png
Binary files differ
diff --git a/app/assets/images/emoji/u7533.png b/app/assets/images/emoji/u7533.png
new file mode 100644
index 00000000000..6b7af0ee222
--- /dev/null
+++ b/app/assets/images/emoji/u7533.png
Binary files differ
diff --git a/app/assets/images/emoji/u7981.png b/app/assets/images/emoji/u7981.png
new file mode 100644
index 00000000000..4c704e03433
--- /dev/null
+++ b/app/assets/images/emoji/u7981.png
Binary files differ
diff --git a/app/assets/images/emoji/u7a7a.png b/app/assets/images/emoji/u7a7a.png
new file mode 100644
index 00000000000..47966c1ea93
--- /dev/null
+++ b/app/assets/images/emoji/u7a7a.png
Binary files differ
diff --git a/app/assets/images/emoji/umbrella.png b/app/assets/images/emoji/umbrella.png
new file mode 100644
index 00000000000..5b35b7ff6a4
--- /dev/null
+++ b/app/assets/images/emoji/umbrella.png
Binary files differ
diff --git a/app/assets/images/emoji/umbrella2.png b/app/assets/images/emoji/umbrella2.png
new file mode 100644
index 00000000000..97fe859e74f
--- /dev/null
+++ b/app/assets/images/emoji/umbrella2.png
Binary files differ
diff --git a/app/assets/images/emoji/unamused.png b/app/assets/images/emoji/unamused.png
new file mode 100644
index 00000000000..25e3677f2eb
--- /dev/null
+++ b/app/assets/images/emoji/unamused.png
Binary files differ
diff --git a/app/assets/images/emoji/underage.png b/app/assets/images/emoji/underage.png
new file mode 100644
index 00000000000..6dfe6da51e2
--- /dev/null
+++ b/app/assets/images/emoji/underage.png
Binary files differ
diff --git a/app/assets/images/emoji/unicorn.png b/app/assets/images/emoji/unicorn.png
new file mode 100644
index 00000000000..05a97969f7e
--- /dev/null
+++ b/app/assets/images/emoji/unicorn.png
Binary files differ
diff --git a/app/assets/images/emoji/unlock.png b/app/assets/images/emoji/unlock.png
new file mode 100644
index 00000000000..4a74a693911
--- /dev/null
+++ b/app/assets/images/emoji/unlock.png
Binary files differ
diff --git a/app/assets/images/emoji/up.png b/app/assets/images/emoji/up.png
new file mode 100644
index 00000000000..0d42142ba04
--- /dev/null
+++ b/app/assets/images/emoji/up.png
Binary files differ
diff --git a/app/assets/images/emoji/upside_down.png b/app/assets/images/emoji/upside_down.png
new file mode 100644
index 00000000000..128f31c9828
--- /dev/null
+++ b/app/assets/images/emoji/upside_down.png
Binary files differ
diff --git a/app/assets/images/emoji/urn.png b/app/assets/images/emoji/urn.png
new file mode 100644
index 00000000000..6b5b3503438
--- /dev/null
+++ b/app/assets/images/emoji/urn.png
Binary files differ
diff --git a/app/assets/images/emoji/v.png b/app/assets/images/emoji/v.png
new file mode 100644
index 00000000000..70c5516ffee
--- /dev/null
+++ b/app/assets/images/emoji/v.png
Binary files differ
diff --git a/app/assets/images/emoji/v_tone1.png b/app/assets/images/emoji/v_tone1.png
new file mode 100644
index 00000000000..6ac54a745f4
--- /dev/null
+++ b/app/assets/images/emoji/v_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/v_tone2.png b/app/assets/images/emoji/v_tone2.png
new file mode 100644
index 00000000000..6dd9669866d
--- /dev/null
+++ b/app/assets/images/emoji/v_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/v_tone3.png b/app/assets/images/emoji/v_tone3.png
new file mode 100644
index 00000000000..a615e53f02f
--- /dev/null
+++ b/app/assets/images/emoji/v_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/v_tone4.png b/app/assets/images/emoji/v_tone4.png
new file mode 100644
index 00000000000..33a34bd5a78
--- /dev/null
+++ b/app/assets/images/emoji/v_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/v_tone5.png b/app/assets/images/emoji/v_tone5.png
new file mode 100644
index 00000000000..45ad14b6c9c
--- /dev/null
+++ b/app/assets/images/emoji/v_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/vertical_traffic_light.png b/app/assets/images/emoji/vertical_traffic_light.png
new file mode 100644
index 00000000000..8085973eecf
--- /dev/null
+++ b/app/assets/images/emoji/vertical_traffic_light.png
Binary files differ
diff --git a/app/assets/images/emoji/vhs.png b/app/assets/images/emoji/vhs.png
new file mode 100644
index 00000000000..b9eb78ecd92
--- /dev/null
+++ b/app/assets/images/emoji/vhs.png
Binary files differ
diff --git a/app/assets/images/emoji/vibration_mode.png b/app/assets/images/emoji/vibration_mode.png
new file mode 100644
index 00000000000..cc46510e48e
--- /dev/null
+++ b/app/assets/images/emoji/vibration_mode.png
Binary files differ
diff --git a/app/assets/images/emoji/video_camera.png b/app/assets/images/emoji/video_camera.png
new file mode 100644
index 00000000000..85b300d425c
--- /dev/null
+++ b/app/assets/images/emoji/video_camera.png
Binary files differ
diff --git a/app/assets/images/emoji/video_game.png b/app/assets/images/emoji/video_game.png
new file mode 100644
index 00000000000..316a9106a55
--- /dev/null
+++ b/app/assets/images/emoji/video_game.png
Binary files differ
diff --git a/app/assets/images/emoji/violin.png b/app/assets/images/emoji/violin.png
new file mode 100644
index 00000000000..e1e76cce242
--- /dev/null
+++ b/app/assets/images/emoji/violin.png
Binary files differ
diff --git a/app/assets/images/emoji/virgo.png b/app/assets/images/emoji/virgo.png
new file mode 100644
index 00000000000..a6b56c2cb5e
--- /dev/null
+++ b/app/assets/images/emoji/virgo.png
Binary files differ
diff --git a/app/assets/images/emoji/volcano.png b/app/assets/images/emoji/volcano.png
new file mode 100644
index 00000000000..931d569294c
--- /dev/null
+++ b/app/assets/images/emoji/volcano.png
Binary files differ
diff --git a/app/assets/images/emoji/volleyball.png b/app/assets/images/emoji/volleyball.png
new file mode 100644
index 00000000000..7a0e49d4b07
--- /dev/null
+++ b/app/assets/images/emoji/volleyball.png
Binary files differ
diff --git a/app/assets/images/emoji/vs.png b/app/assets/images/emoji/vs.png
new file mode 100644
index 00000000000..e1180f4a464
--- /dev/null
+++ b/app/assets/images/emoji/vs.png
Binary files differ
diff --git a/app/assets/images/emoji/vulcan.png b/app/assets/images/emoji/vulcan.png
new file mode 100644
index 00000000000..54728bcaf5c
--- /dev/null
+++ b/app/assets/images/emoji/vulcan.png
Binary files differ
diff --git a/app/assets/images/emoji/vulcan_tone1.png b/app/assets/images/emoji/vulcan_tone1.png
new file mode 100644
index 00000000000..8aff5d8fa16
--- /dev/null
+++ b/app/assets/images/emoji/vulcan_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/vulcan_tone2.png b/app/assets/images/emoji/vulcan_tone2.png
new file mode 100644
index 00000000000..82b7ad519b4
--- /dev/null
+++ b/app/assets/images/emoji/vulcan_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/vulcan_tone3.png b/app/assets/images/emoji/vulcan_tone3.png
new file mode 100644
index 00000000000..d1400e1dd28
--- /dev/null
+++ b/app/assets/images/emoji/vulcan_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/vulcan_tone4.png b/app/assets/images/emoji/vulcan_tone4.png
new file mode 100644
index 00000000000..47e2b280148
--- /dev/null
+++ b/app/assets/images/emoji/vulcan_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/vulcan_tone5.png b/app/assets/images/emoji/vulcan_tone5.png
new file mode 100644
index 00000000000..60b5c6077be
--- /dev/null
+++ b/app/assets/images/emoji/vulcan_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/walking.png b/app/assets/images/emoji/walking.png
new file mode 100644
index 00000000000..06dc169a3fd
--- /dev/null
+++ b/app/assets/images/emoji/walking.png
Binary files differ
diff --git a/app/assets/images/emoji/walking_tone1.png b/app/assets/images/emoji/walking_tone1.png
new file mode 100644
index 00000000000..4e391b45a0b
--- /dev/null
+++ b/app/assets/images/emoji/walking_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/walking_tone2.png b/app/assets/images/emoji/walking_tone2.png
new file mode 100644
index 00000000000..31f94a1bce1
--- /dev/null
+++ b/app/assets/images/emoji/walking_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/walking_tone3.png b/app/assets/images/emoji/walking_tone3.png
new file mode 100644
index 00000000000..f7ed8e39c2e
--- /dev/null
+++ b/app/assets/images/emoji/walking_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/walking_tone4.png b/app/assets/images/emoji/walking_tone4.png
new file mode 100644
index 00000000000..e58dc04c7b2
--- /dev/null
+++ b/app/assets/images/emoji/walking_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/walking_tone5.png b/app/assets/images/emoji/walking_tone5.png
new file mode 100644
index 00000000000..ba4e1b58fcb
--- /dev/null
+++ b/app/assets/images/emoji/walking_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/waning_crescent_moon.png b/app/assets/images/emoji/waning_crescent_moon.png
new file mode 100644
index 00000000000..cf68706b871
--- /dev/null
+++ b/app/assets/images/emoji/waning_crescent_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/waning_gibbous_moon.png b/app/assets/images/emoji/waning_gibbous_moon.png
new file mode 100644
index 00000000000..24e16266119
--- /dev/null
+++ b/app/assets/images/emoji/waning_gibbous_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/warning.png b/app/assets/images/emoji/warning.png
new file mode 100644
index 00000000000..35691c2ed97
--- /dev/null
+++ b/app/assets/images/emoji/warning.png
Binary files differ
diff --git a/app/assets/images/emoji/wastebasket.png b/app/assets/images/emoji/wastebasket.png
new file mode 100644
index 00000000000..2b3c484b498
--- /dev/null
+++ b/app/assets/images/emoji/wastebasket.png
Binary files differ
diff --git a/app/assets/images/emoji/watch.png b/app/assets/images/emoji/watch.png
new file mode 100644
index 00000000000..64819bc6e21
--- /dev/null
+++ b/app/assets/images/emoji/watch.png
Binary files differ
diff --git a/app/assets/images/emoji/water_buffalo.png b/app/assets/images/emoji/water_buffalo.png
new file mode 100644
index 00000000000..80446615caf
--- /dev/null
+++ b/app/assets/images/emoji/water_buffalo.png
Binary files differ
diff --git a/app/assets/images/emoji/water_polo.png b/app/assets/images/emoji/water_polo.png
new file mode 100644
index 00000000000..cb44576780d
--- /dev/null
+++ b/app/assets/images/emoji/water_polo.png
Binary files differ
diff --git a/app/assets/images/emoji/water_polo_tone1.png b/app/assets/images/emoji/water_polo_tone1.png
new file mode 100644
index 00000000000..bed1a908d6a
--- /dev/null
+++ b/app/assets/images/emoji/water_polo_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/water_polo_tone2.png b/app/assets/images/emoji/water_polo_tone2.png
new file mode 100644
index 00000000000..ec5a43b4d4a
--- /dev/null
+++ b/app/assets/images/emoji/water_polo_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/water_polo_tone3.png b/app/assets/images/emoji/water_polo_tone3.png
new file mode 100644
index 00000000000..b081a4a5a96
--- /dev/null
+++ b/app/assets/images/emoji/water_polo_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/water_polo_tone4.png b/app/assets/images/emoji/water_polo_tone4.png
new file mode 100644
index 00000000000..82cfbc3b0c7
--- /dev/null
+++ b/app/assets/images/emoji/water_polo_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/water_polo_tone5.png b/app/assets/images/emoji/water_polo_tone5.png
new file mode 100644
index 00000000000..bd3366eb06c
--- /dev/null
+++ b/app/assets/images/emoji/water_polo_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/watermelon.png b/app/assets/images/emoji/watermelon.png
new file mode 100644
index 00000000000..0761488b4c9
--- /dev/null
+++ b/app/assets/images/emoji/watermelon.png
Binary files differ
diff --git a/app/assets/images/emoji/wave.png b/app/assets/images/emoji/wave.png
new file mode 100644
index 00000000000..e0cd79b45f5
--- /dev/null
+++ b/app/assets/images/emoji/wave.png
Binary files differ
diff --git a/app/assets/images/emoji/wave_tone1.png b/app/assets/images/emoji/wave_tone1.png
new file mode 100644
index 00000000000..6b2b34b106e
--- /dev/null
+++ b/app/assets/images/emoji/wave_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/wave_tone2.png b/app/assets/images/emoji/wave_tone2.png
new file mode 100644
index 00000000000..b857119732e
--- /dev/null
+++ b/app/assets/images/emoji/wave_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/wave_tone3.png b/app/assets/images/emoji/wave_tone3.png
new file mode 100644
index 00000000000..6283b670f43
--- /dev/null
+++ b/app/assets/images/emoji/wave_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/wave_tone4.png b/app/assets/images/emoji/wave_tone4.png
new file mode 100644
index 00000000000..fe6b2baa747
--- /dev/null
+++ b/app/assets/images/emoji/wave_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/wave_tone5.png b/app/assets/images/emoji/wave_tone5.png
new file mode 100644
index 00000000000..4bd168ebb78
--- /dev/null
+++ b/app/assets/images/emoji/wave_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/wavy_dash.png b/app/assets/images/emoji/wavy_dash.png
new file mode 100644
index 00000000000..001c8d6e47d
--- /dev/null
+++ b/app/assets/images/emoji/wavy_dash.png
Binary files differ
diff --git a/app/assets/images/emoji/waxing_crescent_moon.png b/app/assets/images/emoji/waxing_crescent_moon.png
new file mode 100644
index 00000000000..687125173d9
--- /dev/null
+++ b/app/assets/images/emoji/waxing_crescent_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/waxing_gibbous_moon.png b/app/assets/images/emoji/waxing_gibbous_moon.png
new file mode 100644
index 00000000000..3a808156318
--- /dev/null
+++ b/app/assets/images/emoji/waxing_gibbous_moon.png
Binary files differ
diff --git a/app/assets/images/emoji/wc.png b/app/assets/images/emoji/wc.png
new file mode 100644
index 00000000000..aa433e84ba6
--- /dev/null
+++ b/app/assets/images/emoji/wc.png
Binary files differ
diff --git a/app/assets/images/emoji/weary.png b/app/assets/images/emoji/weary.png
new file mode 100644
index 00000000000..98bfbd24a16
--- /dev/null
+++ b/app/assets/images/emoji/weary.png
Binary files differ
diff --git a/app/assets/images/emoji/wedding.png b/app/assets/images/emoji/wedding.png
new file mode 100644
index 00000000000..d0d8aa0bfae
--- /dev/null
+++ b/app/assets/images/emoji/wedding.png
Binary files differ
diff --git a/app/assets/images/emoji/whale.png b/app/assets/images/emoji/whale.png
new file mode 100644
index 00000000000..9f19b44257c
--- /dev/null
+++ b/app/assets/images/emoji/whale.png
Binary files differ
diff --git a/app/assets/images/emoji/whale2.png b/app/assets/images/emoji/whale2.png
new file mode 100644
index 00000000000..0df9d3c73a4
--- /dev/null
+++ b/app/assets/images/emoji/whale2.png
Binary files differ
diff --git a/app/assets/images/emoji/wheel_of_dharma.png b/app/assets/images/emoji/wheel_of_dharma.png
new file mode 100644
index 00000000000..3666db0016b
--- /dev/null
+++ b/app/assets/images/emoji/wheel_of_dharma.png
Binary files differ
diff --git a/app/assets/images/emoji/wheelchair.png b/app/assets/images/emoji/wheelchair.png
new file mode 100644
index 00000000000..4e5b2698eac
--- /dev/null
+++ b/app/assets/images/emoji/wheelchair.png
Binary files differ
diff --git a/app/assets/images/emoji/white_check_mark.png b/app/assets/images/emoji/white_check_mark.png
new file mode 100644
index 00000000000..e55f087e544
--- /dev/null
+++ b/app/assets/images/emoji/white_check_mark.png
Binary files differ
diff --git a/app/assets/images/emoji/white_circle.png b/app/assets/images/emoji/white_circle.png
new file mode 100644
index 00000000000..c19e15684dd
--- /dev/null
+++ b/app/assets/images/emoji/white_circle.png
Binary files differ
diff --git a/app/assets/images/emoji/white_flower.png b/app/assets/images/emoji/white_flower.png
new file mode 100644
index 00000000000..d6af8b60077
--- /dev/null
+++ b/app/assets/images/emoji/white_flower.png
Binary files differ
diff --git a/app/assets/images/emoji/white_large_square.png b/app/assets/images/emoji/white_large_square.png
new file mode 100644
index 00000000000..6f06c1c79de
--- /dev/null
+++ b/app/assets/images/emoji/white_large_square.png
Binary files differ
diff --git a/app/assets/images/emoji/white_medium_small_square.png b/app/assets/images/emoji/white_medium_small_square.png
new file mode 100644
index 00000000000..ae874126750
--- /dev/null
+++ b/app/assets/images/emoji/white_medium_small_square.png
Binary files differ
diff --git a/app/assets/images/emoji/white_medium_square.png b/app/assets/images/emoji/white_medium_square.png
new file mode 100644
index 00000000000..8daacf57059
--- /dev/null
+++ b/app/assets/images/emoji/white_medium_square.png
Binary files differ
diff --git a/app/assets/images/emoji/white_small_square.png b/app/assets/images/emoji/white_small_square.png
new file mode 100644
index 00000000000..d7ebdb0c0ed
--- /dev/null
+++ b/app/assets/images/emoji/white_small_square.png
Binary files differ
diff --git a/app/assets/images/emoji/white_square_button.png b/app/assets/images/emoji/white_square_button.png
new file mode 100644
index 00000000000..934b1cedfd2
--- /dev/null
+++ b/app/assets/images/emoji/white_square_button.png
Binary files differ
diff --git a/app/assets/images/emoji/white_sun_cloud.png b/app/assets/images/emoji/white_sun_cloud.png
new file mode 100644
index 00000000000..0a4cc100269
--- /dev/null
+++ b/app/assets/images/emoji/white_sun_cloud.png
Binary files differ
diff --git a/app/assets/images/emoji/white_sun_rain_cloud.png b/app/assets/images/emoji/white_sun_rain_cloud.png
new file mode 100644
index 00000000000..491f9ca4839
--- /dev/null
+++ b/app/assets/images/emoji/white_sun_rain_cloud.png
Binary files differ
diff --git a/app/assets/images/emoji/white_sun_small_cloud.png b/app/assets/images/emoji/white_sun_small_cloud.png
new file mode 100644
index 00000000000..cead0bfa521
--- /dev/null
+++ b/app/assets/images/emoji/white_sun_small_cloud.png
Binary files differ
diff --git a/app/assets/images/emoji/wilted_rose.png b/app/assets/images/emoji/wilted_rose.png
new file mode 100644
index 00000000000..62412b143ae
--- /dev/null
+++ b/app/assets/images/emoji/wilted_rose.png
Binary files differ
diff --git a/app/assets/images/emoji/wind_blowing_face.png b/app/assets/images/emoji/wind_blowing_face.png
new file mode 100644
index 00000000000..df81b652eb6
--- /dev/null
+++ b/app/assets/images/emoji/wind_blowing_face.png
Binary files differ
diff --git a/app/assets/images/emoji/wind_chime.png b/app/assets/images/emoji/wind_chime.png
new file mode 100644
index 00000000000..3c9ef3a95f6
--- /dev/null
+++ b/app/assets/images/emoji/wind_chime.png
Binary files differ
diff --git a/app/assets/images/emoji/wine_glass.png b/app/assets/images/emoji/wine_glass.png
new file mode 100644
index 00000000000..3cc98689192
--- /dev/null
+++ b/app/assets/images/emoji/wine_glass.png
Binary files differ
diff --git a/app/assets/images/emoji/wink.png b/app/assets/images/emoji/wink.png
new file mode 100644
index 00000000000..7ea7810a37d
--- /dev/null
+++ b/app/assets/images/emoji/wink.png
Binary files differ
diff --git a/app/assets/images/emoji/wolf.png b/app/assets/images/emoji/wolf.png
new file mode 100644
index 00000000000..ba7220f2de9
--- /dev/null
+++ b/app/assets/images/emoji/wolf.png
Binary files differ
diff --git a/app/assets/images/emoji/woman.png b/app/assets/images/emoji/woman.png
new file mode 100644
index 00000000000..ece440e7a61
--- /dev/null
+++ b/app/assets/images/emoji/woman.png
Binary files differ
diff --git a/app/assets/images/emoji/woman_tone1.png b/app/assets/images/emoji/woman_tone1.png
new file mode 100644
index 00000000000..ff089b8889b
--- /dev/null
+++ b/app/assets/images/emoji/woman_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/woman_tone2.png b/app/assets/images/emoji/woman_tone2.png
new file mode 100644
index 00000000000..0719c378016
--- /dev/null
+++ b/app/assets/images/emoji/woman_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/woman_tone3.png b/app/assets/images/emoji/woman_tone3.png
new file mode 100644
index 00000000000..5672e2fd52d
--- /dev/null
+++ b/app/assets/images/emoji/woman_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/woman_tone4.png b/app/assets/images/emoji/woman_tone4.png
new file mode 100644
index 00000000000..5754aab558b
--- /dev/null
+++ b/app/assets/images/emoji/woman_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/woman_tone5.png b/app/assets/images/emoji/woman_tone5.png
new file mode 100644
index 00000000000..fc252af3a39
--- /dev/null
+++ b/app/assets/images/emoji/woman_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/womans_clothes.png b/app/assets/images/emoji/womans_clothes.png
new file mode 100644
index 00000000000..01410dc8107
--- /dev/null
+++ b/app/assets/images/emoji/womans_clothes.png
Binary files differ
diff --git a/app/assets/images/emoji/womans_hat.png b/app/assets/images/emoji/womans_hat.png
new file mode 100644
index 00000000000..b837b6a2e47
--- /dev/null
+++ b/app/assets/images/emoji/womans_hat.png
Binary files differ
diff --git a/app/assets/images/emoji/womens.png b/app/assets/images/emoji/womens.png
new file mode 100644
index 00000000000..d4ecc22e7b3
--- /dev/null
+++ b/app/assets/images/emoji/womens.png
Binary files differ
diff --git a/app/assets/images/emoji/worried.png b/app/assets/images/emoji/worried.png
new file mode 100644
index 00000000000..7074afcf5b7
--- /dev/null
+++ b/app/assets/images/emoji/worried.png
Binary files differ
diff --git a/app/assets/images/emoji/wrench.png b/app/assets/images/emoji/wrench.png
new file mode 100644
index 00000000000..c16b7439697
--- /dev/null
+++ b/app/assets/images/emoji/wrench.png
Binary files differ
diff --git a/app/assets/images/emoji/wrestlers.png b/app/assets/images/emoji/wrestlers.png
new file mode 100644
index 00000000000..71e67cfad85
--- /dev/null
+++ b/app/assets/images/emoji/wrestlers.png
Binary files differ
diff --git a/app/assets/images/emoji/wrestlers_tone1.png b/app/assets/images/emoji/wrestlers_tone1.png
new file mode 100644
index 00000000000..379070fd03b
--- /dev/null
+++ b/app/assets/images/emoji/wrestlers_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/wrestlers_tone2.png b/app/assets/images/emoji/wrestlers_tone2.png
new file mode 100644
index 00000000000..6863ea9209d
--- /dev/null
+++ b/app/assets/images/emoji/wrestlers_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/wrestlers_tone3.png b/app/assets/images/emoji/wrestlers_tone3.png
new file mode 100644
index 00000000000..b7e62910127
--- /dev/null
+++ b/app/assets/images/emoji/wrestlers_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/wrestlers_tone4.png b/app/assets/images/emoji/wrestlers_tone4.png
new file mode 100644
index 00000000000..750f9589233
--- /dev/null
+++ b/app/assets/images/emoji/wrestlers_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/wrestlers_tone5.png b/app/assets/images/emoji/wrestlers_tone5.png
new file mode 100644
index 00000000000..36ab9bb3f42
--- /dev/null
+++ b/app/assets/images/emoji/wrestlers_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/writing_hand.png b/app/assets/images/emoji/writing_hand.png
new file mode 100644
index 00000000000..85639f8ac40
--- /dev/null
+++ b/app/assets/images/emoji/writing_hand.png
Binary files differ
diff --git a/app/assets/images/emoji/writing_hand_tone1.png b/app/assets/images/emoji/writing_hand_tone1.png
new file mode 100644
index 00000000000..7923d8ebb17
--- /dev/null
+++ b/app/assets/images/emoji/writing_hand_tone1.png
Binary files differ
diff --git a/app/assets/images/emoji/writing_hand_tone2.png b/app/assets/images/emoji/writing_hand_tone2.png
new file mode 100644
index 00000000000..bcb304e15d2
--- /dev/null
+++ b/app/assets/images/emoji/writing_hand_tone2.png
Binary files differ
diff --git a/app/assets/images/emoji/writing_hand_tone3.png b/app/assets/images/emoji/writing_hand_tone3.png
new file mode 100644
index 00000000000..fd885fd2d90
--- /dev/null
+++ b/app/assets/images/emoji/writing_hand_tone3.png
Binary files differ
diff --git a/app/assets/images/emoji/writing_hand_tone4.png b/app/assets/images/emoji/writing_hand_tone4.png
new file mode 100644
index 00000000000..d065b8c64ab
--- /dev/null
+++ b/app/assets/images/emoji/writing_hand_tone4.png
Binary files differ
diff --git a/app/assets/images/emoji/writing_hand_tone5.png b/app/assets/images/emoji/writing_hand_tone5.png
new file mode 100644
index 00000000000..a44b3dd757c
--- /dev/null
+++ b/app/assets/images/emoji/writing_hand_tone5.png
Binary files differ
diff --git a/app/assets/images/emoji/x.png b/app/assets/images/emoji/x.png
new file mode 100644
index 00000000000..9f9ed0f7ad2
--- /dev/null
+++ b/app/assets/images/emoji/x.png
Binary files differ
diff --git a/app/assets/images/emoji/yellow_heart.png b/app/assets/images/emoji/yellow_heart.png
new file mode 100644
index 00000000000..7901a9d0103
--- /dev/null
+++ b/app/assets/images/emoji/yellow_heart.png
Binary files differ
diff --git a/app/assets/images/emoji/yen.png b/app/assets/images/emoji/yen.png
new file mode 100644
index 00000000000..63ee4799d66
--- /dev/null
+++ b/app/assets/images/emoji/yen.png
Binary files differ
diff --git a/app/assets/images/emoji/yin_yang.png b/app/assets/images/emoji/yin_yang.png
new file mode 100644
index 00000000000..f2900f6338f
--- /dev/null
+++ b/app/assets/images/emoji/yin_yang.png
Binary files differ
diff --git a/app/assets/images/emoji/yum.png b/app/assets/images/emoji/yum.png
new file mode 100644
index 00000000000..2df15753ca1
--- /dev/null
+++ b/app/assets/images/emoji/yum.png
Binary files differ
diff --git a/app/assets/images/emoji/zap.png b/app/assets/images/emoji/zap.png
new file mode 100644
index 00000000000..47e68e48e49
--- /dev/null
+++ b/app/assets/images/emoji/zap.png
Binary files differ
diff --git a/app/assets/images/emoji/zero.png b/app/assets/images/emoji/zero.png
new file mode 100644
index 00000000000..13aca83e018
--- /dev/null
+++ b/app/assets/images/emoji/zero.png
Binary files differ
diff --git a/app/assets/images/emoji/zipper_mouth.png b/app/assets/images/emoji/zipper_mouth.png
new file mode 100644
index 00000000000..f8ced2502a7
--- /dev/null
+++ b/app/assets/images/emoji/zipper_mouth.png
Binary files differ
diff --git a/app/assets/images/emoji/zzz.png b/app/assets/images/emoji/zzz.png
new file mode 100644
index 00000000000..9bc72b4469f
--- /dev/null
+++ b/app/assets/images/emoji/zzz.png
Binary files differ
diff --git a/app/assets/images/emoji@2x.png b/app/assets/images/emoji@2x.png
index dc9cae1d44c..b0fa9e1139e 100644
--- a/app/assets/images/emoji@2x.png
+++ b/app/assets/images/emoji@2x.png
Binary files differ
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>
+ &middot;
+ <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>
- &middot;
- <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;
+ }
+ }
+}