diff options
Diffstat (limited to 'app')
2168 files changed, 4770 insertions, 2024 deletions
diff --git a/app/assets/images/emoji/100.png b/app/assets/images/emoji/100.png Binary files differdeleted file mode 100644 index 6903ff0304a..00000000000 --- a/app/assets/images/emoji/100.png +++ /dev/null diff --git a/app/assets/images/emoji/1234.png b/app/assets/images/emoji/1234.png Binary files differdeleted file mode 100644 index 248dc7e55b6..00000000000 --- a/app/assets/images/emoji/1234.png +++ /dev/null diff --git a/app/assets/images/emoji/1F627.png b/app/assets/images/emoji/1F627.png Binary files differdeleted file mode 100644 index f99026a3bc7..00000000000 --- a/app/assets/images/emoji/1F627.png +++ /dev/null diff --git a/app/assets/images/emoji/8ball.png b/app/assets/images/emoji/8ball.png Binary files differdeleted file mode 100644 index 38ca662eded..00000000000 --- a/app/assets/images/emoji/8ball.png +++ /dev/null diff --git a/app/assets/images/emoji/a.png b/app/assets/images/emoji/a.png Binary files differdeleted file mode 100644 index 8603ff05a17..00000000000 --- a/app/assets/images/emoji/a.png +++ /dev/null diff --git a/app/assets/images/emoji/ab.png b/app/assets/images/emoji/ab.png Binary files differdeleted file mode 100644 index d9f2d17dea0..00000000000 --- a/app/assets/images/emoji/ab.png +++ /dev/null diff --git a/app/assets/images/emoji/abc.png b/app/assets/images/emoji/abc.png Binary files differdeleted file mode 100644 index 7688de692a9..00000000000 --- a/app/assets/images/emoji/abc.png +++ /dev/null diff --git a/app/assets/images/emoji/abcd.png b/app/assets/images/emoji/abcd.png Binary files differdeleted file mode 100644 index 0996a870570..00000000000 --- a/app/assets/images/emoji/abcd.png +++ /dev/null diff --git a/app/assets/images/emoji/accept.png b/app/assets/images/emoji/accept.png Binary files differdeleted file mode 100644 index 8afd7ce99cf..00000000000 --- a/app/assets/images/emoji/accept.png +++ /dev/null diff --git a/app/assets/images/emoji/aerial_tramway.png b/app/assets/images/emoji/aerial_tramway.png Binary files differdeleted file mode 100644 index 3eb4b61bf1d..00000000000 --- a/app/assets/images/emoji/aerial_tramway.png +++ /dev/null diff --git a/app/assets/images/emoji/airplane.png b/app/assets/images/emoji/airplane.png Binary files differdeleted file mode 100644 index 268d2ac3c8e..00000000000 --- a/app/assets/images/emoji/airplane.png +++ /dev/null diff --git a/app/assets/images/emoji/airplane_arriving.png b/app/assets/images/emoji/airplane_arriving.png Binary files differdeleted file mode 100644 index d66841962f2..00000000000 --- a/app/assets/images/emoji/airplane_arriving.png +++ /dev/null diff --git a/app/assets/images/emoji/airplane_departure.png b/app/assets/images/emoji/airplane_departure.png Binary files differdeleted file mode 100644 index a5766f9f4ae..00000000000 --- a/app/assets/images/emoji/airplane_departure.png +++ /dev/null diff --git a/app/assets/images/emoji/airplane_small.png b/app/assets/images/emoji/airplane_small.png Binary files differdeleted file mode 100644 index b731b15e3a8..00000000000 --- a/app/assets/images/emoji/airplane_small.png +++ /dev/null diff --git a/app/assets/images/emoji/alarm_clock.png b/app/assets/images/emoji/alarm_clock.png Binary files differdeleted file mode 100644 index cdbc2fbb950..00000000000 --- a/app/assets/images/emoji/alarm_clock.png +++ /dev/null diff --git a/app/assets/images/emoji/alembic.png b/app/assets/images/emoji/alembic.png Binary files differdeleted file mode 100644 index 307a7324249..00000000000 --- a/app/assets/images/emoji/alembic.png +++ /dev/null diff --git a/app/assets/images/emoji/alien.png b/app/assets/images/emoji/alien.png Binary files differdeleted file mode 100644 index 3b90e97433b..00000000000 --- a/app/assets/images/emoji/alien.png +++ /dev/null diff --git a/app/assets/images/emoji/ambulance.png b/app/assets/images/emoji/ambulance.png Binary files differdeleted file mode 100644 index 6fb8076d766..00000000000 --- a/app/assets/images/emoji/ambulance.png +++ /dev/null diff --git a/app/assets/images/emoji/amphora.png b/app/assets/images/emoji/amphora.png Binary files differdeleted file mode 100644 index 96de5056059..00000000000 --- a/app/assets/images/emoji/amphora.png +++ /dev/null diff --git a/app/assets/images/emoji/anchor.png b/app/assets/images/emoji/anchor.png Binary files differdeleted file mode 100644 index b036f70a00b..00000000000 --- a/app/assets/images/emoji/anchor.png +++ /dev/null diff --git a/app/assets/images/emoji/angel.png b/app/assets/images/emoji/angel.png Binary files differdeleted file mode 100644 index 66ea97a3b99..00000000000 --- a/app/assets/images/emoji/angel.png +++ /dev/null diff --git a/app/assets/images/emoji/angel_tone1.png b/app/assets/images/emoji/angel_tone1.png Binary files differdeleted file mode 100644 index 391694dc07e..00000000000 --- a/app/assets/images/emoji/angel_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/angel_tone2.png b/app/assets/images/emoji/angel_tone2.png Binary files differdeleted file mode 100644 index 700cbe6ed2c..00000000000 --- a/app/assets/images/emoji/angel_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/angel_tone3.png b/app/assets/images/emoji/angel_tone3.png Binary files differdeleted file mode 100644 index be597437d25..00000000000 --- a/app/assets/images/emoji/angel_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/angel_tone4.png b/app/assets/images/emoji/angel_tone4.png Binary files differdeleted file mode 100644 index b06d3c853ef..00000000000 --- a/app/assets/images/emoji/angel_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/angel_tone5.png b/app/assets/images/emoji/angel_tone5.png Binary files differdeleted file mode 100644 index 17bd677e334..00000000000 --- a/app/assets/images/emoji/angel_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/anger.png b/app/assets/images/emoji/anger.png Binary files differdeleted file mode 100644 index d63c2e000e4..00000000000 --- a/app/assets/images/emoji/anger.png +++ /dev/null diff --git a/app/assets/images/emoji/anger_right.png b/app/assets/images/emoji/anger_right.png Binary files differdeleted file mode 100644 index f5c97c4d297..00000000000 --- a/app/assets/images/emoji/anger_right.png +++ /dev/null diff --git a/app/assets/images/emoji/angry.png b/app/assets/images/emoji/angry.png Binary files differdeleted file mode 100644 index cfc4a6ecde5..00000000000 --- a/app/assets/images/emoji/angry.png +++ /dev/null diff --git a/app/assets/images/emoji/ant.png b/app/assets/images/emoji/ant.png Binary files differdeleted file mode 100644 index 994127ed6b3..00000000000 --- a/app/assets/images/emoji/ant.png +++ /dev/null diff --git a/app/assets/images/emoji/apple.png b/app/assets/images/emoji/apple.png Binary files differdeleted file mode 100644 index da650c60f62..00000000000 --- a/app/assets/images/emoji/apple.png +++ /dev/null diff --git a/app/assets/images/emoji/aquarius.png b/app/assets/images/emoji/aquarius.png Binary files differdeleted file mode 100644 index 641a4f68889..00000000000 --- a/app/assets/images/emoji/aquarius.png +++ /dev/null diff --git a/app/assets/images/emoji/aries.png b/app/assets/images/emoji/aries.png Binary files differdeleted file mode 100644 index 21a189d0ede..00000000000 --- a/app/assets/images/emoji/aries.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_backward.png b/app/assets/images/emoji/arrow_backward.png Binary files differdeleted file mode 100644 index ee38e3b038e..00000000000 --- a/app/assets/images/emoji/arrow_backward.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_double_down.png b/app/assets/images/emoji/arrow_double_down.png Binary files differdeleted file mode 100644 index 90193bfcb40..00000000000 --- a/app/assets/images/emoji/arrow_double_down.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_double_up.png b/app/assets/images/emoji/arrow_double_up.png Binary files differdeleted file mode 100644 index 13543d5eef2..00000000000 --- a/app/assets/images/emoji/arrow_double_up.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_down.png b/app/assets/images/emoji/arrow_down.png Binary files differdeleted file mode 100644 index b8eefd0b19f..00000000000 --- a/app/assets/images/emoji/arrow_down.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_down_small.png b/app/assets/images/emoji/arrow_down_small.png Binary files differdeleted file mode 100644 index 5870b9a2241..00000000000 --- a/app/assets/images/emoji/arrow_down_small.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_forward.png b/app/assets/images/emoji/arrow_forward.png Binary files differdeleted file mode 100644 index 4e2b682857c..00000000000 --- a/app/assets/images/emoji/arrow_forward.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_heading_down.png b/app/assets/images/emoji/arrow_heading_down.png Binary files differdeleted file mode 100644 index 2d9d24bca80..00000000000 --- a/app/assets/images/emoji/arrow_heading_down.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_heading_up.png b/app/assets/images/emoji/arrow_heading_up.png Binary files differdeleted file mode 100644 index f29bfcfc0de..00000000000 --- a/app/assets/images/emoji/arrow_heading_up.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_left.png b/app/assets/images/emoji/arrow_left.png Binary files differdeleted file mode 100644 index 8c685e0a81b..00000000000 --- a/app/assets/images/emoji/arrow_left.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_lower_left.png b/app/assets/images/emoji/arrow_lower_left.png Binary files differdeleted file mode 100644 index 88b37716078..00000000000 --- a/app/assets/images/emoji/arrow_lower_left.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_lower_right.png b/app/assets/images/emoji/arrow_lower_right.png Binary files differdeleted file mode 100644 index 7e807da7392..00000000000 --- a/app/assets/images/emoji/arrow_lower_right.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_right.png b/app/assets/images/emoji/arrow_right.png Binary files differdeleted file mode 100644 index 4755670b5cc..00000000000 --- a/app/assets/images/emoji/arrow_right.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_right_hook.png b/app/assets/images/emoji/arrow_right_hook.png Binary files differdeleted file mode 100644 index e7258ad3268..00000000000 --- a/app/assets/images/emoji/arrow_right_hook.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_up.png b/app/assets/images/emoji/arrow_up.png Binary files differdeleted file mode 100644 index af8218a87f7..00000000000 --- a/app/assets/images/emoji/arrow_up.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_up_down.png b/app/assets/images/emoji/arrow_up_down.png Binary files differdeleted file mode 100644 index dfa32b97186..00000000000 --- a/app/assets/images/emoji/arrow_up_down.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_up_small.png b/app/assets/images/emoji/arrow_up_small.png Binary files differdeleted file mode 100644 index 20a13dcd5cd..00000000000 --- a/app/assets/images/emoji/arrow_up_small.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_upper_left.png b/app/assets/images/emoji/arrow_upper_left.png Binary files differdeleted file mode 100644 index f38718fbe34..00000000000 --- a/app/assets/images/emoji/arrow_upper_left.png +++ /dev/null diff --git a/app/assets/images/emoji/arrow_upper_right.png b/app/assets/images/emoji/arrow_upper_right.png Binary files differdeleted file mode 100644 index c43e12d0f64..00000000000 --- a/app/assets/images/emoji/arrow_upper_right.png +++ /dev/null diff --git a/app/assets/images/emoji/arrows_clockwise.png b/app/assets/images/emoji/arrows_clockwise.png Binary files differdeleted file mode 100644 index 26e49c38388..00000000000 --- a/app/assets/images/emoji/arrows_clockwise.png +++ /dev/null diff --git a/app/assets/images/emoji/arrows_counterclockwise.png b/app/assets/images/emoji/arrows_counterclockwise.png Binary files differdeleted file mode 100644 index 8d06d8e0912..00000000000 --- a/app/assets/images/emoji/arrows_counterclockwise.png +++ /dev/null diff --git a/app/assets/images/emoji/art.png b/app/assets/images/emoji/art.png Binary files differdeleted file mode 100644 index bd6afe9ff06..00000000000 --- a/app/assets/images/emoji/art.png +++ /dev/null diff --git a/app/assets/images/emoji/articulated_lorry.png b/app/assets/images/emoji/articulated_lorry.png Binary files differdeleted file mode 100644 index c8217317132..00000000000 --- a/app/assets/images/emoji/articulated_lorry.png +++ /dev/null diff --git a/app/assets/images/emoji/asterisk.png b/app/assets/images/emoji/asterisk.png Binary files differdeleted file mode 100644 index 2f8e5113803..00000000000 --- a/app/assets/images/emoji/asterisk.png +++ /dev/null diff --git a/app/assets/images/emoji/astonished.png b/app/assets/images/emoji/astonished.png Binary files differdeleted file mode 100644 index bd0ac55ec8e..00000000000 --- a/app/assets/images/emoji/astonished.png +++ /dev/null diff --git a/app/assets/images/emoji/athletic_shoe.png b/app/assets/images/emoji/athletic_shoe.png Binary files differdeleted file mode 100644 index 423fa07dd5d..00000000000 --- a/app/assets/images/emoji/athletic_shoe.png +++ /dev/null diff --git a/app/assets/images/emoji/atm.png b/app/assets/images/emoji/atm.png Binary files differdeleted file mode 100644 index 4d935307b94..00000000000 --- a/app/assets/images/emoji/atm.png +++ /dev/null diff --git a/app/assets/images/emoji/atom.png b/app/assets/images/emoji/atom.png Binary files differdeleted file mode 100644 index 5f4567aa093..00000000000 --- a/app/assets/images/emoji/atom.png +++ /dev/null diff --git a/app/assets/images/emoji/avocado.png b/app/assets/images/emoji/avocado.png Binary files differdeleted file mode 100644 index 06f0d124aed..00000000000 --- a/app/assets/images/emoji/avocado.png +++ /dev/null diff --git a/app/assets/images/emoji/b.png b/app/assets/images/emoji/b.png Binary files differdeleted file mode 100644 index 25875bc6a14..00000000000 --- a/app/assets/images/emoji/b.png +++ /dev/null diff --git a/app/assets/images/emoji/baby.png b/app/assets/images/emoji/baby.png Binary files differdeleted file mode 100644 index a4af92c63c7..00000000000 --- a/app/assets/images/emoji/baby.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_bottle.png b/app/assets/images/emoji/baby_bottle.png Binary files differdeleted file mode 100644 index 2bd10524180..00000000000 --- a/app/assets/images/emoji/baby_bottle.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_chick.png b/app/assets/images/emoji/baby_chick.png Binary files differdeleted file mode 100644 index dccd96576ea..00000000000 --- a/app/assets/images/emoji/baby_chick.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_symbol.png b/app/assets/images/emoji/baby_symbol.png Binary files differdeleted file mode 100644 index 64a10b71710..00000000000 --- a/app/assets/images/emoji/baby_symbol.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_tone1.png b/app/assets/images/emoji/baby_tone1.png Binary files differdeleted file mode 100644 index d20911d40db..00000000000 --- a/app/assets/images/emoji/baby_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_tone2.png b/app/assets/images/emoji/baby_tone2.png Binary files differdeleted file mode 100644 index b0a9b30ed17..00000000000 --- a/app/assets/images/emoji/baby_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_tone3.png b/app/assets/images/emoji/baby_tone3.png Binary files differdeleted file mode 100644 index 7de5286fac1..00000000000 --- a/app/assets/images/emoji/baby_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_tone4.png b/app/assets/images/emoji/baby_tone4.png Binary files differdeleted file mode 100644 index 9b7a86ac615..00000000000 --- a/app/assets/images/emoji/baby_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/baby_tone5.png b/app/assets/images/emoji/baby_tone5.png Binary files differdeleted file mode 100644 index fe1be34cb88..00000000000 --- a/app/assets/images/emoji/baby_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/back.png b/app/assets/images/emoji/back.png Binary files differdeleted file mode 100644 index d32c5d4f17f..00000000000 --- a/app/assets/images/emoji/back.png +++ /dev/null diff --git a/app/assets/images/emoji/bacon.png b/app/assets/images/emoji/bacon.png Binary files differdeleted file mode 100644 index f38a485fbe4..00000000000 --- a/app/assets/images/emoji/bacon.png +++ /dev/null diff --git a/app/assets/images/emoji/badminton.png b/app/assets/images/emoji/badminton.png Binary files differdeleted file mode 100644 index 7ba15708990..00000000000 --- a/app/assets/images/emoji/badminton.png +++ /dev/null diff --git a/app/assets/images/emoji/baggage_claim.png b/app/assets/images/emoji/baggage_claim.png Binary files differdeleted file mode 100644 index 409b593e78a..00000000000 --- a/app/assets/images/emoji/baggage_claim.png +++ /dev/null diff --git a/app/assets/images/emoji/balloon.png b/app/assets/images/emoji/balloon.png Binary files differdeleted file mode 100644 index 07916fe6df1..00000000000 --- a/app/assets/images/emoji/balloon.png +++ /dev/null diff --git a/app/assets/images/emoji/ballot_box.png b/app/assets/images/emoji/ballot_box.png Binary files differdeleted file mode 100644 index 9b6767aea9e..00000000000 --- a/app/assets/images/emoji/ballot_box.png +++ /dev/null diff --git a/app/assets/images/emoji/ballot_box_with_check.png b/app/assets/images/emoji/ballot_box_with_check.png Binary files differdeleted file mode 100644 index 284d9573847..00000000000 --- a/app/assets/images/emoji/ballot_box_with_check.png +++ /dev/null diff --git a/app/assets/images/emoji/bamboo.png b/app/assets/images/emoji/bamboo.png Binary files differdeleted file mode 100644 index 5d5e0e728a0..00000000000 --- a/app/assets/images/emoji/bamboo.png +++ /dev/null diff --git a/app/assets/images/emoji/banana.png b/app/assets/images/emoji/banana.png Binary files differdeleted file mode 100644 index f4987279580..00000000000 --- a/app/assets/images/emoji/banana.png +++ /dev/null diff --git a/app/assets/images/emoji/bangbang.png b/app/assets/images/emoji/bangbang.png Binary files differdeleted file mode 100644 index 58a9c528fca..00000000000 --- a/app/assets/images/emoji/bangbang.png +++ /dev/null diff --git a/app/assets/images/emoji/bank.png b/app/assets/images/emoji/bank.png Binary files differdeleted file mode 100644 index dffdcef36a1..00000000000 --- a/app/assets/images/emoji/bank.png +++ /dev/null diff --git a/app/assets/images/emoji/bar_chart.png b/app/assets/images/emoji/bar_chart.png Binary files differdeleted file mode 100644 index 53c89455008..00000000000 --- a/app/assets/images/emoji/bar_chart.png +++ /dev/null diff --git a/app/assets/images/emoji/barber.png b/app/assets/images/emoji/barber.png Binary files differdeleted file mode 100644 index 896f4d716cf..00000000000 --- a/app/assets/images/emoji/barber.png +++ /dev/null diff --git a/app/assets/images/emoji/baseball.png b/app/assets/images/emoji/baseball.png Binary files differdeleted file mode 100644 index f8463f1538b..00000000000 --- a/app/assets/images/emoji/baseball.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball.png b/app/assets/images/emoji/basketball.png Binary files differdeleted file mode 100644 index 64c76b79c6d..00000000000 --- a/app/assets/images/emoji/basketball.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball_player.png b/app/assets/images/emoji/basketball_player.png Binary files differdeleted file mode 100644 index 8ce90c5cad6..00000000000 --- a/app/assets/images/emoji/basketball_player.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball_player_tone1.png b/app/assets/images/emoji/basketball_player_tone1.png Binary files differdeleted file mode 100644 index cd12c7ab9bf..00000000000 --- a/app/assets/images/emoji/basketball_player_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball_player_tone2.png b/app/assets/images/emoji/basketball_player_tone2.png Binary files differdeleted file mode 100644 index f892fd596da..00000000000 --- a/app/assets/images/emoji/basketball_player_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball_player_tone3.png b/app/assets/images/emoji/basketball_player_tone3.png Binary files differdeleted file mode 100644 index e109997a91a..00000000000 --- a/app/assets/images/emoji/basketball_player_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball_player_tone4.png b/app/assets/images/emoji/basketball_player_tone4.png Binary files differdeleted file mode 100644 index 3b90b946af4..00000000000 --- a/app/assets/images/emoji/basketball_player_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/basketball_player_tone5.png b/app/assets/images/emoji/basketball_player_tone5.png Binary files differdeleted file mode 100644 index bafed7828a7..00000000000 --- a/app/assets/images/emoji/basketball_player_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/bat.png b/app/assets/images/emoji/bat.png Binary files differdeleted file mode 100644 index 3152c047e00..00000000000 --- a/app/assets/images/emoji/bat.png +++ /dev/null diff --git a/app/assets/images/emoji/bath.png b/app/assets/images/emoji/bath.png Binary files differdeleted file mode 100644 index 43fba5c8a28..00000000000 --- a/app/assets/images/emoji/bath.png +++ /dev/null diff --git a/app/assets/images/emoji/bath_tone1.png b/app/assets/images/emoji/bath_tone1.png Binary files differdeleted file mode 100644 index 2152eabf2f5..00000000000 --- a/app/assets/images/emoji/bath_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/bath_tone2.png b/app/assets/images/emoji/bath_tone2.png Binary files differdeleted file mode 100644 index 2102e6133e3..00000000000 --- a/app/assets/images/emoji/bath_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/bath_tone3.png b/app/assets/images/emoji/bath_tone3.png Binary files differdeleted file mode 100644 index fae66181e9f..00000000000 --- a/app/assets/images/emoji/bath_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/bath_tone4.png b/app/assets/images/emoji/bath_tone4.png Binary files differdeleted file mode 100644 index 1f8959d0d99..00000000000 --- a/app/assets/images/emoji/bath_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/bath_tone5.png b/app/assets/images/emoji/bath_tone5.png Binary files differdeleted file mode 100644 index c8a08e84f25..00000000000 --- a/app/assets/images/emoji/bath_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/bathtub.png b/app/assets/images/emoji/bathtub.png Binary files differdeleted file mode 100644 index 9a5f09361eb..00000000000 --- a/app/assets/images/emoji/bathtub.png +++ /dev/null diff --git a/app/assets/images/emoji/battery.png b/app/assets/images/emoji/battery.png Binary files differdeleted file mode 100644 index f593e2bdb65..00000000000 --- a/app/assets/images/emoji/battery.png +++ /dev/null diff --git a/app/assets/images/emoji/beach.png b/app/assets/images/emoji/beach.png Binary files differdeleted file mode 100644 index 69108c8ea10..00000000000 --- a/app/assets/images/emoji/beach.png +++ /dev/null diff --git a/app/assets/images/emoji/beach_umbrella.png b/app/assets/images/emoji/beach_umbrella.png Binary files differdeleted file mode 100644 index 220a74f8132..00000000000 --- a/app/assets/images/emoji/beach_umbrella.png +++ /dev/null diff --git a/app/assets/images/emoji/bear.png b/app/assets/images/emoji/bear.png Binary files differdeleted file mode 100644 index 272d56bbbcc..00000000000 --- a/app/assets/images/emoji/bear.png +++ /dev/null diff --git a/app/assets/images/emoji/bed.png b/app/assets/images/emoji/bed.png Binary files differdeleted file mode 100644 index 86f964e245d..00000000000 --- a/app/assets/images/emoji/bed.png +++ /dev/null diff --git a/app/assets/images/emoji/bee.png b/app/assets/images/emoji/bee.png Binary files differdeleted file mode 100644 index 46156060096..00000000000 --- a/app/assets/images/emoji/bee.png +++ /dev/null diff --git a/app/assets/images/emoji/beer.png b/app/assets/images/emoji/beer.png Binary files differdeleted file mode 100644 index b6d73dc0b7a..00000000000 --- a/app/assets/images/emoji/beer.png +++ /dev/null diff --git a/app/assets/images/emoji/beers.png b/app/assets/images/emoji/beers.png Binary files differdeleted file mode 100644 index b55deb66b41..00000000000 --- a/app/assets/images/emoji/beers.png +++ /dev/null diff --git a/app/assets/images/emoji/beetle.png b/app/assets/images/emoji/beetle.png Binary files differdeleted file mode 100644 index 3d93174d7fc..00000000000 --- a/app/assets/images/emoji/beetle.png +++ /dev/null diff --git a/app/assets/images/emoji/beginner.png b/app/assets/images/emoji/beginner.png Binary files differdeleted file mode 100644 index bc434fb7cb5..00000000000 --- a/app/assets/images/emoji/beginner.png +++ /dev/null diff --git a/app/assets/images/emoji/bell.png b/app/assets/images/emoji/bell.png Binary files differdeleted file mode 100644 index 5b3b0461999..00000000000 --- a/app/assets/images/emoji/bell.png +++ /dev/null diff --git a/app/assets/images/emoji/bellhop.png b/app/assets/images/emoji/bellhop.png Binary files differdeleted file mode 100644 index 6b3297ceaf7..00000000000 --- a/app/assets/images/emoji/bellhop.png +++ /dev/null diff --git a/app/assets/images/emoji/bento.png b/app/assets/images/emoji/bento.png Binary files differdeleted file mode 100644 index 83d41ca7eb9..00000000000 --- a/app/assets/images/emoji/bento.png +++ /dev/null diff --git a/app/assets/images/emoji/bicyclist.png b/app/assets/images/emoji/bicyclist.png Binary files differdeleted file mode 100644 index 9274da11048..00000000000 --- a/app/assets/images/emoji/bicyclist.png +++ /dev/null diff --git a/app/assets/images/emoji/bicyclist_tone1.png b/app/assets/images/emoji/bicyclist_tone1.png Binary files differdeleted file mode 100644 index decc2f728fe..00000000000 --- a/app/assets/images/emoji/bicyclist_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/bicyclist_tone2.png b/app/assets/images/emoji/bicyclist_tone2.png Binary files differdeleted file mode 100644 index 0067717b80a..00000000000 --- a/app/assets/images/emoji/bicyclist_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/bicyclist_tone3.png b/app/assets/images/emoji/bicyclist_tone3.png Binary files differdeleted file mode 100644 index a4f7b5e2776..00000000000 --- a/app/assets/images/emoji/bicyclist_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/bicyclist_tone4.png b/app/assets/images/emoji/bicyclist_tone4.png Binary files differdeleted file mode 100644 index a3c8a797db4..00000000000 --- a/app/assets/images/emoji/bicyclist_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/bicyclist_tone5.png b/app/assets/images/emoji/bicyclist_tone5.png Binary files differdeleted file mode 100644 index 1606a874051..00000000000 --- a/app/assets/images/emoji/bicyclist_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/bike.png b/app/assets/images/emoji/bike.png Binary files differdeleted file mode 100644 index 556ed70f1a7..00000000000 --- a/app/assets/images/emoji/bike.png +++ /dev/null diff --git a/app/assets/images/emoji/bikini.png b/app/assets/images/emoji/bikini.png Binary files differdeleted file mode 100644 index 77a8a0aae5b..00000000000 --- a/app/assets/images/emoji/bikini.png +++ /dev/null diff --git a/app/assets/images/emoji/biohazard.png b/app/assets/images/emoji/biohazard.png Binary files differdeleted file mode 100644 index 007b4fc2d85..00000000000 --- a/app/assets/images/emoji/biohazard.png +++ /dev/null diff --git a/app/assets/images/emoji/bird.png b/app/assets/images/emoji/bird.png Binary files differdeleted file mode 100644 index e201c22be33..00000000000 --- a/app/assets/images/emoji/bird.png +++ /dev/null diff --git a/app/assets/images/emoji/birthday.png b/app/assets/images/emoji/birthday.png Binary files differdeleted file mode 100644 index 317e9a41949..00000000000 --- a/app/assets/images/emoji/birthday.png +++ /dev/null diff --git a/app/assets/images/emoji/black_circle.png b/app/assets/images/emoji/black_circle.png Binary files differdeleted file mode 100644 index b62b87170e8..00000000000 --- a/app/assets/images/emoji/black_circle.png +++ /dev/null diff --git a/app/assets/images/emoji/black_heart.png b/app/assets/images/emoji/black_heart.png Binary files differdeleted file mode 100644 index b4068c3e6e8..00000000000 --- a/app/assets/images/emoji/black_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/black_joker.png b/app/assets/images/emoji/black_joker.png Binary files differdeleted file mode 100644 index 3d0924b68aa..00000000000 --- a/app/assets/images/emoji/black_joker.png +++ /dev/null diff --git a/app/assets/images/emoji/black_large_square.png b/app/assets/images/emoji/black_large_square.png Binary files differdeleted file mode 100644 index 162f2bb4290..00000000000 --- a/app/assets/images/emoji/black_large_square.png +++ /dev/null diff --git a/app/assets/images/emoji/black_medium_small_square.png b/app/assets/images/emoji/black_medium_small_square.png Binary files differdeleted file mode 100644 index 39765bba610..00000000000 --- a/app/assets/images/emoji/black_medium_small_square.png +++ /dev/null diff --git a/app/assets/images/emoji/black_medium_square.png b/app/assets/images/emoji/black_medium_square.png Binary files differdeleted file mode 100644 index 05a30a6aa2d..00000000000 --- a/app/assets/images/emoji/black_medium_square.png +++ /dev/null diff --git a/app/assets/images/emoji/black_nib.png b/app/assets/images/emoji/black_nib.png Binary files differdeleted file mode 100644 index 872d0ae1598..00000000000 --- a/app/assets/images/emoji/black_nib.png +++ /dev/null diff --git a/app/assets/images/emoji/black_small_square.png b/app/assets/images/emoji/black_small_square.png Binary files differdeleted file mode 100644 index 48595d3e1a9..00000000000 --- a/app/assets/images/emoji/black_small_square.png +++ /dev/null diff --git a/app/assets/images/emoji/black_square_button.png b/app/assets/images/emoji/black_square_button.png Binary files differdeleted file mode 100644 index a78fc2f6b63..00000000000 --- a/app/assets/images/emoji/black_square_button.png +++ /dev/null diff --git a/app/assets/images/emoji/blossom.png b/app/assets/images/emoji/blossom.png Binary files differdeleted file mode 100644 index 4083026c157..00000000000 --- a/app/assets/images/emoji/blossom.png +++ /dev/null diff --git a/app/assets/images/emoji/blowfish.png b/app/assets/images/emoji/blowfish.png Binary files differdeleted file mode 100644 index a10f4f84e35..00000000000 --- a/app/assets/images/emoji/blowfish.png +++ /dev/null diff --git a/app/assets/images/emoji/blue_book.png b/app/assets/images/emoji/blue_book.png Binary files differdeleted file mode 100644 index e1e455401cc..00000000000 --- a/app/assets/images/emoji/blue_book.png +++ /dev/null diff --git a/app/assets/images/emoji/blue_car.png b/app/assets/images/emoji/blue_car.png Binary files differdeleted file mode 100644 index e8ba817d393..00000000000 --- a/app/assets/images/emoji/blue_car.png +++ /dev/null diff --git a/app/assets/images/emoji/blue_heart.png b/app/assets/images/emoji/blue_heart.png Binary files differdeleted file mode 100644 index bdf1287e55e..00000000000 --- a/app/assets/images/emoji/blue_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/blush.png b/app/assets/images/emoji/blush.png Binary files differdeleted file mode 100644 index aac1a424ad4..00000000000 --- a/app/assets/images/emoji/blush.png +++ /dev/null diff --git a/app/assets/images/emoji/boar.png b/app/assets/images/emoji/boar.png Binary files differdeleted file mode 100644 index fead972633c..00000000000 --- a/app/assets/images/emoji/boar.png +++ /dev/null diff --git a/app/assets/images/emoji/bomb.png b/app/assets/images/emoji/bomb.png Binary files differdeleted file mode 100644 index c7f8f81c939..00000000000 --- a/app/assets/images/emoji/bomb.png +++ /dev/null diff --git a/app/assets/images/emoji/book.png b/app/assets/images/emoji/book.png Binary files differdeleted file mode 100644 index 0f4447ed396..00000000000 --- a/app/assets/images/emoji/book.png +++ /dev/null diff --git a/app/assets/images/emoji/bookmark.png b/app/assets/images/emoji/bookmark.png Binary files differdeleted file mode 100644 index bbb444611f0..00000000000 --- a/app/assets/images/emoji/bookmark.png +++ /dev/null diff --git a/app/assets/images/emoji/bookmark_tabs.png b/app/assets/images/emoji/bookmark_tabs.png Binary files differdeleted file mode 100644 index f8d9e01b428..00000000000 --- a/app/assets/images/emoji/bookmark_tabs.png +++ /dev/null diff --git a/app/assets/images/emoji/books.png b/app/assets/images/emoji/books.png Binary files differdeleted file mode 100644 index 59a8bafeb0d..00000000000 --- a/app/assets/images/emoji/books.png +++ /dev/null diff --git a/app/assets/images/emoji/boom.png b/app/assets/images/emoji/boom.png Binary files differdeleted file mode 100644 index 9b0f027b1a8..00000000000 --- a/app/assets/images/emoji/boom.png +++ /dev/null diff --git a/app/assets/images/emoji/boot.png b/app/assets/images/emoji/boot.png Binary files differdeleted file mode 100644 index 11f1065ed07..00000000000 --- a/app/assets/images/emoji/boot.png +++ /dev/null diff --git a/app/assets/images/emoji/bouquet.png b/app/assets/images/emoji/bouquet.png Binary files differdeleted file mode 100644 index 11455af6df4..00000000000 --- a/app/assets/images/emoji/bouquet.png +++ /dev/null diff --git a/app/assets/images/emoji/bow.png b/app/assets/images/emoji/bow.png Binary files differdeleted file mode 100644 index d8f793088dc..00000000000 --- a/app/assets/images/emoji/bow.png +++ /dev/null diff --git a/app/assets/images/emoji/bow_and_arrow.png b/app/assets/images/emoji/bow_and_arrow.png Binary files differdeleted file mode 100644 index 6a538bf475f..00000000000 --- a/app/assets/images/emoji/bow_and_arrow.png +++ /dev/null diff --git a/app/assets/images/emoji/bow_tone1.png b/app/assets/images/emoji/bow_tone1.png Binary files differdeleted file mode 100644 index 87afb7b54cf..00000000000 --- a/app/assets/images/emoji/bow_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/bow_tone2.png b/app/assets/images/emoji/bow_tone2.png Binary files differdeleted file mode 100644 index 3ccf7dc0850..00000000000 --- a/app/assets/images/emoji/bow_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/bow_tone3.png b/app/assets/images/emoji/bow_tone3.png Binary files differdeleted file mode 100644 index 8b9eb64f926..00000000000 --- a/app/assets/images/emoji/bow_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/bow_tone4.png b/app/assets/images/emoji/bow_tone4.png Binary files differdeleted file mode 100644 index 683795ff40d..00000000000 --- a/app/assets/images/emoji/bow_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/bow_tone5.png b/app/assets/images/emoji/bow_tone5.png Binary files differdeleted file mode 100644 index 7969d971752..00000000000 --- a/app/assets/images/emoji/bow_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/bowling.png b/app/assets/images/emoji/bowling.png Binary files differdeleted file mode 100644 index 63add89e53b..00000000000 --- a/app/assets/images/emoji/bowling.png +++ /dev/null diff --git a/app/assets/images/emoji/boxing_glove.png b/app/assets/images/emoji/boxing_glove.png Binary files differdeleted file mode 100644 index 9838f24e51a..00000000000 --- a/app/assets/images/emoji/boxing_glove.png +++ /dev/null diff --git a/app/assets/images/emoji/boy.png b/app/assets/images/emoji/boy.png Binary files differdeleted file mode 100644 index 8ecfb0a4e92..00000000000 --- a/app/assets/images/emoji/boy.png +++ /dev/null diff --git a/app/assets/images/emoji/boy_tone1.png b/app/assets/images/emoji/boy_tone1.png Binary files differdeleted file mode 100644 index 2fc436ea512..00000000000 --- a/app/assets/images/emoji/boy_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/boy_tone2.png b/app/assets/images/emoji/boy_tone2.png Binary files differdeleted file mode 100644 index 09a5f18d360..00000000000 --- a/app/assets/images/emoji/boy_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/boy_tone3.png b/app/assets/images/emoji/boy_tone3.png Binary files differdeleted file mode 100644 index 3cfe675dd3a..00000000000 --- a/app/assets/images/emoji/boy_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/boy_tone4.png b/app/assets/images/emoji/boy_tone4.png Binary files differdeleted file mode 100644 index 780be0ace36..00000000000 --- a/app/assets/images/emoji/boy_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/boy_tone5.png b/app/assets/images/emoji/boy_tone5.png Binary files differdeleted file mode 100644 index f32fe22e35c..00000000000 --- a/app/assets/images/emoji/boy_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/bread.png b/app/assets/images/emoji/bread.png Binary files differdeleted file mode 100644 index 6676510aaa5..00000000000 --- a/app/assets/images/emoji/bread.png +++ /dev/null diff --git a/app/assets/images/emoji/bride_with_veil.png b/app/assets/images/emoji/bride_with_veil.png Binary files differdeleted file mode 100644 index eaf4bd97890..00000000000 --- a/app/assets/images/emoji/bride_with_veil.png +++ /dev/null diff --git a/app/assets/images/emoji/bride_with_veil_tone1.png b/app/assets/images/emoji/bride_with_veil_tone1.png Binary files differdeleted file mode 100644 index c4fb141ae8f..00000000000 --- a/app/assets/images/emoji/bride_with_veil_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/bride_with_veil_tone2.png b/app/assets/images/emoji/bride_with_veil_tone2.png Binary files differdeleted file mode 100644 index c248769fc06..00000000000 --- a/app/assets/images/emoji/bride_with_veil_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/bride_with_veil_tone3.png b/app/assets/images/emoji/bride_with_veil_tone3.png Binary files differdeleted file mode 100644 index 962c0a6eedb..00000000000 --- a/app/assets/images/emoji/bride_with_veil_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/bride_with_veil_tone4.png b/app/assets/images/emoji/bride_with_veil_tone4.png Binary files differdeleted file mode 100644 index 740ca208cd4..00000000000 --- a/app/assets/images/emoji/bride_with_veil_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/bride_with_veil_tone5.png b/app/assets/images/emoji/bride_with_veil_tone5.png Binary files differdeleted file mode 100644 index 5cc5598587d..00000000000 --- a/app/assets/images/emoji/bride_with_veil_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/bridge_at_night.png b/app/assets/images/emoji/bridge_at_night.png Binary files differdeleted file mode 100644 index 1d444e0be65..00000000000 --- a/app/assets/images/emoji/bridge_at_night.png +++ /dev/null diff --git a/app/assets/images/emoji/briefcase.png b/app/assets/images/emoji/briefcase.png Binary files differdeleted file mode 100644 index b9912ba2148..00000000000 --- a/app/assets/images/emoji/briefcase.png +++ /dev/null diff --git a/app/assets/images/emoji/broken_heart.png b/app/assets/images/emoji/broken_heart.png Binary files differdeleted file mode 100644 index 718e26ee122..00000000000 --- a/app/assets/images/emoji/broken_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/bug.png b/app/assets/images/emoji/bug.png Binary files differdeleted file mode 100644 index e64e72f259a..00000000000 --- a/app/assets/images/emoji/bug.png +++ /dev/null diff --git a/app/assets/images/emoji/bulb.png b/app/assets/images/emoji/bulb.png Binary files differdeleted file mode 100644 index 38e32e02d9f..00000000000 --- a/app/assets/images/emoji/bulb.png +++ /dev/null diff --git a/app/assets/images/emoji/bullettrain_front.png b/app/assets/images/emoji/bullettrain_front.png Binary files differdeleted file mode 100644 index 4f698e056fa..00000000000 --- a/app/assets/images/emoji/bullettrain_front.png +++ /dev/null diff --git a/app/assets/images/emoji/bullettrain_side.png b/app/assets/images/emoji/bullettrain_side.png Binary files differdeleted file mode 100644 index ed61c67bf07..00000000000 --- a/app/assets/images/emoji/bullettrain_side.png +++ /dev/null diff --git a/app/assets/images/emoji/burrito.png b/app/assets/images/emoji/burrito.png Binary files differdeleted file mode 100644 index 02bd5601df7..00000000000 --- a/app/assets/images/emoji/burrito.png +++ /dev/null diff --git a/app/assets/images/emoji/bus.png b/app/assets/images/emoji/bus.png Binary files differdeleted file mode 100644 index 641ddc56ca7..00000000000 --- a/app/assets/images/emoji/bus.png +++ /dev/null diff --git a/app/assets/images/emoji/busstop.png b/app/assets/images/emoji/busstop.png Binary files differdeleted file mode 100644 index b2b62208bfd..00000000000 --- a/app/assets/images/emoji/busstop.png +++ /dev/null diff --git a/app/assets/images/emoji/bust_in_silhouette.png b/app/assets/images/emoji/bust_in_silhouette.png Binary files differdeleted file mode 100644 index 123b2cbe1fb..00000000000 --- a/app/assets/images/emoji/bust_in_silhouette.png +++ /dev/null diff --git a/app/assets/images/emoji/busts_in_silhouette.png b/app/assets/images/emoji/busts_in_silhouette.png Binary files differdeleted file mode 100644 index d7656860a1c..00000000000 --- a/app/assets/images/emoji/busts_in_silhouette.png +++ /dev/null diff --git a/app/assets/images/emoji/butterfly.png b/app/assets/images/emoji/butterfly.png Binary files differdeleted file mode 100644 index 5631fe99226..00000000000 --- a/app/assets/images/emoji/butterfly.png +++ /dev/null diff --git a/app/assets/images/emoji/cactus.png b/app/assets/images/emoji/cactus.png Binary files differdeleted file mode 100644 index 9b48ccf3d0c..00000000000 --- a/app/assets/images/emoji/cactus.png +++ /dev/null diff --git a/app/assets/images/emoji/cake.png b/app/assets/images/emoji/cake.png Binary files differdeleted file mode 100644 index 4368177be9a..00000000000 --- a/app/assets/images/emoji/cake.png +++ /dev/null diff --git a/app/assets/images/emoji/calendar.png b/app/assets/images/emoji/calendar.png Binary files differdeleted file mode 100644 index 47353b74447..00000000000 --- a/app/assets/images/emoji/calendar.png +++ /dev/null diff --git a/app/assets/images/emoji/calendar_spiral.png b/app/assets/images/emoji/calendar_spiral.png Binary files differdeleted file mode 100644 index dec8d49bfa8..00000000000 --- a/app/assets/images/emoji/calendar_spiral.png +++ /dev/null diff --git a/app/assets/images/emoji/call_me.png b/app/assets/images/emoji/call_me.png Binary files differdeleted file mode 100644 index a10c59ba711..00000000000 --- a/app/assets/images/emoji/call_me.png +++ /dev/null diff --git a/app/assets/images/emoji/call_me_tone1.png b/app/assets/images/emoji/call_me_tone1.png Binary files differdeleted file mode 100644 index 2c93201181a..00000000000 --- a/app/assets/images/emoji/call_me_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/call_me_tone2.png b/app/assets/images/emoji/call_me_tone2.png Binary files differdeleted file mode 100644 index c39f45a41ed..00000000000 --- a/app/assets/images/emoji/call_me_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/call_me_tone3.png b/app/assets/images/emoji/call_me_tone3.png Binary files differdeleted file mode 100644 index 83a57f63c29..00000000000 --- a/app/assets/images/emoji/call_me_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/call_me_tone4.png b/app/assets/images/emoji/call_me_tone4.png Binary files differdeleted file mode 100644 index 65b3468fe44..00000000000 --- a/app/assets/images/emoji/call_me_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/call_me_tone5.png b/app/assets/images/emoji/call_me_tone5.png Binary files differdeleted file mode 100644 index 94ef68ff3b3..00000000000 --- a/app/assets/images/emoji/call_me_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/calling.png b/app/assets/images/emoji/calling.png Binary files differdeleted file mode 100644 index e2f308f8e46..00000000000 --- a/app/assets/images/emoji/calling.png +++ /dev/null diff --git a/app/assets/images/emoji/camel.png b/app/assets/images/emoji/camel.png Binary files differdeleted file mode 100644 index b421d07a805..00000000000 --- a/app/assets/images/emoji/camel.png +++ /dev/null diff --git a/app/assets/images/emoji/camera.png b/app/assets/images/emoji/camera.png Binary files differdeleted file mode 100644 index 0a3429f72ef..00000000000 --- a/app/assets/images/emoji/camera.png +++ /dev/null diff --git a/app/assets/images/emoji/camera_with_flash.png b/app/assets/images/emoji/camera_with_flash.png Binary files differdeleted file mode 100644 index 27471da2029..00000000000 --- a/app/assets/images/emoji/camera_with_flash.png +++ /dev/null diff --git a/app/assets/images/emoji/camping.png b/app/assets/images/emoji/camping.png Binary files differdeleted file mode 100644 index d589cc1f44b..00000000000 --- a/app/assets/images/emoji/camping.png +++ /dev/null diff --git a/app/assets/images/emoji/cancer.png b/app/assets/images/emoji/cancer.png Binary files differdeleted file mode 100644 index a64af07cb5f..00000000000 --- a/app/assets/images/emoji/cancer.png +++ /dev/null diff --git a/app/assets/images/emoji/candle.png b/app/assets/images/emoji/candle.png Binary files differdeleted file mode 100644 index 0b56444e355..00000000000 --- a/app/assets/images/emoji/candle.png +++ /dev/null diff --git a/app/assets/images/emoji/candy.png b/app/assets/images/emoji/candy.png Binary files differdeleted file mode 100644 index 8c67ace3a35..00000000000 --- a/app/assets/images/emoji/candy.png +++ /dev/null diff --git a/app/assets/images/emoji/canoe.png b/app/assets/images/emoji/canoe.png Binary files differdeleted file mode 100644 index e26cdb9da69..00000000000 --- a/app/assets/images/emoji/canoe.png +++ /dev/null diff --git a/app/assets/images/emoji/capital_abcd.png b/app/assets/images/emoji/capital_abcd.png Binary files differdeleted file mode 100644 index fe9482d2d8a..00000000000 --- a/app/assets/images/emoji/capital_abcd.png +++ /dev/null diff --git a/app/assets/images/emoji/capricorn.png b/app/assets/images/emoji/capricorn.png Binary files differdeleted file mode 100644 index 6293d31d4b1..00000000000 --- a/app/assets/images/emoji/capricorn.png +++ /dev/null diff --git a/app/assets/images/emoji/card_box.png b/app/assets/images/emoji/card_box.png Binary files differdeleted file mode 100644 index f2e764ce59d..00000000000 --- a/app/assets/images/emoji/card_box.png +++ /dev/null diff --git a/app/assets/images/emoji/card_index.png b/app/assets/images/emoji/card_index.png Binary files differdeleted file mode 100644 index 151e11cb3b4..00000000000 --- a/app/assets/images/emoji/card_index.png +++ /dev/null diff --git a/app/assets/images/emoji/carousel_horse.png b/app/assets/images/emoji/carousel_horse.png Binary files differdeleted file mode 100644 index a17074edf05..00000000000 --- a/app/assets/images/emoji/carousel_horse.png +++ /dev/null diff --git a/app/assets/images/emoji/carrot.png b/app/assets/images/emoji/carrot.png Binary files differdeleted file mode 100644 index c68829b58e7..00000000000 --- a/app/assets/images/emoji/carrot.png +++ /dev/null diff --git a/app/assets/images/emoji/cartwheel.png b/app/assets/images/emoji/cartwheel.png Binary files differdeleted file mode 100644 index cbcaa578253..00000000000 --- a/app/assets/images/emoji/cartwheel.png +++ /dev/null diff --git a/app/assets/images/emoji/cartwheel_tone1.png b/app/assets/images/emoji/cartwheel_tone1.png Binary files differdeleted file mode 100644 index db6d65895fb..00000000000 --- a/app/assets/images/emoji/cartwheel_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/cartwheel_tone2.png b/app/assets/images/emoji/cartwheel_tone2.png Binary files differdeleted file mode 100644 index e00ffbc27a8..00000000000 --- a/app/assets/images/emoji/cartwheel_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/cartwheel_tone3.png b/app/assets/images/emoji/cartwheel_tone3.png Binary files differdeleted file mode 100644 index 49321be391f..00000000000 --- a/app/assets/images/emoji/cartwheel_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/cartwheel_tone4.png b/app/assets/images/emoji/cartwheel_tone4.png Binary files differdeleted file mode 100644 index d4562b5e3dd..00000000000 --- a/app/assets/images/emoji/cartwheel_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/cartwheel_tone5.png b/app/assets/images/emoji/cartwheel_tone5.png Binary files differdeleted file mode 100644 index 6e09a870767..00000000000 --- a/app/assets/images/emoji/cartwheel_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/cat.png b/app/assets/images/emoji/cat.png Binary files differdeleted file mode 100644 index efd82c2abf3..00000000000 --- a/app/assets/images/emoji/cat.png +++ /dev/null diff --git a/app/assets/images/emoji/cat2.png b/app/assets/images/emoji/cat2.png Binary files differdeleted file mode 100644 index 46abe8cbc14..00000000000 --- a/app/assets/images/emoji/cat2.png +++ /dev/null diff --git a/app/assets/images/emoji/cd.png b/app/assets/images/emoji/cd.png Binary files differdeleted file mode 100644 index e6b01449cd9..00000000000 --- a/app/assets/images/emoji/cd.png +++ /dev/null diff --git a/app/assets/images/emoji/chains.png b/app/assets/images/emoji/chains.png Binary files differdeleted file mode 100644 index 57f46139a06..00000000000 --- a/app/assets/images/emoji/chains.png +++ /dev/null diff --git a/app/assets/images/emoji/champagne.png b/app/assets/images/emoji/champagne.png Binary files differdeleted file mode 100644 index 285a79a93d0..00000000000 --- a/app/assets/images/emoji/champagne.png +++ /dev/null diff --git a/app/assets/images/emoji/champagne_glass.png b/app/assets/images/emoji/champagne_glass.png Binary files differdeleted file mode 100644 index 31937ae9392..00000000000 --- a/app/assets/images/emoji/champagne_glass.png +++ /dev/null diff --git a/app/assets/images/emoji/chart.png b/app/assets/images/emoji/chart.png Binary files differdeleted file mode 100644 index 9773f03be22..00000000000 --- a/app/assets/images/emoji/chart.png +++ /dev/null diff --git a/app/assets/images/emoji/chart_with_downwards_trend.png b/app/assets/images/emoji/chart_with_downwards_trend.png Binary files differdeleted file mode 100644 index 5222ec72d85..00000000000 --- a/app/assets/images/emoji/chart_with_downwards_trend.png +++ /dev/null diff --git a/app/assets/images/emoji/chart_with_upwards_trend.png b/app/assets/images/emoji/chart_with_upwards_trend.png Binary files differdeleted file mode 100644 index f13cfcf9956..00000000000 --- a/app/assets/images/emoji/chart_with_upwards_trend.png +++ /dev/null diff --git a/app/assets/images/emoji/checkered_flag.png b/app/assets/images/emoji/checkered_flag.png Binary files differdeleted file mode 100644 index 5a71eecb89b..00000000000 --- a/app/assets/images/emoji/checkered_flag.png +++ /dev/null diff --git a/app/assets/images/emoji/cheese.png b/app/assets/images/emoji/cheese.png Binary files differdeleted file mode 100644 index 00e99762286..00000000000 --- a/app/assets/images/emoji/cheese.png +++ /dev/null diff --git a/app/assets/images/emoji/cherries.png b/app/assets/images/emoji/cherries.png Binary files differdeleted file mode 100644 index 9b10cbaac5e..00000000000 --- a/app/assets/images/emoji/cherries.png +++ /dev/null diff --git a/app/assets/images/emoji/cherry_blossom.png b/app/assets/images/emoji/cherry_blossom.png Binary files differdeleted file mode 100644 index 282f3e7bc81..00000000000 --- a/app/assets/images/emoji/cherry_blossom.png +++ /dev/null diff --git a/app/assets/images/emoji/chestnut.png b/app/assets/images/emoji/chestnut.png Binary files differdeleted file mode 100644 index e9fb40468ed..00000000000 --- a/app/assets/images/emoji/chestnut.png +++ /dev/null diff --git a/app/assets/images/emoji/chicken.png b/app/assets/images/emoji/chicken.png Binary files differdeleted file mode 100644 index 9a6992e55ba..00000000000 --- a/app/assets/images/emoji/chicken.png +++ /dev/null diff --git a/app/assets/images/emoji/children_crossing.png b/app/assets/images/emoji/children_crossing.png Binary files differdeleted file mode 100644 index fa4c091c7c3..00000000000 --- a/app/assets/images/emoji/children_crossing.png +++ /dev/null diff --git a/app/assets/images/emoji/chipmunk.png b/app/assets/images/emoji/chipmunk.png Binary files differdeleted file mode 100644 index 2aac560cb22..00000000000 --- a/app/assets/images/emoji/chipmunk.png +++ /dev/null diff --git a/app/assets/images/emoji/chocolate_bar.png b/app/assets/images/emoji/chocolate_bar.png Binary files differdeleted file mode 100644 index 318bbd40ef9..00000000000 --- a/app/assets/images/emoji/chocolate_bar.png +++ /dev/null diff --git a/app/assets/images/emoji/christmas_tree.png b/app/assets/images/emoji/christmas_tree.png Binary files differdeleted file mode 100644 index 4197d37a52b..00000000000 --- a/app/assets/images/emoji/christmas_tree.png +++ /dev/null diff --git a/app/assets/images/emoji/church.png b/app/assets/images/emoji/church.png Binary files differdeleted file mode 100644 index 8242fd272b3..00000000000 --- a/app/assets/images/emoji/church.png +++ /dev/null diff --git a/app/assets/images/emoji/cinema.png b/app/assets/images/emoji/cinema.png Binary files differdeleted file mode 100644 index 65f27b386f2..00000000000 --- a/app/assets/images/emoji/cinema.png +++ /dev/null diff --git a/app/assets/images/emoji/circus_tent.png b/app/assets/images/emoji/circus_tent.png Binary files differdeleted file mode 100644 index b0379775b12..00000000000 --- a/app/assets/images/emoji/circus_tent.png +++ /dev/null diff --git a/app/assets/images/emoji/city_dusk.png b/app/assets/images/emoji/city_dusk.png Binary files differdeleted file mode 100644 index 80cdff7cf5d..00000000000 --- a/app/assets/images/emoji/city_dusk.png +++ /dev/null diff --git a/app/assets/images/emoji/city_sunset.png b/app/assets/images/emoji/city_sunset.png Binary files differdeleted file mode 100644 index 7cded0ba55b..00000000000 --- a/app/assets/images/emoji/city_sunset.png +++ /dev/null diff --git a/app/assets/images/emoji/cityscape.png b/app/assets/images/emoji/cityscape.png Binary files differdeleted file mode 100644 index d7b9844a0b4..00000000000 --- a/app/assets/images/emoji/cityscape.png +++ /dev/null diff --git a/app/assets/images/emoji/cl.png b/app/assets/images/emoji/cl.png Binary files differdeleted file mode 100644 index 8b01b4343e2..00000000000 --- a/app/assets/images/emoji/cl.png +++ /dev/null diff --git a/app/assets/images/emoji/clap.png b/app/assets/images/emoji/clap.png Binary files differdeleted file mode 100644 index b0ffe928920..00000000000 --- a/app/assets/images/emoji/clap.png +++ /dev/null diff --git a/app/assets/images/emoji/clap_tone1.png b/app/assets/images/emoji/clap_tone1.png Binary files differdeleted file mode 100644 index de4bc837b96..00000000000 --- a/app/assets/images/emoji/clap_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/clap_tone2.png b/app/assets/images/emoji/clap_tone2.png Binary files differdeleted file mode 100644 index 1323de775ba..00000000000 --- a/app/assets/images/emoji/clap_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/clap_tone3.png b/app/assets/images/emoji/clap_tone3.png Binary files differdeleted file mode 100644 index d448ca19dde..00000000000 --- a/app/assets/images/emoji/clap_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/clap_tone4.png b/app/assets/images/emoji/clap_tone4.png Binary files differdeleted file mode 100644 index c49f44ee91d..00000000000 --- a/app/assets/images/emoji/clap_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/clap_tone5.png b/app/assets/images/emoji/clap_tone5.png Binary files differdeleted file mode 100644 index 29ee9bdf37c..00000000000 --- a/app/assets/images/emoji/clap_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/clapper.png b/app/assets/images/emoji/clapper.png Binary files differdeleted file mode 100644 index 81390883111..00000000000 --- a/app/assets/images/emoji/clapper.png +++ /dev/null diff --git a/app/assets/images/emoji/classical_building.png b/app/assets/images/emoji/classical_building.png Binary files differdeleted file mode 100644 index de7b559daaf..00000000000 --- a/app/assets/images/emoji/classical_building.png +++ /dev/null diff --git a/app/assets/images/emoji/clipboard.png b/app/assets/images/emoji/clipboard.png Binary files differdeleted file mode 100644 index 7edcfc52509..00000000000 --- a/app/assets/images/emoji/clipboard.png +++ /dev/null diff --git a/app/assets/images/emoji/clock.png b/app/assets/images/emoji/clock.png Binary files differdeleted file mode 100644 index ffdb451e3a8..00000000000 --- a/app/assets/images/emoji/clock.png +++ /dev/null diff --git a/app/assets/images/emoji/clock1.png b/app/assets/images/emoji/clock1.png Binary files differdeleted file mode 100644 index d6e34941f23..00000000000 --- a/app/assets/images/emoji/clock1.png +++ /dev/null diff --git a/app/assets/images/emoji/clock10.png b/app/assets/images/emoji/clock10.png Binary files differdeleted file mode 100644 index e62b245cdbe..00000000000 --- a/app/assets/images/emoji/clock10.png +++ /dev/null diff --git a/app/assets/images/emoji/clock1030.png b/app/assets/images/emoji/clock1030.png Binary files differdeleted file mode 100644 index 0802b3c65b9..00000000000 --- a/app/assets/images/emoji/clock1030.png +++ /dev/null diff --git a/app/assets/images/emoji/clock11.png b/app/assets/images/emoji/clock11.png Binary files differdeleted file mode 100644 index 0983345273b..00000000000 --- a/app/assets/images/emoji/clock11.png +++ /dev/null diff --git a/app/assets/images/emoji/clock1130.png b/app/assets/images/emoji/clock1130.png Binary files differdeleted file mode 100644 index d970d03b809..00000000000 --- a/app/assets/images/emoji/clock1130.png +++ /dev/null diff --git a/app/assets/images/emoji/clock12.png b/app/assets/images/emoji/clock12.png Binary files differdeleted file mode 100644 index e61caa4b3e2..00000000000 --- a/app/assets/images/emoji/clock12.png +++ /dev/null diff --git a/app/assets/images/emoji/clock1230.png b/app/assets/images/emoji/clock1230.png Binary files differdeleted file mode 100644 index f2b1d261721..00000000000 --- a/app/assets/images/emoji/clock1230.png +++ /dev/null diff --git a/app/assets/images/emoji/clock130.png b/app/assets/images/emoji/clock130.png Binary files differdeleted file mode 100644 index 86b7689b84e..00000000000 --- a/app/assets/images/emoji/clock130.png +++ /dev/null diff --git a/app/assets/images/emoji/clock2.png b/app/assets/images/emoji/clock2.png Binary files differdeleted file mode 100644 index a54253d7d57..00000000000 --- a/app/assets/images/emoji/clock2.png +++ /dev/null diff --git a/app/assets/images/emoji/clock230.png b/app/assets/images/emoji/clock230.png Binary files differdeleted file mode 100644 index 7a787e018e6..00000000000 --- a/app/assets/images/emoji/clock230.png +++ /dev/null diff --git a/app/assets/images/emoji/clock3.png b/app/assets/images/emoji/clock3.png Binary files differdeleted file mode 100644 index 27ec4b1f514..00000000000 --- a/app/assets/images/emoji/clock3.png +++ /dev/null diff --git a/app/assets/images/emoji/clock330.png b/app/assets/images/emoji/clock330.png Binary files differdeleted file mode 100644 index c6860395cec..00000000000 --- a/app/assets/images/emoji/clock330.png +++ /dev/null diff --git a/app/assets/images/emoji/clock4.png b/app/assets/images/emoji/clock4.png Binary files differdeleted file mode 100644 index 60a1ef4cc13..00000000000 --- a/app/assets/images/emoji/clock4.png +++ /dev/null diff --git a/app/assets/images/emoji/clock430.png b/app/assets/images/emoji/clock430.png Binary files differdeleted file mode 100644 index 3c05b362122..00000000000 --- a/app/assets/images/emoji/clock430.png +++ /dev/null diff --git a/app/assets/images/emoji/clock5.png b/app/assets/images/emoji/clock5.png Binary files differdeleted file mode 100644 index c9382d1e094..00000000000 --- a/app/assets/images/emoji/clock5.png +++ /dev/null diff --git a/app/assets/images/emoji/clock530.png b/app/assets/images/emoji/clock530.png Binary files differdeleted file mode 100644 index c21fa926db2..00000000000 --- a/app/assets/images/emoji/clock530.png +++ /dev/null diff --git a/app/assets/images/emoji/clock6.png b/app/assets/images/emoji/clock6.png Binary files differdeleted file mode 100644 index 8fd5d3f5bd7..00000000000 --- a/app/assets/images/emoji/clock6.png +++ /dev/null diff --git a/app/assets/images/emoji/clock630.png b/app/assets/images/emoji/clock630.png Binary files differdeleted file mode 100644 index 2aec87fefcf..00000000000 --- a/app/assets/images/emoji/clock630.png +++ /dev/null diff --git a/app/assets/images/emoji/clock7.png b/app/assets/images/emoji/clock7.png Binary files differdeleted file mode 100644 index 8c7084036f2..00000000000 --- a/app/assets/images/emoji/clock7.png +++ /dev/null diff --git a/app/assets/images/emoji/clock730.png b/app/assets/images/emoji/clock730.png Binary files differdeleted file mode 100644 index f7a1135e03f..00000000000 --- a/app/assets/images/emoji/clock730.png +++ /dev/null diff --git a/app/assets/images/emoji/clock8.png b/app/assets/images/emoji/clock8.png Binary files differdeleted file mode 100644 index fcddf722e95..00000000000 --- a/app/assets/images/emoji/clock8.png +++ /dev/null diff --git a/app/assets/images/emoji/clock830.png b/app/assets/images/emoji/clock830.png Binary files differdeleted file mode 100644 index 799b4aebc08..00000000000 --- a/app/assets/images/emoji/clock830.png +++ /dev/null diff --git a/app/assets/images/emoji/clock9.png b/app/assets/images/emoji/clock9.png Binary files differdeleted file mode 100644 index dfbe0117981..00000000000 --- a/app/assets/images/emoji/clock9.png +++ /dev/null diff --git a/app/assets/images/emoji/clock930.png b/app/assets/images/emoji/clock930.png Binary files differdeleted file mode 100644 index 4a2092ee6f0..00000000000 --- a/app/assets/images/emoji/clock930.png +++ /dev/null diff --git a/app/assets/images/emoji/closed_book.png b/app/assets/images/emoji/closed_book.png Binary files differdeleted file mode 100644 index 6395cf2151e..00000000000 --- a/app/assets/images/emoji/closed_book.png +++ /dev/null diff --git a/app/assets/images/emoji/closed_lock_with_key.png b/app/assets/images/emoji/closed_lock_with_key.png Binary files differdeleted file mode 100644 index 1c1cd5d0741..00000000000 --- a/app/assets/images/emoji/closed_lock_with_key.png +++ /dev/null diff --git a/app/assets/images/emoji/closed_umbrella.png b/app/assets/images/emoji/closed_umbrella.png Binary files differdeleted file mode 100644 index ecefba9e446..00000000000 --- a/app/assets/images/emoji/closed_umbrella.png +++ /dev/null diff --git a/app/assets/images/emoji/cloud.png b/app/assets/images/emoji/cloud.png Binary files differdeleted file mode 100644 index 5b4f57f77ba..00000000000 --- a/app/assets/images/emoji/cloud.png +++ /dev/null diff --git a/app/assets/images/emoji/cloud_lightning.png b/app/assets/images/emoji/cloud_lightning.png Binary files differdeleted file mode 100644 index 0831e88aa31..00000000000 --- a/app/assets/images/emoji/cloud_lightning.png +++ /dev/null diff --git a/app/assets/images/emoji/cloud_rain.png b/app/assets/images/emoji/cloud_rain.png Binary files differdeleted file mode 100644 index 385685e0512..00000000000 --- a/app/assets/images/emoji/cloud_rain.png +++ /dev/null diff --git a/app/assets/images/emoji/cloud_snow.png b/app/assets/images/emoji/cloud_snow.png Binary files differdeleted file mode 100644 index 9720384eb99..00000000000 --- a/app/assets/images/emoji/cloud_snow.png +++ /dev/null diff --git a/app/assets/images/emoji/cloud_tornado.png b/app/assets/images/emoji/cloud_tornado.png Binary files differdeleted file mode 100644 index 4821c89da1e..00000000000 --- a/app/assets/images/emoji/cloud_tornado.png +++ /dev/null diff --git a/app/assets/images/emoji/clown.png b/app/assets/images/emoji/clown.png Binary files differdeleted file mode 100644 index 02b7ff70049..00000000000 --- a/app/assets/images/emoji/clown.png +++ /dev/null diff --git a/app/assets/images/emoji/clubs.png b/app/assets/images/emoji/clubs.png Binary files differdeleted file mode 100644 index 4f2abf791ca..00000000000 --- a/app/assets/images/emoji/clubs.png +++ /dev/null diff --git a/app/assets/images/emoji/cocktail.png b/app/assets/images/emoji/cocktail.png Binary files differdeleted file mode 100644 index 2e50c57e98d..00000000000 --- a/app/assets/images/emoji/cocktail.png +++ /dev/null diff --git a/app/assets/images/emoji/coffee.png b/app/assets/images/emoji/coffee.png Binary files differdeleted file mode 100644 index 553061471b1..00000000000 --- a/app/assets/images/emoji/coffee.png +++ /dev/null diff --git a/app/assets/images/emoji/coffin.png b/app/assets/images/emoji/coffin.png Binary files differdeleted file mode 100644 index fb2932aa5f6..00000000000 --- a/app/assets/images/emoji/coffin.png +++ /dev/null diff --git a/app/assets/images/emoji/cold_sweat.png b/app/assets/images/emoji/cold_sweat.png Binary files differdeleted file mode 100644 index 85b2231bbf6..00000000000 --- a/app/assets/images/emoji/cold_sweat.png +++ /dev/null diff --git a/app/assets/images/emoji/comet.png b/app/assets/images/emoji/comet.png Binary files differdeleted file mode 100644 index a99751f79be..00000000000 --- a/app/assets/images/emoji/comet.png +++ /dev/null diff --git a/app/assets/images/emoji/compression.png b/app/assets/images/emoji/compression.png Binary files differdeleted file mode 100644 index d7eda7f362a..00000000000 --- a/app/assets/images/emoji/compression.png +++ /dev/null diff --git a/app/assets/images/emoji/computer.png b/app/assets/images/emoji/computer.png Binary files differdeleted file mode 100644 index c1fee27e3a9..00000000000 --- a/app/assets/images/emoji/computer.png +++ /dev/null diff --git a/app/assets/images/emoji/confetti_ball.png b/app/assets/images/emoji/confetti_ball.png Binary files differdeleted file mode 100644 index ba4fd9b12be..00000000000 --- a/app/assets/images/emoji/confetti_ball.png +++ /dev/null diff --git a/app/assets/images/emoji/confounded.png b/app/assets/images/emoji/confounded.png Binary files differdeleted file mode 100644 index aa4b29e9375..00000000000 --- a/app/assets/images/emoji/confounded.png +++ /dev/null diff --git a/app/assets/images/emoji/confused.png b/app/assets/images/emoji/confused.png Binary files differdeleted file mode 100644 index 502b6bf0e0b..00000000000 --- a/app/assets/images/emoji/confused.png +++ /dev/null diff --git a/app/assets/images/emoji/congratulations.png b/app/assets/images/emoji/congratulations.png Binary files differdeleted file mode 100644 index ba8c89d95ee..00000000000 --- a/app/assets/images/emoji/congratulations.png +++ /dev/null diff --git a/app/assets/images/emoji/construction.png b/app/assets/images/emoji/construction.png Binary files differdeleted file mode 100644 index ef8db5f471c..00000000000 --- a/app/assets/images/emoji/construction.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_site.png b/app/assets/images/emoji/construction_site.png Binary files differdeleted file mode 100644 index 8206a20f63f..00000000000 --- a/app/assets/images/emoji/construction_site.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_worker.png b/app/assets/images/emoji/construction_worker.png Binary files differdeleted file mode 100644 index a9970a89005..00000000000 --- a/app/assets/images/emoji/construction_worker.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_worker_tone1.png b/app/assets/images/emoji/construction_worker_tone1.png Binary files differdeleted file mode 100644 index 2f24a2bab24..00000000000 --- a/app/assets/images/emoji/construction_worker_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_worker_tone2.png b/app/assets/images/emoji/construction_worker_tone2.png Binary files differdeleted file mode 100644 index 93c8fec5a75..00000000000 --- a/app/assets/images/emoji/construction_worker_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_worker_tone3.png b/app/assets/images/emoji/construction_worker_tone3.png Binary files differdeleted file mode 100644 index abc1f2af2e0..00000000000 --- a/app/assets/images/emoji/construction_worker_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_worker_tone4.png b/app/assets/images/emoji/construction_worker_tone4.png Binary files differdeleted file mode 100644 index eed83289aeb..00000000000 --- a/app/assets/images/emoji/construction_worker_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/construction_worker_tone5.png b/app/assets/images/emoji/construction_worker_tone5.png Binary files differdeleted file mode 100644 index acbb220b8bb..00000000000 --- a/app/assets/images/emoji/construction_worker_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/control_knobs.png b/app/assets/images/emoji/control_knobs.png Binary files differdeleted file mode 100644 index 6635ac93b50..00000000000 --- a/app/assets/images/emoji/control_knobs.png +++ /dev/null diff --git a/app/assets/images/emoji/convenience_store.png b/app/assets/images/emoji/convenience_store.png Binary files differdeleted file mode 100644 index 26b53b5669e..00000000000 --- a/app/assets/images/emoji/convenience_store.png +++ /dev/null diff --git a/app/assets/images/emoji/cookie.png b/app/assets/images/emoji/cookie.png Binary files differdeleted file mode 100644 index 1b6bcb1554f..00000000000 --- a/app/assets/images/emoji/cookie.png +++ /dev/null diff --git a/app/assets/images/emoji/cooking.png b/app/assets/images/emoji/cooking.png Binary files differdeleted file mode 100644 index 918c980577a..00000000000 --- a/app/assets/images/emoji/cooking.png +++ /dev/null diff --git a/app/assets/images/emoji/cool.png b/app/assets/images/emoji/cool.png Binary files differdeleted file mode 100644 index 74674978d00..00000000000 --- a/app/assets/images/emoji/cool.png +++ /dev/null diff --git a/app/assets/images/emoji/cop.png b/app/assets/images/emoji/cop.png Binary files differdeleted file mode 100644 index 0b16d7c17b7..00000000000 --- a/app/assets/images/emoji/cop.png +++ /dev/null diff --git a/app/assets/images/emoji/cop_tone1.png b/app/assets/images/emoji/cop_tone1.png Binary files differdeleted file mode 100644 index 6ccba3879dc..00000000000 --- a/app/assets/images/emoji/cop_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/cop_tone2.png b/app/assets/images/emoji/cop_tone2.png Binary files differdeleted file mode 100644 index 7814ea9f52d..00000000000 --- a/app/assets/images/emoji/cop_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/cop_tone3.png b/app/assets/images/emoji/cop_tone3.png Binary files differdeleted file mode 100644 index d78e88ec872..00000000000 --- a/app/assets/images/emoji/cop_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/cop_tone4.png b/app/assets/images/emoji/cop_tone4.png Binary files differdeleted file mode 100644 index 2e13c508315..00000000000 --- a/app/assets/images/emoji/cop_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/cop_tone5.png b/app/assets/images/emoji/cop_tone5.png Binary files differdeleted file mode 100644 index 2980d61cc2e..00000000000 --- a/app/assets/images/emoji/cop_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/copyright.png b/app/assets/images/emoji/copyright.png Binary files differdeleted file mode 100644 index 6b9a6adbfd2..00000000000 --- a/app/assets/images/emoji/copyright.png +++ /dev/null diff --git a/app/assets/images/emoji/corn.png b/app/assets/images/emoji/corn.png Binary files differdeleted file mode 100644 index 36e20127931..00000000000 --- a/app/assets/images/emoji/corn.png +++ /dev/null diff --git a/app/assets/images/emoji/couch.png b/app/assets/images/emoji/couch.png Binary files differdeleted file mode 100644 index 27b19b13bb0..00000000000 --- a/app/assets/images/emoji/couch.png +++ /dev/null diff --git a/app/assets/images/emoji/couple.png b/app/assets/images/emoji/couple.png Binary files differdeleted file mode 100644 index 960323f3c16..00000000000 --- a/app/assets/images/emoji/couple.png +++ /dev/null diff --git a/app/assets/images/emoji/couple_mm.png b/app/assets/images/emoji/couple_mm.png Binary files differdeleted file mode 100644 index 8759fa5db87..00000000000 --- a/app/assets/images/emoji/couple_mm.png +++ /dev/null diff --git a/app/assets/images/emoji/couple_with_heart.png b/app/assets/images/emoji/couple_with_heart.png Binary files differdeleted file mode 100644 index 62111601b36..00000000000 --- a/app/assets/images/emoji/couple_with_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/couple_ww.png b/app/assets/images/emoji/couple_ww.png Binary files differdeleted file mode 100644 index 08fdabcdc5c..00000000000 --- a/app/assets/images/emoji/couple_ww.png +++ /dev/null diff --git a/app/assets/images/emoji/couplekiss.png b/app/assets/images/emoji/couplekiss.png Binary files differdeleted file mode 100644 index 9aa519da9e8..00000000000 --- a/app/assets/images/emoji/couplekiss.png +++ /dev/null diff --git a/app/assets/images/emoji/cow.png b/app/assets/images/emoji/cow.png Binary files differdeleted file mode 100644 index 718a3986d64..00000000000 --- a/app/assets/images/emoji/cow.png +++ /dev/null diff --git a/app/assets/images/emoji/cow2.png b/app/assets/images/emoji/cow2.png Binary files differdeleted file mode 100644 index 4d0ca534ff1..00000000000 --- a/app/assets/images/emoji/cow2.png +++ /dev/null diff --git a/app/assets/images/emoji/cowboy.png b/app/assets/images/emoji/cowboy.png Binary files differdeleted file mode 100644 index 70dd5d0d9d1..00000000000 --- a/app/assets/images/emoji/cowboy.png +++ /dev/null diff --git a/app/assets/images/emoji/crab.png b/app/assets/images/emoji/crab.png Binary files differdeleted file mode 100644 index 19f3047ab61..00000000000 --- a/app/assets/images/emoji/crab.png +++ /dev/null diff --git a/app/assets/images/emoji/crayon.png b/app/assets/images/emoji/crayon.png Binary files differdeleted file mode 100644 index 8d7b427aaa3..00000000000 --- a/app/assets/images/emoji/crayon.png +++ /dev/null diff --git a/app/assets/images/emoji/credit_card.png b/app/assets/images/emoji/credit_card.png Binary files differdeleted file mode 100644 index 372777d5c61..00000000000 --- a/app/assets/images/emoji/credit_card.png +++ /dev/null diff --git a/app/assets/images/emoji/crescent_moon.png b/app/assets/images/emoji/crescent_moon.png Binary files differdeleted file mode 100644 index 765420ecec7..00000000000 --- a/app/assets/images/emoji/crescent_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/cricket.png b/app/assets/images/emoji/cricket.png Binary files differdeleted file mode 100644 index d602294a2cd..00000000000 --- a/app/assets/images/emoji/cricket.png +++ /dev/null diff --git a/app/assets/images/emoji/crocodile.png b/app/assets/images/emoji/crocodile.png Binary files differdeleted file mode 100644 index 3005c46f176..00000000000 --- a/app/assets/images/emoji/crocodile.png +++ /dev/null diff --git a/app/assets/images/emoji/croissant.png b/app/assets/images/emoji/croissant.png Binary files differdeleted file mode 100644 index fb33feb1a38..00000000000 --- a/app/assets/images/emoji/croissant.png +++ /dev/null diff --git a/app/assets/images/emoji/cross.png b/app/assets/images/emoji/cross.png Binary files differdeleted file mode 100644 index 42b10e82257..00000000000 --- a/app/assets/images/emoji/cross.png +++ /dev/null diff --git a/app/assets/images/emoji/crossed_flags.png b/app/assets/images/emoji/crossed_flags.png Binary files differdeleted file mode 100644 index 273bd0f0fe5..00000000000 --- a/app/assets/images/emoji/crossed_flags.png +++ /dev/null diff --git a/app/assets/images/emoji/crossed_swords.png b/app/assets/images/emoji/crossed_swords.png Binary files differdeleted file mode 100644 index 907e9607134..00000000000 --- a/app/assets/images/emoji/crossed_swords.png +++ /dev/null diff --git a/app/assets/images/emoji/crown.png b/app/assets/images/emoji/crown.png Binary files differdeleted file mode 100644 index 93b82d92f04..00000000000 --- a/app/assets/images/emoji/crown.png +++ /dev/null diff --git a/app/assets/images/emoji/cruise_ship.png b/app/assets/images/emoji/cruise_ship.png Binary files differdeleted file mode 100644 index 19d4acbe40c..00000000000 --- a/app/assets/images/emoji/cruise_ship.png +++ /dev/null diff --git a/app/assets/images/emoji/cry.png b/app/assets/images/emoji/cry.png Binary files differdeleted file mode 100644 index b7877f8a173..00000000000 --- a/app/assets/images/emoji/cry.png +++ /dev/null diff --git a/app/assets/images/emoji/crying_cat_face.png b/app/assets/images/emoji/crying_cat_face.png Binary files differdeleted file mode 100644 index b4f49715e00..00000000000 --- a/app/assets/images/emoji/crying_cat_face.png +++ /dev/null diff --git a/app/assets/images/emoji/crystal_ball.png b/app/assets/images/emoji/crystal_ball.png Binary files differdeleted file mode 100644 index 485d5c888f1..00000000000 --- a/app/assets/images/emoji/crystal_ball.png +++ /dev/null diff --git a/app/assets/images/emoji/cucumber.png b/app/assets/images/emoji/cucumber.png Binary files differdeleted file mode 100644 index 500807059d2..00000000000 --- a/app/assets/images/emoji/cucumber.png +++ /dev/null diff --git a/app/assets/images/emoji/cupid.png b/app/assets/images/emoji/cupid.png Binary files differdeleted file mode 100644 index 2df0078ddd1..00000000000 --- a/app/assets/images/emoji/cupid.png +++ /dev/null diff --git a/app/assets/images/emoji/curly_loop.png b/app/assets/images/emoji/curly_loop.png Binary files differdeleted file mode 100644 index 440aa56d50e..00000000000 --- a/app/assets/images/emoji/curly_loop.png +++ /dev/null diff --git a/app/assets/images/emoji/currency_exchange.png b/app/assets/images/emoji/currency_exchange.png Binary files differdeleted file mode 100644 index 4d46c6050e7..00000000000 --- a/app/assets/images/emoji/currency_exchange.png +++ /dev/null diff --git a/app/assets/images/emoji/curry.png b/app/assets/images/emoji/curry.png Binary files differdeleted file mode 100644 index 69657ca8103..00000000000 --- a/app/assets/images/emoji/curry.png +++ /dev/null diff --git a/app/assets/images/emoji/custard.png b/app/assets/images/emoji/custard.png Binary files differdeleted file mode 100644 index fa3df67b8f6..00000000000 --- a/app/assets/images/emoji/custard.png +++ /dev/null diff --git a/app/assets/images/emoji/customs.png b/app/assets/images/emoji/customs.png Binary files differdeleted file mode 100644 index 21b7ce2c69e..00000000000 --- a/app/assets/images/emoji/customs.png +++ /dev/null diff --git a/app/assets/images/emoji/cyclone.png b/app/assets/images/emoji/cyclone.png Binary files differdeleted file mode 100644 index ff00b1afe70..00000000000 --- a/app/assets/images/emoji/cyclone.png +++ /dev/null diff --git a/app/assets/images/emoji/dagger.png b/app/assets/images/emoji/dagger.png Binary files differdeleted file mode 100644 index 66e97b0aa25..00000000000 --- a/app/assets/images/emoji/dagger.png +++ /dev/null diff --git a/app/assets/images/emoji/dancer.png b/app/assets/images/emoji/dancer.png Binary files differdeleted file mode 100644 index 04b166991cb..00000000000 --- a/app/assets/images/emoji/dancer.png +++ /dev/null diff --git a/app/assets/images/emoji/dancer_tone1.png b/app/assets/images/emoji/dancer_tone1.png Binary files differdeleted file mode 100644 index 2c7b11c3a6e..00000000000 --- a/app/assets/images/emoji/dancer_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/dancer_tone2.png b/app/assets/images/emoji/dancer_tone2.png Binary files differdeleted file mode 100644 index cb04b1f907e..00000000000 --- a/app/assets/images/emoji/dancer_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/dancer_tone3.png b/app/assets/images/emoji/dancer_tone3.png Binary files differdeleted file mode 100644 index 98c5bca7b64..00000000000 --- a/app/assets/images/emoji/dancer_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/dancer_tone4.png b/app/assets/images/emoji/dancer_tone4.png Binary files differdeleted file mode 100644 index fdb1e00cbba..00000000000 --- a/app/assets/images/emoji/dancer_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/dancer_tone5.png b/app/assets/images/emoji/dancer_tone5.png Binary files differdeleted file mode 100644 index 0e34e0e23f0..00000000000 --- a/app/assets/images/emoji/dancer_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/dancers.png b/app/assets/images/emoji/dancers.png Binary files differdeleted file mode 100644 index 67e6ffacb76..00000000000 --- a/app/assets/images/emoji/dancers.png +++ /dev/null diff --git a/app/assets/images/emoji/dango.png b/app/assets/images/emoji/dango.png Binary files differdeleted file mode 100644 index f73f37b01c7..00000000000 --- a/app/assets/images/emoji/dango.png +++ /dev/null diff --git a/app/assets/images/emoji/dark_sunglasses.png b/app/assets/images/emoji/dark_sunglasses.png Binary files differdeleted file mode 100644 index b1b6db0acff..00000000000 --- a/app/assets/images/emoji/dark_sunglasses.png +++ /dev/null diff --git a/app/assets/images/emoji/dart.png b/app/assets/images/emoji/dart.png Binary files differdeleted file mode 100644 index f6704aeb8ba..00000000000 --- a/app/assets/images/emoji/dart.png +++ /dev/null diff --git a/app/assets/images/emoji/dash.png b/app/assets/images/emoji/dash.png Binary files differdeleted file mode 100644 index 064b8525c12..00000000000 --- a/app/assets/images/emoji/dash.png +++ /dev/null diff --git a/app/assets/images/emoji/date.png b/app/assets/images/emoji/date.png Binary files differdeleted file mode 100644 index f05b3da97b8..00000000000 --- a/app/assets/images/emoji/date.png +++ /dev/null diff --git a/app/assets/images/emoji/deciduous_tree.png b/app/assets/images/emoji/deciduous_tree.png Binary files differdeleted file mode 100644 index 785fc1c30ea..00000000000 --- a/app/assets/images/emoji/deciduous_tree.png +++ /dev/null diff --git a/app/assets/images/emoji/deer.png b/app/assets/images/emoji/deer.png Binary files differdeleted file mode 100644 index d8698195ff0..00000000000 --- a/app/assets/images/emoji/deer.png +++ /dev/null diff --git a/app/assets/images/emoji/department_store.png b/app/assets/images/emoji/department_store.png Binary files differdeleted file mode 100644 index 58867c7a6e1..00000000000 --- a/app/assets/images/emoji/department_store.png +++ /dev/null diff --git a/app/assets/images/emoji/desert.png b/app/assets/images/emoji/desert.png Binary files differdeleted file mode 100644 index e9966ff8c65..00000000000 --- a/app/assets/images/emoji/desert.png +++ /dev/null diff --git a/app/assets/images/emoji/desktop.png b/app/assets/images/emoji/desktop.png Binary files differdeleted file mode 100644 index 909bd42b5e1..00000000000 --- a/app/assets/images/emoji/desktop.png +++ /dev/null diff --git a/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png b/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png Binary files differdeleted file mode 100644 index 2a22a26d1e2..00000000000 --- a/app/assets/images/emoji/diamond_shape_with_a_dot_inside.png +++ /dev/null diff --git a/app/assets/images/emoji/diamonds.png b/app/assets/images/emoji/diamonds.png Binary files differdeleted file mode 100644 index 1f25f51f97a..00000000000 --- a/app/assets/images/emoji/diamonds.png +++ /dev/null diff --git a/app/assets/images/emoji/disappointed.png b/app/assets/images/emoji/disappointed.png Binary files differdeleted file mode 100644 index efe4e67e23c..00000000000 --- a/app/assets/images/emoji/disappointed.png +++ /dev/null diff --git a/app/assets/images/emoji/disappointed_relieved.png b/app/assets/images/emoji/disappointed_relieved.png Binary files differdeleted file mode 100644 index aef864d2b3d..00000000000 --- a/app/assets/images/emoji/disappointed_relieved.png +++ /dev/null diff --git a/app/assets/images/emoji/dividers.png b/app/assets/images/emoji/dividers.png Binary files differdeleted file mode 100644 index 46a7e403f9d..00000000000 --- a/app/assets/images/emoji/dividers.png +++ /dev/null diff --git a/app/assets/images/emoji/dizzy.png b/app/assets/images/emoji/dizzy.png Binary files differdeleted file mode 100644 index 85f52efad24..00000000000 --- a/app/assets/images/emoji/dizzy.png +++ /dev/null diff --git a/app/assets/images/emoji/dizzy_face.png b/app/assets/images/emoji/dizzy_face.png Binary files differdeleted file mode 100644 index 3120316ab5e..00000000000 --- a/app/assets/images/emoji/dizzy_face.png +++ /dev/null diff --git a/app/assets/images/emoji/do_not_litter.png b/app/assets/images/emoji/do_not_litter.png Binary files differdeleted file mode 100644 index 341d2575f4f..00000000000 --- a/app/assets/images/emoji/do_not_litter.png +++ /dev/null diff --git a/app/assets/images/emoji/dog.png b/app/assets/images/emoji/dog.png Binary files differdeleted file mode 100644 index 281b81d58bd..00000000000 --- a/app/assets/images/emoji/dog.png +++ /dev/null diff --git a/app/assets/images/emoji/dog2.png b/app/assets/images/emoji/dog2.png Binary files differdeleted file mode 100644 index 976143dbdbe..00000000000 --- a/app/assets/images/emoji/dog2.png +++ /dev/null diff --git a/app/assets/images/emoji/dollar.png b/app/assets/images/emoji/dollar.png Binary files differdeleted file mode 100644 index a9904c28293..00000000000 --- a/app/assets/images/emoji/dollar.png +++ /dev/null diff --git a/app/assets/images/emoji/dolls.png b/app/assets/images/emoji/dolls.png Binary files differdeleted file mode 100644 index 10955615110..00000000000 --- a/app/assets/images/emoji/dolls.png +++ /dev/null diff --git a/app/assets/images/emoji/dolphin.png b/app/assets/images/emoji/dolphin.png Binary files differdeleted file mode 100644 index 81434809003..00000000000 --- a/app/assets/images/emoji/dolphin.png +++ /dev/null diff --git a/app/assets/images/emoji/door.png b/app/assets/images/emoji/door.png Binary files differdeleted file mode 100644 index 36ae3e27494..00000000000 --- a/app/assets/images/emoji/door.png +++ /dev/null diff --git a/app/assets/images/emoji/doughnut.png b/app/assets/images/emoji/doughnut.png Binary files differdeleted file mode 100644 index 0ca4cd0bde8..00000000000 --- a/app/assets/images/emoji/doughnut.png +++ /dev/null diff --git a/app/assets/images/emoji/dove.png b/app/assets/images/emoji/dove.png Binary files differdeleted file mode 100644 index 9580c4917d7..00000000000 --- a/app/assets/images/emoji/dove.png +++ /dev/null diff --git a/app/assets/images/emoji/dragon.png b/app/assets/images/emoji/dragon.png Binary files differdeleted file mode 100644 index d6311cf5429..00000000000 --- a/app/assets/images/emoji/dragon.png +++ /dev/null diff --git a/app/assets/images/emoji/dragon_face.png b/app/assets/images/emoji/dragon_face.png Binary files differdeleted file mode 100644 index 3c2720446c6..00000000000 --- a/app/assets/images/emoji/dragon_face.png +++ /dev/null diff --git a/app/assets/images/emoji/dress.png b/app/assets/images/emoji/dress.png Binary files differdeleted file mode 100644 index a697ca5c57d..00000000000 --- a/app/assets/images/emoji/dress.png +++ /dev/null diff --git a/app/assets/images/emoji/dromedary_camel.png b/app/assets/images/emoji/dromedary_camel.png Binary files differdeleted file mode 100644 index 5271637c7c4..00000000000 --- a/app/assets/images/emoji/dromedary_camel.png +++ /dev/null diff --git a/app/assets/images/emoji/drooling_face.png b/app/assets/images/emoji/drooling_face.png Binary files differdeleted file mode 100644 index a5460532597..00000000000 --- a/app/assets/images/emoji/drooling_face.png +++ /dev/null diff --git a/app/assets/images/emoji/droplet.png b/app/assets/images/emoji/droplet.png Binary files differdeleted file mode 100644 index 71241ec3061..00000000000 --- a/app/assets/images/emoji/droplet.png +++ /dev/null diff --git a/app/assets/images/emoji/drum.png b/app/assets/images/emoji/drum.png Binary files differdeleted file mode 100644 index b038727cc99..00000000000 --- a/app/assets/images/emoji/drum.png +++ /dev/null diff --git a/app/assets/images/emoji/duck.png b/app/assets/images/emoji/duck.png Binary files differdeleted file mode 100644 index 74330b77ca3..00000000000 --- a/app/assets/images/emoji/duck.png +++ /dev/null diff --git a/app/assets/images/emoji/dvd.png b/app/assets/images/emoji/dvd.png Binary files differdeleted file mode 100644 index 045a6f7a08d..00000000000 --- a/app/assets/images/emoji/dvd.png +++ /dev/null diff --git a/app/assets/images/emoji/e-mail.png b/app/assets/images/emoji/e-mail.png Binary files differdeleted file mode 100644 index d22e654a20b..00000000000 --- a/app/assets/images/emoji/e-mail.png +++ /dev/null diff --git a/app/assets/images/emoji/eagle.png b/app/assets/images/emoji/eagle.png Binary files differdeleted file mode 100644 index 4f277debeef..00000000000 --- a/app/assets/images/emoji/eagle.png +++ /dev/null diff --git a/app/assets/images/emoji/ear.png b/app/assets/images/emoji/ear.png Binary files differdeleted file mode 100644 index f84f9ff154a..00000000000 --- a/app/assets/images/emoji/ear.png +++ /dev/null diff --git a/app/assets/images/emoji/ear_of_rice.png b/app/assets/images/emoji/ear_of_rice.png Binary files differdeleted file mode 100644 index 3564d9d643a..00000000000 --- a/app/assets/images/emoji/ear_of_rice.png +++ /dev/null diff --git a/app/assets/images/emoji/ear_tone1.png b/app/assets/images/emoji/ear_tone1.png Binary files differdeleted file mode 100644 index d09e1e41996..00000000000 --- a/app/assets/images/emoji/ear_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/ear_tone2.png b/app/assets/images/emoji/ear_tone2.png Binary files differdeleted file mode 100644 index 300d60a9948..00000000000 --- a/app/assets/images/emoji/ear_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/ear_tone3.png b/app/assets/images/emoji/ear_tone3.png Binary files differdeleted file mode 100644 index 2a56eebe445..00000000000 --- a/app/assets/images/emoji/ear_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/ear_tone4.png b/app/assets/images/emoji/ear_tone4.png Binary files differdeleted file mode 100644 index bd270f7763e..00000000000 --- a/app/assets/images/emoji/ear_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/ear_tone5.png b/app/assets/images/emoji/ear_tone5.png Binary files differdeleted file mode 100644 index b96bb441dff..00000000000 --- a/app/assets/images/emoji/ear_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/earth_africa.png b/app/assets/images/emoji/earth_africa.png Binary files differdeleted file mode 100644 index 66c3348c23a..00000000000 --- a/app/assets/images/emoji/earth_africa.png +++ /dev/null diff --git a/app/assets/images/emoji/earth_americas.png b/app/assets/images/emoji/earth_americas.png Binary files differdeleted file mode 100644 index 538c3cddd68..00000000000 --- a/app/assets/images/emoji/earth_americas.png +++ /dev/null diff --git a/app/assets/images/emoji/earth_asia.png b/app/assets/images/emoji/earth_asia.png Binary files differdeleted file mode 100644 index d8df97fec3c..00000000000 --- a/app/assets/images/emoji/earth_asia.png +++ /dev/null diff --git a/app/assets/images/emoji/egg.png b/app/assets/images/emoji/egg.png Binary files differdeleted file mode 100644 index c171974d993..00000000000 --- a/app/assets/images/emoji/egg.png +++ /dev/null diff --git a/app/assets/images/emoji/eggplant.png b/app/assets/images/emoji/eggplant.png Binary files differdeleted file mode 100644 index fafd7c1a14c..00000000000 --- a/app/assets/images/emoji/eggplant.png +++ /dev/null diff --git a/app/assets/images/emoji/eight.png b/app/assets/images/emoji/eight.png Binary files differdeleted file mode 100644 index 8c95874d4c5..00000000000 --- a/app/assets/images/emoji/eight.png +++ /dev/null diff --git a/app/assets/images/emoji/eight_pointed_black_star.png b/app/assets/images/emoji/eight_pointed_black_star.png Binary files differdeleted file mode 100644 index 820179bda50..00000000000 --- a/app/assets/images/emoji/eight_pointed_black_star.png +++ /dev/null diff --git a/app/assets/images/emoji/eight_spoked_asterisk.png b/app/assets/images/emoji/eight_spoked_asterisk.png Binary files differdeleted file mode 100644 index 3307ffa62ee..00000000000 --- a/app/assets/images/emoji/eight_spoked_asterisk.png +++ /dev/null diff --git a/app/assets/images/emoji/eject.png b/app/assets/images/emoji/eject.png Binary files differdeleted file mode 100644 index ec5cfc48973..00000000000 --- a/app/assets/images/emoji/eject.png +++ /dev/null diff --git a/app/assets/images/emoji/electric_plug.png b/app/assets/images/emoji/electric_plug.png Binary files differdeleted file mode 100644 index 31d1eb215b4..00000000000 --- a/app/assets/images/emoji/electric_plug.png +++ /dev/null diff --git a/app/assets/images/emoji/elephant.png b/app/assets/images/emoji/elephant.png Binary files differdeleted file mode 100644 index b8a6d140595..00000000000 --- a/app/assets/images/emoji/elephant.png +++ /dev/null diff --git a/app/assets/images/emoji/end.png b/app/assets/images/emoji/end.png Binary files differdeleted file mode 100644 index ef3ccd5f367..00000000000 --- a/app/assets/images/emoji/end.png +++ /dev/null diff --git a/app/assets/images/emoji/envelope.png b/app/assets/images/emoji/envelope.png Binary files differdeleted file mode 100644 index ec77ac375a4..00000000000 --- a/app/assets/images/emoji/envelope.png +++ /dev/null diff --git a/app/assets/images/emoji/envelope_with_arrow.png b/app/assets/images/emoji/envelope_with_arrow.png Binary files differdeleted file mode 100644 index 7448a6b7673..00000000000 --- a/app/assets/images/emoji/envelope_with_arrow.png +++ /dev/null diff --git a/app/assets/images/emoji/euro.png b/app/assets/images/emoji/euro.png Binary files differdeleted file mode 100644 index a49020820e1..00000000000 --- a/app/assets/images/emoji/euro.png +++ /dev/null diff --git a/app/assets/images/emoji/european_castle.png b/app/assets/images/emoji/european_castle.png Binary files differdeleted file mode 100644 index 888d11332ce..00000000000 --- a/app/assets/images/emoji/european_castle.png +++ /dev/null diff --git a/app/assets/images/emoji/european_post_office.png b/app/assets/images/emoji/european_post_office.png Binary files differdeleted file mode 100644 index 3745aff8dd2..00000000000 --- a/app/assets/images/emoji/european_post_office.png +++ /dev/null diff --git a/app/assets/images/emoji/evergreen_tree.png b/app/assets/images/emoji/evergreen_tree.png Binary files differdeleted file mode 100644 index f679d8dd772..00000000000 --- a/app/assets/images/emoji/evergreen_tree.png +++ /dev/null diff --git a/app/assets/images/emoji/exclamation.png b/app/assets/images/emoji/exclamation.png Binary files differdeleted file mode 100644 index 2c14406422f..00000000000 --- a/app/assets/images/emoji/exclamation.png +++ /dev/null diff --git a/app/assets/images/emoji/expressionless.png b/app/assets/images/emoji/expressionless.png Binary files differdeleted file mode 100644 index 2954017f6c2..00000000000 --- a/app/assets/images/emoji/expressionless.png +++ /dev/null diff --git a/app/assets/images/emoji/eye.png b/app/assets/images/emoji/eye.png Binary files differdeleted file mode 100644 index 9d989cdd375..00000000000 --- a/app/assets/images/emoji/eye.png +++ /dev/null diff --git a/app/assets/images/emoji/eye_in_speech_bubble.png b/app/assets/images/emoji/eye_in_speech_bubble.png Binary files differdeleted file mode 100644 index 21bd22bbcce..00000000000 --- a/app/assets/images/emoji/eye_in_speech_bubble.png +++ /dev/null diff --git a/app/assets/images/emoji/eyeglasses.png b/app/assets/images/emoji/eyeglasses.png Binary files differdeleted file mode 100644 index 865d8274acf..00000000000 --- a/app/assets/images/emoji/eyeglasses.png +++ /dev/null diff --git a/app/assets/images/emoji/eyes.png b/app/assets/images/emoji/eyes.png Binary files differdeleted file mode 100644 index 2102ada7e09..00000000000 --- a/app/assets/images/emoji/eyes.png +++ /dev/null diff --git a/app/assets/images/emoji/face_palm.png b/app/assets/images/emoji/face_palm.png Binary files differdeleted file mode 100644 index defc796cf16..00000000000 --- a/app/assets/images/emoji/face_palm.png +++ /dev/null diff --git a/app/assets/images/emoji/face_palm_tone1.png b/app/assets/images/emoji/face_palm_tone1.png Binary files differdeleted file mode 100644 index 2f4b010bb40..00000000000 --- a/app/assets/images/emoji/face_palm_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/face_palm_tone2.png b/app/assets/images/emoji/face_palm_tone2.png Binary files differdeleted file mode 100644 index 97fb6831687..00000000000 --- a/app/assets/images/emoji/face_palm_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/face_palm_tone3.png b/app/assets/images/emoji/face_palm_tone3.png Binary files differdeleted file mode 100644 index b5b5c1e5306..00000000000 --- a/app/assets/images/emoji/face_palm_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/face_palm_tone4.png b/app/assets/images/emoji/face_palm_tone4.png Binary files differdeleted file mode 100644 index 2840b113483..00000000000 --- a/app/assets/images/emoji/face_palm_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/face_palm_tone5.png b/app/assets/images/emoji/face_palm_tone5.png Binary files differdeleted file mode 100644 index 6f070db98be..00000000000 --- a/app/assets/images/emoji/face_palm_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/factory.png b/app/assets/images/emoji/factory.png Binary files differdeleted file mode 100644 index e1d2ddf4a27..00000000000 --- a/app/assets/images/emoji/factory.png +++ /dev/null diff --git a/app/assets/images/emoji/fallen_leaf.png b/app/assets/images/emoji/fallen_leaf.png Binary files differdeleted file mode 100644 index 0d60e7bdf2d..00000000000 --- a/app/assets/images/emoji/fallen_leaf.png +++ /dev/null diff --git a/app/assets/images/emoji/family.png b/app/assets/images/emoji/family.png Binary files differdeleted file mode 100644 index 26421965791..00000000000 --- a/app/assets/images/emoji/family.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mmb.png b/app/assets/images/emoji/family_mmb.png Binary files differdeleted file mode 100644 index 7a2e4e2c491..00000000000 --- a/app/assets/images/emoji/family_mmb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mmbb.png b/app/assets/images/emoji/family_mmbb.png Binary files differdeleted file mode 100644 index 81e6c0fc0ee..00000000000 --- a/app/assets/images/emoji/family_mmbb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mmg.png b/app/assets/images/emoji/family_mmg.png Binary files differdeleted file mode 100644 index 932a85e1fe5..00000000000 --- a/app/assets/images/emoji/family_mmg.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mmgb.png b/app/assets/images/emoji/family_mmgb.png Binary files differdeleted file mode 100644 index 41e35166670..00000000000 --- a/app/assets/images/emoji/family_mmgb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mmgg.png b/app/assets/images/emoji/family_mmgg.png Binary files differdeleted file mode 100644 index 8e8ccfe6c7f..00000000000 --- a/app/assets/images/emoji/family_mmgg.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mwbb.png b/app/assets/images/emoji/family_mwbb.png Binary files differdeleted file mode 100644 index b544fbe573f..00000000000 --- a/app/assets/images/emoji/family_mwbb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mwg.png b/app/assets/images/emoji/family_mwg.png Binary files differdeleted file mode 100644 index 71d2681c32a..00000000000 --- a/app/assets/images/emoji/family_mwg.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mwgb.png b/app/assets/images/emoji/family_mwgb.png Binary files differdeleted file mode 100644 index 40dbf1f7a18..00000000000 --- a/app/assets/images/emoji/family_mwgb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_mwgg.png b/app/assets/images/emoji/family_mwgg.png Binary files differdeleted file mode 100644 index bfefa4879cb..00000000000 --- a/app/assets/images/emoji/family_mwgg.png +++ /dev/null diff --git a/app/assets/images/emoji/family_wwb.png b/app/assets/images/emoji/family_wwb.png Binary files differdeleted file mode 100644 index 836feae7c78..00000000000 --- a/app/assets/images/emoji/family_wwb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_wwbb.png b/app/assets/images/emoji/family_wwbb.png Binary files differdeleted file mode 100644 index 6c6ba45e7bb..00000000000 --- a/app/assets/images/emoji/family_wwbb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_wwg.png b/app/assets/images/emoji/family_wwg.png Binary files differdeleted file mode 100644 index 41225c6fa5a..00000000000 --- a/app/assets/images/emoji/family_wwg.png +++ /dev/null diff --git a/app/assets/images/emoji/family_wwgb.png b/app/assets/images/emoji/family_wwgb.png Binary files differdeleted file mode 100644 index 284d29ab5da..00000000000 --- a/app/assets/images/emoji/family_wwgb.png +++ /dev/null diff --git a/app/assets/images/emoji/family_wwgg.png b/app/assets/images/emoji/family_wwgg.png Binary files differdeleted file mode 100644 index d8d3f49b85f..00000000000 --- a/app/assets/images/emoji/family_wwgg.png +++ /dev/null diff --git a/app/assets/images/emoji/fast_forward.png b/app/assets/images/emoji/fast_forward.png Binary files differdeleted file mode 100644 index c406fedfdb1..00000000000 --- a/app/assets/images/emoji/fast_forward.png +++ /dev/null diff --git a/app/assets/images/emoji/fax.png b/app/assets/images/emoji/fax.png Binary files differdeleted file mode 100644 index 6f929e294c2..00000000000 --- a/app/assets/images/emoji/fax.png +++ /dev/null diff --git a/app/assets/images/emoji/fearful.png b/app/assets/images/emoji/fearful.png Binary files differdeleted file mode 100644 index eb8b347cef9..00000000000 --- a/app/assets/images/emoji/fearful.png +++ /dev/null diff --git a/app/assets/images/emoji/feet.png b/app/assets/images/emoji/feet.png Binary files differdeleted file mode 100644 index 5fe568cee93..00000000000 --- a/app/assets/images/emoji/feet.png +++ /dev/null diff --git a/app/assets/images/emoji/fencer.png b/app/assets/images/emoji/fencer.png Binary files differdeleted file mode 100644 index 5288c920eb9..00000000000 --- a/app/assets/images/emoji/fencer.png +++ /dev/null diff --git a/app/assets/images/emoji/ferris_wheel.png b/app/assets/images/emoji/ferris_wheel.png Binary files differdeleted file mode 100644 index 55c8ff0475b..00000000000 --- a/app/assets/images/emoji/ferris_wheel.png +++ /dev/null diff --git a/app/assets/images/emoji/ferry.png b/app/assets/images/emoji/ferry.png Binary files differdeleted file mode 100644 index 41816b3ae34..00000000000 --- a/app/assets/images/emoji/ferry.png +++ /dev/null diff --git a/app/assets/images/emoji/field_hockey.png b/app/assets/images/emoji/field_hockey.png Binary files differdeleted file mode 100644 index 839637716ee..00000000000 --- a/app/assets/images/emoji/field_hockey.png +++ /dev/null diff --git a/app/assets/images/emoji/file_cabinet.png b/app/assets/images/emoji/file_cabinet.png Binary files differdeleted file mode 100644 index fddc65dde96..00000000000 --- a/app/assets/images/emoji/file_cabinet.png +++ /dev/null diff --git a/app/assets/images/emoji/file_folder.png b/app/assets/images/emoji/file_folder.png Binary files differdeleted file mode 100644 index addedaf0870..00000000000 --- a/app/assets/images/emoji/file_folder.png +++ /dev/null diff --git a/app/assets/images/emoji/film_frames.png b/app/assets/images/emoji/film_frames.png Binary files differdeleted file mode 100644 index 30143aedbe6..00000000000 --- a/app/assets/images/emoji/film_frames.png +++ /dev/null diff --git a/app/assets/images/emoji/fingers_crossed.png b/app/assets/images/emoji/fingers_crossed.png Binary files differdeleted file mode 100644 index 4cd18514ea3..00000000000 --- a/app/assets/images/emoji/fingers_crossed.png +++ /dev/null diff --git a/app/assets/images/emoji/fingers_crossed_tone1.png b/app/assets/images/emoji/fingers_crossed_tone1.png Binary files differdeleted file mode 100644 index dd2384a6cd5..00000000000 --- a/app/assets/images/emoji/fingers_crossed_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/fingers_crossed_tone2.png b/app/assets/images/emoji/fingers_crossed_tone2.png Binary files differdeleted file mode 100644 index 6228401befe..00000000000 --- a/app/assets/images/emoji/fingers_crossed_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/fingers_crossed_tone3.png b/app/assets/images/emoji/fingers_crossed_tone3.png Binary files differdeleted file mode 100644 index b1074da15f5..00000000000 --- a/app/assets/images/emoji/fingers_crossed_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/fingers_crossed_tone4.png b/app/assets/images/emoji/fingers_crossed_tone4.png Binary files differdeleted file mode 100644 index 75e05e4d332..00000000000 --- a/app/assets/images/emoji/fingers_crossed_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/fingers_crossed_tone5.png b/app/assets/images/emoji/fingers_crossed_tone5.png Binary files differdeleted file mode 100644 index 761aebdc30f..00000000000 --- a/app/assets/images/emoji/fingers_crossed_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/fire.png b/app/assets/images/emoji/fire.png Binary files differdeleted file mode 100644 index bd3775a460b..00000000000 --- a/app/assets/images/emoji/fire.png +++ /dev/null diff --git a/app/assets/images/emoji/fire_engine.png b/app/assets/images/emoji/fire_engine.png Binary files differdeleted file mode 100644 index 2cd45b7cf7e..00000000000 --- a/app/assets/images/emoji/fire_engine.png +++ /dev/null diff --git a/app/assets/images/emoji/fireworks.png b/app/assets/images/emoji/fireworks.png Binary files differdeleted file mode 100644 index 176c8b58265..00000000000 --- a/app/assets/images/emoji/fireworks.png +++ /dev/null diff --git a/app/assets/images/emoji/first_place.png b/app/assets/images/emoji/first_place.png Binary files differdeleted file mode 100644 index 15612b66492..00000000000 --- a/app/assets/images/emoji/first_place.png +++ /dev/null diff --git a/app/assets/images/emoji/first_quarter_moon.png b/app/assets/images/emoji/first_quarter_moon.png Binary files differdeleted file mode 100644 index 5dccaf72a4f..00000000000 --- a/app/assets/images/emoji/first_quarter_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/first_quarter_moon_with_face.png b/app/assets/images/emoji/first_quarter_moon_with_face.png Binary files differdeleted file mode 100644 index cd8a3d7acd8..00000000000 --- a/app/assets/images/emoji/first_quarter_moon_with_face.png +++ /dev/null diff --git a/app/assets/images/emoji/fish.png b/app/assets/images/emoji/fish.png Binary files differdeleted file mode 100644 index c2d2faaacd4..00000000000 --- a/app/assets/images/emoji/fish.png +++ /dev/null diff --git a/app/assets/images/emoji/fish_cake.png b/app/assets/images/emoji/fish_cake.png Binary files differdeleted file mode 100644 index 157bded65db..00000000000 --- a/app/assets/images/emoji/fish_cake.png +++ /dev/null diff --git a/app/assets/images/emoji/fishing_pole_and_fish.png b/app/assets/images/emoji/fishing_pole_and_fish.png Binary files differdeleted file mode 100644 index dfcdf07eb50..00000000000 --- a/app/assets/images/emoji/fishing_pole_and_fish.png +++ /dev/null diff --git a/app/assets/images/emoji/fist.png b/app/assets/images/emoji/fist.png Binary files differdeleted file mode 100644 index de33592bf98..00000000000 --- a/app/assets/images/emoji/fist.png +++ /dev/null diff --git a/app/assets/images/emoji/fist_tone1.png b/app/assets/images/emoji/fist_tone1.png Binary files differdeleted file mode 100644 index 02809e2dd68..00000000000 --- a/app/assets/images/emoji/fist_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/fist_tone2.png b/app/assets/images/emoji/fist_tone2.png Binary files differdeleted file mode 100644 index 5de34810383..00000000000 --- a/app/assets/images/emoji/fist_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/fist_tone3.png b/app/assets/images/emoji/fist_tone3.png Binary files differdeleted file mode 100644 index 0d5240129b1..00000000000 --- a/app/assets/images/emoji/fist_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/fist_tone4.png b/app/assets/images/emoji/fist_tone4.png Binary files differdeleted file mode 100644 index a95c0dd634b..00000000000 --- a/app/assets/images/emoji/fist_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/fist_tone5.png b/app/assets/images/emoji/fist_tone5.png Binary files differdeleted file mode 100644 index a2f092fd8c7..00000000000 --- a/app/assets/images/emoji/fist_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/five.png b/app/assets/images/emoji/five.png Binary files differdeleted file mode 100644 index d14371f3f27..00000000000 --- a/app/assets/images/emoji/five.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ac.png b/app/assets/images/emoji/flag_ac.png Binary files differdeleted file mode 100644 index 286239920c7..00000000000 --- a/app/assets/images/emoji/flag_ac.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ad.png b/app/assets/images/emoji/flag_ad.png Binary files differdeleted file mode 100644 index 20f4b14e8ad..00000000000 --- a/app/assets/images/emoji/flag_ad.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ae.png b/app/assets/images/emoji/flag_ae.png Binary files differdeleted file mode 100644 index d16ffe4b862..00000000000 --- a/app/assets/images/emoji/flag_ae.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_af.png b/app/assets/images/emoji/flag_af.png Binary files differdeleted file mode 100644 index a51533b554d..00000000000 --- a/app/assets/images/emoji/flag_af.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ag.png b/app/assets/images/emoji/flag_ag.png Binary files differdeleted file mode 100644 index 07f2ce397d0..00000000000 --- a/app/assets/images/emoji/flag_ag.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ai.png b/app/assets/images/emoji/flag_ai.png Binary files differdeleted file mode 100644 index 500b5ab09fb..00000000000 --- a/app/assets/images/emoji/flag_ai.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_al.png b/app/assets/images/emoji/flag_al.png Binary files differdeleted file mode 100644 index 03a20132cc6..00000000000 --- a/app/assets/images/emoji/flag_al.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_am.png b/app/assets/images/emoji/flag_am.png Binary files differdeleted file mode 100644 index 2ad60a273ec..00000000000 --- a/app/assets/images/emoji/flag_am.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ao.png b/app/assets/images/emoji/flag_ao.png Binary files differdeleted file mode 100644 index cb46c31f862..00000000000 --- a/app/assets/images/emoji/flag_ao.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_aq.png b/app/assets/images/emoji/flag_aq.png Binary files differdeleted file mode 100644 index b272021d375..00000000000 --- a/app/assets/images/emoji/flag_aq.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ar.png b/app/assets/images/emoji/flag_ar.png Binary files differdeleted file mode 100644 index 73136caf3b7..00000000000 --- a/app/assets/images/emoji/flag_ar.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_as.png b/app/assets/images/emoji/flag_as.png Binary files differdeleted file mode 100644 index 3db45a0d9f3..00000000000 --- a/app/assets/images/emoji/flag_as.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_at.png b/app/assets/images/emoji/flag_at.png Binary files differdeleted file mode 100644 index c43769dcb19..00000000000 --- a/app/assets/images/emoji/flag_at.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_au.png b/app/assets/images/emoji/flag_au.png Binary files differdeleted file mode 100644 index 7794309c78c..00000000000 --- a/app/assets/images/emoji/flag_au.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_aw.png b/app/assets/images/emoji/flag_aw.png Binary files differdeleted file mode 100644 index 02c840d12c9..00000000000 --- a/app/assets/images/emoji/flag_aw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ax.png b/app/assets/images/emoji/flag_ax.png Binary files differdeleted file mode 100644 index fc5466174bb..00000000000 --- a/app/assets/images/emoji/flag_ax.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_az.png b/app/assets/images/emoji/flag_az.png Binary files differdeleted file mode 100644 index 89d3d15fd9f..00000000000 --- a/app/assets/images/emoji/flag_az.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ba.png b/app/assets/images/emoji/flag_ba.png Binary files differdeleted file mode 100644 index 25fe407e13c..00000000000 --- a/app/assets/images/emoji/flag_ba.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bb.png b/app/assets/images/emoji/flag_bb.png Binary files differdeleted file mode 100644 index bccd8c5c9b0..00000000000 --- a/app/assets/images/emoji/flag_bb.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bd.png b/app/assets/images/emoji/flag_bd.png Binary files differdeleted file mode 100644 index b0597a3149b..00000000000 --- a/app/assets/images/emoji/flag_bd.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_be.png b/app/assets/images/emoji/flag_be.png Binary files differdeleted file mode 100644 index 551f086e3c4..00000000000 --- a/app/assets/images/emoji/flag_be.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bf.png b/app/assets/images/emoji/flag_bf.png Binary files differdeleted file mode 100644 index 444d4829f94..00000000000 --- a/app/assets/images/emoji/flag_bf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bg.png b/app/assets/images/emoji/flag_bg.png Binary files differdeleted file mode 100644 index 821eee5e170..00000000000 --- a/app/assets/images/emoji/flag_bg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bh.png b/app/assets/images/emoji/flag_bh.png Binary files differdeleted file mode 100644 index f33724249f0..00000000000 --- a/app/assets/images/emoji/flag_bh.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bi.png b/app/assets/images/emoji/flag_bi.png Binary files differdeleted file mode 100644 index ea20ac93211..00000000000 --- a/app/assets/images/emoji/flag_bi.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bj.png b/app/assets/images/emoji/flag_bj.png Binary files differdeleted file mode 100644 index 7cca4f80457..00000000000 --- a/app/assets/images/emoji/flag_bj.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bl.png b/app/assets/images/emoji/flag_bl.png Binary files differdeleted file mode 100644 index 1082e78999f..00000000000 --- a/app/assets/images/emoji/flag_bl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_black.png b/app/assets/images/emoji/flag_black.png Binary files differdeleted file mode 100644 index 0e28d05d5ac..00000000000 --- a/app/assets/images/emoji/flag_black.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bm.png b/app/assets/images/emoji/flag_bm.png Binary files differdeleted file mode 100644 index ab8cafdac63..00000000000 --- a/app/assets/images/emoji/flag_bm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bn.png b/app/assets/images/emoji/flag_bn.png Binary files differdeleted file mode 100644 index caa9329a896..00000000000 --- a/app/assets/images/emoji/flag_bn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bo.png b/app/assets/images/emoji/flag_bo.png Binary files differdeleted file mode 100644 index 98af62b3da7..00000000000 --- a/app/assets/images/emoji/flag_bo.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bq.png b/app/assets/images/emoji/flag_bq.png Binary files differdeleted file mode 100644 index cb978ef9de9..00000000000 --- a/app/assets/images/emoji/flag_bq.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_br.png b/app/assets/images/emoji/flag_br.png Binary files differdeleted file mode 100644 index b139366a42b..00000000000 --- a/app/assets/images/emoji/flag_br.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bs.png b/app/assets/images/emoji/flag_bs.png Binary files differdeleted file mode 100644 index d36bcd2fb52..00000000000 --- a/app/assets/images/emoji/flag_bs.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bt.png b/app/assets/images/emoji/flag_bt.png Binary files differdeleted file mode 100644 index ed57aa0360e..00000000000 --- a/app/assets/images/emoji/flag_bt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bv.png b/app/assets/images/emoji/flag_bv.png Binary files differdeleted file mode 100644 index 5884e648228..00000000000 --- a/app/assets/images/emoji/flag_bv.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bw.png b/app/assets/images/emoji/flag_bw.png Binary files differdeleted file mode 100644 index cb12f34739d..00000000000 --- a/app/assets/images/emoji/flag_bw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_by.png b/app/assets/images/emoji/flag_by.png Binary files differdeleted file mode 100644 index 859c05beb13..00000000000 --- a/app/assets/images/emoji/flag_by.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_bz.png b/app/assets/images/emoji/flag_bz.png Binary files differdeleted file mode 100644 index 34761cd03d8..00000000000 --- a/app/assets/images/emoji/flag_bz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ca.png b/app/assets/images/emoji/flag_ca.png Binary files differdeleted file mode 100644 index 7c5b390e85b..00000000000 --- a/app/assets/images/emoji/flag_ca.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cc.png b/app/assets/images/emoji/flag_cc.png Binary files differdeleted file mode 100644 index b6555a23d83..00000000000 --- a/app/assets/images/emoji/flag_cc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cd.png b/app/assets/images/emoji/flag_cd.png Binary files differdeleted file mode 100644 index fa92009771d..00000000000 --- a/app/assets/images/emoji/flag_cd.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cf.png b/app/assets/images/emoji/flag_cf.png Binary files differdeleted file mode 100644 index b969ae29ea9..00000000000 --- a/app/assets/images/emoji/flag_cf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cg.png b/app/assets/images/emoji/flag_cg.png Binary files differdeleted file mode 100644 index 3a38a40a95e..00000000000 --- a/app/assets/images/emoji/flag_cg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ch.png b/app/assets/images/emoji/flag_ch.png Binary files differdeleted file mode 100644 index 5ff86b8a3b7..00000000000 --- a/app/assets/images/emoji/flag_ch.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ci.png b/app/assets/images/emoji/flag_ci.png Binary files differdeleted file mode 100644 index e3b4d15c7f1..00000000000 --- a/app/assets/images/emoji/flag_ci.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ck.png b/app/assets/images/emoji/flag_ck.png Binary files differdeleted file mode 100644 index b6b53dbc1c4..00000000000 --- a/app/assets/images/emoji/flag_ck.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cl.png b/app/assets/images/emoji/flag_cl.png Binary files differdeleted file mode 100644 index c9390da5499..00000000000 --- a/app/assets/images/emoji/flag_cl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cm.png b/app/assets/images/emoji/flag_cm.png Binary files differdeleted file mode 100644 index 2d3f6ec4518..00000000000 --- a/app/assets/images/emoji/flag_cm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cn.png b/app/assets/images/emoji/flag_cn.png Binary files differdeleted file mode 100644 index 0a7f350a6d2..00000000000 --- a/app/assets/images/emoji/flag_cn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_co.png b/app/assets/images/emoji/flag_co.png Binary files differdeleted file mode 100644 index 7e0f5e0dc3c..00000000000 --- a/app/assets/images/emoji/flag_co.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cp.png b/app/assets/images/emoji/flag_cp.png Binary files differdeleted file mode 100644 index 70c761036bd..00000000000 --- a/app/assets/images/emoji/flag_cp.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cr.png b/app/assets/images/emoji/flag_cr.png Binary files differdeleted file mode 100644 index a5fce126515..00000000000 --- a/app/assets/images/emoji/flag_cr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cu.png b/app/assets/images/emoji/flag_cu.png Binary files differdeleted file mode 100644 index 447328f7dfd..00000000000 --- a/app/assets/images/emoji/flag_cu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cv.png b/app/assets/images/emoji/flag_cv.png Binary files differdeleted file mode 100644 index 43faf4d64d5..00000000000 --- a/app/assets/images/emoji/flag_cv.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cw.png b/app/assets/images/emoji/flag_cw.png Binary files differdeleted file mode 100644 index eb39e8d0078..00000000000 --- a/app/assets/images/emoji/flag_cw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cx.png b/app/assets/images/emoji/flag_cx.png Binary files differdeleted file mode 100644 index 09d21359f3a..00000000000 --- a/app/assets/images/emoji/flag_cx.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cy.png b/app/assets/images/emoji/flag_cy.png Binary files differdeleted file mode 100644 index 154a7aa3176..00000000000 --- a/app/assets/images/emoji/flag_cy.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_cz.png b/app/assets/images/emoji/flag_cz.png Binary files differdeleted file mode 100644 index 9737ca223c7..00000000000 --- a/app/assets/images/emoji/flag_cz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_de.png b/app/assets/images/emoji/flag_de.png Binary files differdeleted file mode 100644 index 98ed76b3bab..00000000000 --- a/app/assets/images/emoji/flag_de.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_dg.png b/app/assets/images/emoji/flag_dg.png Binary files differdeleted file mode 100644 index aae927d14b8..00000000000 --- a/app/assets/images/emoji/flag_dg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_dj.png b/app/assets/images/emoji/flag_dj.png Binary files differdeleted file mode 100644 index 73c2a2acbd9..00000000000 --- a/app/assets/images/emoji/flag_dj.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_dk.png b/app/assets/images/emoji/flag_dk.png Binary files differdeleted file mode 100644 index e5a60b06256..00000000000 --- a/app/assets/images/emoji/flag_dk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_dm.png b/app/assets/images/emoji/flag_dm.png Binary files differdeleted file mode 100644 index 50f8a53981d..00000000000 --- a/app/assets/images/emoji/flag_dm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_do.png b/app/assets/images/emoji/flag_do.png Binary files differdeleted file mode 100644 index 037a45d7c26..00000000000 --- a/app/assets/images/emoji/flag_do.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_dz.png b/app/assets/images/emoji/flag_dz.png Binary files differdeleted file mode 100644 index 24945b10f2d..00000000000 --- a/app/assets/images/emoji/flag_dz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ea.png b/app/assets/images/emoji/flag_ea.png Binary files differdeleted file mode 100644 index 356ff347838..00000000000 --- a/app/assets/images/emoji/flag_ea.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ec.png b/app/assets/images/emoji/flag_ec.png Binary files differdeleted file mode 100644 index 13814594619..00000000000 --- a/app/assets/images/emoji/flag_ec.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ee.png b/app/assets/images/emoji/flag_ee.png Binary files differdeleted file mode 100644 index 84f317e7747..00000000000 --- a/app/assets/images/emoji/flag_ee.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_eg.png b/app/assets/images/emoji/flag_eg.png Binary files differdeleted file mode 100644 index 57786064a95..00000000000 --- a/app/assets/images/emoji/flag_eg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_eh.png b/app/assets/images/emoji/flag_eh.png Binary files differdeleted file mode 100644 index 4d7a76687f6..00000000000 --- a/app/assets/images/emoji/flag_eh.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_er.png b/app/assets/images/emoji/flag_er.png Binary files differdeleted file mode 100644 index 0c3c724c1fb..00000000000 --- a/app/assets/images/emoji/flag_er.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_es.png b/app/assets/images/emoji/flag_es.png Binary files differdeleted file mode 100644 index 3e73597a225..00000000000 --- a/app/assets/images/emoji/flag_es.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_et.png b/app/assets/images/emoji/flag_et.png Binary files differdeleted file mode 100644 index 9560a134c97..00000000000 --- a/app/assets/images/emoji/flag_et.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_eu.png b/app/assets/images/emoji/flag_eu.png Binary files differdeleted file mode 100644 index 0b456cf3330..00000000000 --- a/app/assets/images/emoji/flag_eu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_fi.png b/app/assets/images/emoji/flag_fi.png Binary files differdeleted file mode 100644 index ebcf58abfc5..00000000000 --- a/app/assets/images/emoji/flag_fi.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_fj.png b/app/assets/images/emoji/flag_fj.png Binary files differdeleted file mode 100644 index 9cc8c37fe37..00000000000 --- a/app/assets/images/emoji/flag_fj.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_fk.png b/app/assets/images/emoji/flag_fk.png Binary files differdeleted file mode 100644 index 61372fd2549..00000000000 --- a/app/assets/images/emoji/flag_fk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_fm.png b/app/assets/images/emoji/flag_fm.png Binary files differdeleted file mode 100644 index 0889825c8e1..00000000000 --- a/app/assets/images/emoji/flag_fm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_fo.png b/app/assets/images/emoji/flag_fo.png Binary files differdeleted file mode 100644 index 9a4431b0831..00000000000 --- a/app/assets/images/emoji/flag_fo.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_fr.png b/app/assets/images/emoji/flag_fr.png Binary files differdeleted file mode 100644 index 62ca19c3fcf..00000000000 --- a/app/assets/images/emoji/flag_fr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ga.png b/app/assets/images/emoji/flag_ga.png Binary files differdeleted file mode 100644 index 2e68e527a3e..00000000000 --- a/app/assets/images/emoji/flag_ga.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gb.png b/app/assets/images/emoji/flag_gb.png Binary files differdeleted file mode 100644 index 3ed10f62347..00000000000 --- a/app/assets/images/emoji/flag_gb.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gd.png b/app/assets/images/emoji/flag_gd.png Binary files differdeleted file mode 100644 index 527aad33807..00000000000 --- a/app/assets/images/emoji/flag_gd.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ge.png b/app/assets/images/emoji/flag_ge.png Binary files differdeleted file mode 100644 index a75d142480d..00000000000 --- a/app/assets/images/emoji/flag_ge.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gf.png b/app/assets/images/emoji/flag_gf.png Binary files differdeleted file mode 100644 index 0cf96f327c0..00000000000 --- a/app/assets/images/emoji/flag_gf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gg.png b/app/assets/images/emoji/flag_gg.png Binary files differdeleted file mode 100644 index 970002c7f76..00000000000 --- a/app/assets/images/emoji/flag_gg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gh.png b/app/assets/images/emoji/flag_gh.png Binary files differdeleted file mode 100644 index f31b5eb7b45..00000000000 --- a/app/assets/images/emoji/flag_gh.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gi.png b/app/assets/images/emoji/flag_gi.png Binary files differdeleted file mode 100644 index e554a2a1d0c..00000000000 --- a/app/assets/images/emoji/flag_gi.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gl.png b/app/assets/images/emoji/flag_gl.png Binary files differdeleted file mode 100644 index 2e795dd4e33..00000000000 --- a/app/assets/images/emoji/flag_gl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gm.png b/app/assets/images/emoji/flag_gm.png Binary files differdeleted file mode 100644 index bb69c0975a3..00000000000 --- a/app/assets/images/emoji/flag_gm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gn.png b/app/assets/images/emoji/flag_gn.png Binary files differdeleted file mode 100644 index 1981f61dbf5..00000000000 --- a/app/assets/images/emoji/flag_gn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gp.png b/app/assets/images/emoji/flag_gp.png Binary files differdeleted file mode 100644 index 10e42e672bd..00000000000 --- a/app/assets/images/emoji/flag_gp.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gq.png b/app/assets/images/emoji/flag_gq.png Binary files differdeleted file mode 100644 index 11475e61eeb..00000000000 --- a/app/assets/images/emoji/flag_gq.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gr.png b/app/assets/images/emoji/flag_gr.png Binary files differdeleted file mode 100644 index 0f6bb1b6b94..00000000000 --- a/app/assets/images/emoji/flag_gr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gs.png b/app/assets/images/emoji/flag_gs.png Binary files differdeleted file mode 100644 index 6fc92780453..00000000000 --- a/app/assets/images/emoji/flag_gs.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gt.png b/app/assets/images/emoji/flag_gt.png Binary files differdeleted file mode 100644 index 7213d4139ed..00000000000 --- a/app/assets/images/emoji/flag_gt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gu.png b/app/assets/images/emoji/flag_gu.png Binary files differdeleted file mode 100644 index 4027549ca3c..00000000000 --- a/app/assets/images/emoji/flag_gu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gw.png b/app/assets/images/emoji/flag_gw.png Binary files differdeleted file mode 100644 index 6357f6225f4..00000000000 --- a/app/assets/images/emoji/flag_gw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_gy.png b/app/assets/images/emoji/flag_gy.png Binary files differdeleted file mode 100644 index 746e2fb7e44..00000000000 --- a/app/assets/images/emoji/flag_gy.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_hk.png b/app/assets/images/emoji/flag_hk.png Binary files differdeleted file mode 100644 index cf0c7151b56..00000000000 --- a/app/assets/images/emoji/flag_hk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_hm.png b/app/assets/images/emoji/flag_hm.png Binary files differdeleted file mode 100644 index b613509e466..00000000000 --- a/app/assets/images/emoji/flag_hm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_hn.png b/app/assets/images/emoji/flag_hn.png Binary files differdeleted file mode 100644 index 402cdcefdf8..00000000000 --- a/app/assets/images/emoji/flag_hn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_hr.png b/app/assets/images/emoji/flag_hr.png Binary files differdeleted file mode 100644 index 46f4f06b4f2..00000000000 --- a/app/assets/images/emoji/flag_hr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ht.png b/app/assets/images/emoji/flag_ht.png Binary files differdeleted file mode 100644 index d8d0c888498..00000000000 --- a/app/assets/images/emoji/flag_ht.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_hu.png b/app/assets/images/emoji/flag_hu.png Binary files differdeleted file mode 100644 index a898de636a5..00000000000 --- a/app/assets/images/emoji/flag_hu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ic.png b/app/assets/images/emoji/flag_ic.png Binary files differdeleted file mode 100644 index 69fd990aa95..00000000000 --- a/app/assets/images/emoji/flag_ic.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_id.png b/app/assets/images/emoji/flag_id.png Binary files differdeleted file mode 100644 index 85b4c063a45..00000000000 --- a/app/assets/images/emoji/flag_id.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ie.png b/app/assets/images/emoji/flag_ie.png Binary files differdeleted file mode 100644 index a28295838cc..00000000000 --- a/app/assets/images/emoji/flag_ie.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_il.png b/app/assets/images/emoji/flag_il.png Binary files differdeleted file mode 100644 index 85c410d45fb..00000000000 --- a/app/assets/images/emoji/flag_il.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_im.png b/app/assets/images/emoji/flag_im.png Binary files differdeleted file mode 100644 index 60a2458e38e..00000000000 --- a/app/assets/images/emoji/flag_im.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_in.png b/app/assets/images/emoji/flag_in.png Binary files differdeleted file mode 100644 index feccc8952ce..00000000000 --- a/app/assets/images/emoji/flag_in.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_io.png b/app/assets/images/emoji/flag_io.png Binary files differdeleted file mode 100644 index aae927d14b8..00000000000 --- a/app/assets/images/emoji/flag_io.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_iq.png b/app/assets/images/emoji/flag_iq.png Binary files differdeleted file mode 100644 index 41fd1db6f86..00000000000 --- a/app/assets/images/emoji/flag_iq.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ir.png b/app/assets/images/emoji/flag_ir.png Binary files differdeleted file mode 100644 index ff7aaf62ba6..00000000000 --- a/app/assets/images/emoji/flag_ir.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_is.png b/app/assets/images/emoji/flag_is.png Binary files differdeleted file mode 100644 index ad8d4131dd2..00000000000 --- a/app/assets/images/emoji/flag_is.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_it.png b/app/assets/images/emoji/flag_it.png Binary files differdeleted file mode 100644 index f21563ec533..00000000000 --- a/app/assets/images/emoji/flag_it.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_je.png b/app/assets/images/emoji/flag_je.png Binary files differdeleted file mode 100644 index 198a918f6a4..00000000000 --- a/app/assets/images/emoji/flag_je.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_jm.png b/app/assets/images/emoji/flag_jm.png Binary files differdeleted file mode 100644 index f84e4f9e8db..00000000000 --- a/app/assets/images/emoji/flag_jm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_jo.png b/app/assets/images/emoji/flag_jo.png Binary files differdeleted file mode 100644 index 20bfa147e3e..00000000000 --- a/app/assets/images/emoji/flag_jo.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_jp.png b/app/assets/images/emoji/flag_jp.png Binary files differdeleted file mode 100644 index 8d8838e4708..00000000000 --- a/app/assets/images/emoji/flag_jp.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ke.png b/app/assets/images/emoji/flag_ke.png Binary files differdeleted file mode 100644 index 9e417ab3009..00000000000 --- a/app/assets/images/emoji/flag_ke.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kg.png b/app/assets/images/emoji/flag_kg.png Binary files differdeleted file mode 100644 index 2f2d848fe58..00000000000 --- a/app/assets/images/emoji/flag_kg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kh.png b/app/assets/images/emoji/flag_kh.png Binary files differdeleted file mode 100644 index 9a2877dd620..00000000000 --- a/app/assets/images/emoji/flag_kh.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ki.png b/app/assets/images/emoji/flag_ki.png Binary files differdeleted file mode 100644 index 10e507e3245..00000000000 --- a/app/assets/images/emoji/flag_ki.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_km.png b/app/assets/images/emoji/flag_km.png Binary files differdeleted file mode 100644 index bd5a0588e03..00000000000 --- a/app/assets/images/emoji/flag_km.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kn.png b/app/assets/images/emoji/flag_kn.png Binary files differdeleted file mode 100644 index 776207c9605..00000000000 --- a/app/assets/images/emoji/flag_kn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kp.png b/app/assets/images/emoji/flag_kp.png Binary files differdeleted file mode 100644 index 6b3fd89eaaa..00000000000 --- a/app/assets/images/emoji/flag_kp.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kr.png b/app/assets/images/emoji/flag_kr.png Binary files differdeleted file mode 100644 index 833a88116e1..00000000000 --- a/app/assets/images/emoji/flag_kr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kw.png b/app/assets/images/emoji/flag_kw.png Binary files differdeleted file mode 100644 index 4d19bfa6ca7..00000000000 --- a/app/assets/images/emoji/flag_kw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ky.png b/app/assets/images/emoji/flag_ky.png Binary files differdeleted file mode 100644 index 40daa4da597..00000000000 --- a/app/assets/images/emoji/flag_ky.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_kz.png b/app/assets/images/emoji/flag_kz.png Binary files differdeleted file mode 100644 index 2f97a8fd3c6..00000000000 --- a/app/assets/images/emoji/flag_kz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_la.png b/app/assets/images/emoji/flag_la.png Binary files differdeleted file mode 100644 index 4d4179f34f6..00000000000 --- a/app/assets/images/emoji/flag_la.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lb.png b/app/assets/images/emoji/flag_lb.png Binary files differdeleted file mode 100644 index 3d594467011..00000000000 --- a/app/assets/images/emoji/flag_lb.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lc.png b/app/assets/images/emoji/flag_lc.png Binary files differdeleted file mode 100644 index 45547b1e439..00000000000 --- a/app/assets/images/emoji/flag_lc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_li.png b/app/assets/images/emoji/flag_li.png Binary files differdeleted file mode 100644 index 0eafa6a2215..00000000000 --- a/app/assets/images/emoji/flag_li.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lk.png b/app/assets/images/emoji/flag_lk.png Binary files differdeleted file mode 100644 index ab4fe10c40c..00000000000 --- a/app/assets/images/emoji/flag_lk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lr.png b/app/assets/images/emoji/flag_lr.png Binary files differdeleted file mode 100644 index f66f267fea2..00000000000 --- a/app/assets/images/emoji/flag_lr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ls.png b/app/assets/images/emoji/flag_ls.png Binary files differdeleted file mode 100644 index 24745631e3c..00000000000 --- a/app/assets/images/emoji/flag_ls.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lt.png b/app/assets/images/emoji/flag_lt.png Binary files differdeleted file mode 100644 index d644b56d62a..00000000000 --- a/app/assets/images/emoji/flag_lt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lu.png b/app/assets/images/emoji/flag_lu.png Binary files differdeleted file mode 100644 index a2df9c92994..00000000000 --- a/app/assets/images/emoji/flag_lu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_lv.png b/app/assets/images/emoji/flag_lv.png Binary files differdeleted file mode 100644 index ae680d5f0e3..00000000000 --- a/app/assets/images/emoji/flag_lv.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ly.png b/app/assets/images/emoji/flag_ly.png Binary files differdeleted file mode 100644 index f6e77b0f3ba..00000000000 --- a/app/assets/images/emoji/flag_ly.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ma.png b/app/assets/images/emoji/flag_ma.png Binary files differdeleted file mode 100644 index c4a056722cd..00000000000 --- a/app/assets/images/emoji/flag_ma.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mc.png b/app/assets/images/emoji/flag_mc.png Binary files differdeleted file mode 100644 index d479eab98cb..00000000000 --- a/app/assets/images/emoji/flag_mc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_md.png b/app/assets/images/emoji/flag_md.png Binary files differdeleted file mode 100644 index a7a72539872..00000000000 --- a/app/assets/images/emoji/flag_md.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_me.png b/app/assets/images/emoji/flag_me.png Binary files differdeleted file mode 100644 index 7c771e7e120..00000000000 --- a/app/assets/images/emoji/flag_me.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mf.png b/app/assets/images/emoji/flag_mf.png Binary files differdeleted file mode 100644 index 70c761036bd..00000000000 --- a/app/assets/images/emoji/flag_mf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mg.png b/app/assets/images/emoji/flag_mg.png Binary files differdeleted file mode 100644 index 2f3ccdda76f..00000000000 --- a/app/assets/images/emoji/flag_mg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mh.png b/app/assets/images/emoji/flag_mh.png Binary files differdeleted file mode 100644 index 598016481c1..00000000000 --- a/app/assets/images/emoji/flag_mh.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mk.png b/app/assets/images/emoji/flag_mk.png Binary files differdeleted file mode 100644 index 7ba775ee75c..00000000000 --- a/app/assets/images/emoji/flag_mk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ml.png b/app/assets/images/emoji/flag_ml.png Binary files differdeleted file mode 100644 index 68343785468..00000000000 --- a/app/assets/images/emoji/flag_ml.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mm.png b/app/assets/images/emoji/flag_mm.png Binary files differdeleted file mode 100644 index 37dc7d71591..00000000000 --- a/app/assets/images/emoji/flag_mm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mn.png b/app/assets/images/emoji/flag_mn.png Binary files differdeleted file mode 100644 index 1f146bbcd1a..00000000000 --- a/app/assets/images/emoji/flag_mn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mo.png b/app/assets/images/emoji/flag_mo.png Binary files differdeleted file mode 100644 index 7edde31f64b..00000000000 --- a/app/assets/images/emoji/flag_mo.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mp.png b/app/assets/images/emoji/flag_mp.png Binary files differdeleted file mode 100644 index 17ec1c441ed..00000000000 --- a/app/assets/images/emoji/flag_mp.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mq.png b/app/assets/images/emoji/flag_mq.png Binary files differdeleted file mode 100644 index 1e672dc9087..00000000000 --- a/app/assets/images/emoji/flag_mq.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mr.png b/app/assets/images/emoji/flag_mr.png Binary files differdeleted file mode 100644 index f87de46effe..00000000000 --- a/app/assets/images/emoji/flag_mr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ms.png b/app/assets/images/emoji/flag_ms.png Binary files differdeleted file mode 100644 index 480b0d4ebda..00000000000 --- a/app/assets/images/emoji/flag_ms.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mt.png b/app/assets/images/emoji/flag_mt.png Binary files differdeleted file mode 100644 index c9e1dbdce82..00000000000 --- a/app/assets/images/emoji/flag_mt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mu.png b/app/assets/images/emoji/flag_mu.png Binary files differdeleted file mode 100644 index 55b33cb7c33..00000000000 --- a/app/assets/images/emoji/flag_mu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mv.png b/app/assets/images/emoji/flag_mv.png Binary files differdeleted file mode 100644 index ce5867126ae..00000000000 --- a/app/assets/images/emoji/flag_mv.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mw.png b/app/assets/images/emoji/flag_mw.png Binary files differdeleted file mode 100644 index 003d8548401..00000000000 --- a/app/assets/images/emoji/flag_mw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mx.png b/app/assets/images/emoji/flag_mx.png Binary files differdeleted file mode 100644 index 42572bcd0ba..00000000000 --- a/app/assets/images/emoji/flag_mx.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_my.png b/app/assets/images/emoji/flag_my.png Binary files differdeleted file mode 100644 index 17526c26742..00000000000 --- a/app/assets/images/emoji/flag_my.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_mz.png b/app/assets/images/emoji/flag_mz.png Binary files differdeleted file mode 100644 index 2352a78e786..00000000000 --- a/app/assets/images/emoji/flag_mz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_na.png b/app/assets/images/emoji/flag_na.png Binary files differdeleted file mode 100644 index ed31c3df04d..00000000000 --- a/app/assets/images/emoji/flag_na.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_nc.png b/app/assets/images/emoji/flag_nc.png Binary files differdeleted file mode 100644 index 90b3afebfa3..00000000000 --- a/app/assets/images/emoji/flag_nc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ne.png b/app/assets/images/emoji/flag_ne.png Binary files differdeleted file mode 100644 index f98a1173c2a..00000000000 --- a/app/assets/images/emoji/flag_ne.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_nf.png b/app/assets/images/emoji/flag_nf.png Binary files differdeleted file mode 100644 index 9099e767420..00000000000 --- a/app/assets/images/emoji/flag_nf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ng.png b/app/assets/images/emoji/flag_ng.png Binary files differdeleted file mode 100644 index ea0abeff1a1..00000000000 --- a/app/assets/images/emoji/flag_ng.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ni.png b/app/assets/images/emoji/flag_ni.png Binary files differdeleted file mode 100644 index 772920dfa10..00000000000 --- a/app/assets/images/emoji/flag_ni.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_nl.png b/app/assets/images/emoji/flag_nl.png Binary files differdeleted file mode 100644 index 83a0e817e41..00000000000 --- a/app/assets/images/emoji/flag_nl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_no.png b/app/assets/images/emoji/flag_no.png Binary files differdeleted file mode 100644 index 99d3142eb7b..00000000000 --- a/app/assets/images/emoji/flag_no.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_np.png b/app/assets/images/emoji/flag_np.png Binary files differdeleted file mode 100644 index 87425a8dfef..00000000000 --- a/app/assets/images/emoji/flag_np.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_nr.png b/app/assets/images/emoji/flag_nr.png Binary files differdeleted file mode 100644 index b3e3a5d5621..00000000000 --- a/app/assets/images/emoji/flag_nr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_nu.png b/app/assets/images/emoji/flag_nu.png Binary files differdeleted file mode 100644 index f03614443ee..00000000000 --- a/app/assets/images/emoji/flag_nu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_nz.png b/app/assets/images/emoji/flag_nz.png Binary files differdeleted file mode 100644 index a4eeeab9cd9..00000000000 --- a/app/assets/images/emoji/flag_nz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_om.png b/app/assets/images/emoji/flag_om.png Binary files differdeleted file mode 100644 index ea824ba31e7..00000000000 --- a/app/assets/images/emoji/flag_om.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pa.png b/app/assets/images/emoji/flag_pa.png Binary files differdeleted file mode 100644 index c3091d89889..00000000000 --- a/app/assets/images/emoji/flag_pa.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pe.png b/app/assets/images/emoji/flag_pe.png Binary files differdeleted file mode 100644 index 39223aa9dbb..00000000000 --- a/app/assets/images/emoji/flag_pe.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pf.png b/app/assets/images/emoji/flag_pf.png Binary files differdeleted file mode 100644 index 113445f8f6e..00000000000 --- a/app/assets/images/emoji/flag_pf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pg.png b/app/assets/images/emoji/flag_pg.png Binary files differdeleted file mode 100644 index 825e9dcb762..00000000000 --- a/app/assets/images/emoji/flag_pg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ph.png b/app/assets/images/emoji/flag_ph.png Binary files differdeleted file mode 100644 index 8260e15bd2c..00000000000 --- a/app/assets/images/emoji/flag_ph.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pk.png b/app/assets/images/emoji/flag_pk.png Binary files differdeleted file mode 100644 index a7b6a1c5074..00000000000 --- a/app/assets/images/emoji/flag_pk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pl.png b/app/assets/images/emoji/flag_pl.png Binary files differdeleted file mode 100644 index 19de2edec11..00000000000 --- a/app/assets/images/emoji/flag_pl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pm.png b/app/assets/images/emoji/flag_pm.png Binary files differdeleted file mode 100644 index 2ca60554193..00000000000 --- a/app/assets/images/emoji/flag_pm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pn.png b/app/assets/images/emoji/flag_pn.png Binary files differdeleted file mode 100644 index f2263b154bc..00000000000 --- a/app/assets/images/emoji/flag_pn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pr.png b/app/assets/images/emoji/flag_pr.png Binary files differdeleted file mode 100644 index d0209cddb79..00000000000 --- a/app/assets/images/emoji/flag_pr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ps.png b/app/assets/images/emoji/flag_ps.png Binary files differdeleted file mode 100644 index 7ccab09778b..00000000000 --- a/app/assets/images/emoji/flag_ps.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pt.png b/app/assets/images/emoji/flag_pt.png Binary files differdeleted file mode 100644 index cc93f27c64b..00000000000 --- a/app/assets/images/emoji/flag_pt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_pw.png b/app/assets/images/emoji/flag_pw.png Binary files differdeleted file mode 100644 index 154b2f12d3c..00000000000 --- a/app/assets/images/emoji/flag_pw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_py.png b/app/assets/images/emoji/flag_py.png Binary files differdeleted file mode 100644 index 662ad2f6ff1..00000000000 --- a/app/assets/images/emoji/flag_py.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_qa.png b/app/assets/images/emoji/flag_qa.png Binary files differdeleted file mode 100644 index a01d8b05cc7..00000000000 --- a/app/assets/images/emoji/flag_qa.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_re.png b/app/assets/images/emoji/flag_re.png Binary files differdeleted file mode 100644 index 57f2bbe9df8..00000000000 --- a/app/assets/images/emoji/flag_re.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ro.png b/app/assets/images/emoji/flag_ro.png Binary files differdeleted file mode 100644 index 3e48c447706..00000000000 --- a/app/assets/images/emoji/flag_ro.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_rs.png b/app/assets/images/emoji/flag_rs.png Binary files differdeleted file mode 100644 index 9df6c9a5235..00000000000 --- a/app/assets/images/emoji/flag_rs.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ru.png b/app/assets/images/emoji/flag_ru.png Binary files differdeleted file mode 100644 index e50c9db90e7..00000000000 --- a/app/assets/images/emoji/flag_ru.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_rw.png b/app/assets/images/emoji/flag_rw.png Binary files differdeleted file mode 100644 index c238c874e1d..00000000000 --- a/app/assets/images/emoji/flag_rw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sa.png b/app/assets/images/emoji/flag_sa.png Binary files differdeleted file mode 100644 index 4941be7d198..00000000000 --- a/app/assets/images/emoji/flag_sa.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sb.png b/app/assets/images/emoji/flag_sb.png Binary files differdeleted file mode 100644 index 7d8f1ac6130..00000000000 --- a/app/assets/images/emoji/flag_sb.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sc.png b/app/assets/images/emoji/flag_sc.png Binary files differdeleted file mode 100644 index 6ae4d90765e..00000000000 --- a/app/assets/images/emoji/flag_sc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sd.png b/app/assets/images/emoji/flag_sd.png Binary files differdeleted file mode 100644 index 963be1b36fb..00000000000 --- a/app/assets/images/emoji/flag_sd.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_se.png b/app/assets/images/emoji/flag_se.png Binary files differdeleted file mode 100644 index fc0d0e0ce89..00000000000 --- a/app/assets/images/emoji/flag_se.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sg.png b/app/assets/images/emoji/flag_sg.png Binary files differdeleted file mode 100644 index de3c7737c42..00000000000 --- a/app/assets/images/emoji/flag_sg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sh.png b/app/assets/images/emoji/flag_sh.png Binary files differdeleted file mode 100644 index 40cd9e44e96..00000000000 --- a/app/assets/images/emoji/flag_sh.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_si.png b/app/assets/images/emoji/flag_si.png Binary files differdeleted file mode 100644 index e308999dba2..00000000000 --- a/app/assets/images/emoji/flag_si.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sj.png b/app/assets/images/emoji/flag_sj.png Binary files differdeleted file mode 100644 index 5884e648228..00000000000 --- a/app/assets/images/emoji/flag_sj.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sk.png b/app/assets/images/emoji/flag_sk.png Binary files differdeleted file mode 100644 index 4259d0e1418..00000000000 --- a/app/assets/images/emoji/flag_sk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sl.png b/app/assets/images/emoji/flag_sl.png Binary files differdeleted file mode 100644 index d2cc68830ab..00000000000 --- a/app/assets/images/emoji/flag_sl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sm.png b/app/assets/images/emoji/flag_sm.png Binary files differdeleted file mode 100644 index 03b8708754e..00000000000 --- a/app/assets/images/emoji/flag_sm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sn.png b/app/assets/images/emoji/flag_sn.png Binary files differdeleted file mode 100644 index 5368bbe93df..00000000000 --- a/app/assets/images/emoji/flag_sn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_so.png b/app/assets/images/emoji/flag_so.png Binary files differdeleted file mode 100644 index 68a0597365a..00000000000 --- a/app/assets/images/emoji/flag_so.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sr.png b/app/assets/images/emoji/flag_sr.png Binary files differdeleted file mode 100644 index d3251327035..00000000000 --- a/app/assets/images/emoji/flag_sr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ss.png b/app/assets/images/emoji/flag_ss.png Binary files differdeleted file mode 100644 index 122977e798f..00000000000 --- a/app/assets/images/emoji/flag_ss.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_st.png b/app/assets/images/emoji/flag_st.png Binary files differdeleted file mode 100644 index f83a863d612..00000000000 --- a/app/assets/images/emoji/flag_st.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sv.png b/app/assets/images/emoji/flag_sv.png Binary files differdeleted file mode 100644 index efb83e2f253..00000000000 --- a/app/assets/images/emoji/flag_sv.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sx.png b/app/assets/images/emoji/flag_sx.png Binary files differdeleted file mode 100644 index 94b760fbedf..00000000000 --- a/app/assets/images/emoji/flag_sx.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sy.png b/app/assets/images/emoji/flag_sy.png Binary files differdeleted file mode 100644 index 09a8ee8f78c..00000000000 --- a/app/assets/images/emoji/flag_sy.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_sz.png b/app/assets/images/emoji/flag_sz.png Binary files differdeleted file mode 100644 index f74e82ea1fd..00000000000 --- a/app/assets/images/emoji/flag_sz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ta.png b/app/assets/images/emoji/flag_ta.png Binary files differdeleted file mode 100644 index b44283e90e2..00000000000 --- a/app/assets/images/emoji/flag_ta.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tc.png b/app/assets/images/emoji/flag_tc.png Binary files differdeleted file mode 100644 index 156b33d1ba6..00000000000 --- a/app/assets/images/emoji/flag_tc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_td.png b/app/assets/images/emoji/flag_td.png Binary files differdeleted file mode 100644 index ebe7f592828..00000000000 --- a/app/assets/images/emoji/flag_td.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tf.png b/app/assets/images/emoji/flag_tf.png Binary files differdeleted file mode 100644 index a1a3ad68ee2..00000000000 --- a/app/assets/images/emoji/flag_tf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tg.png b/app/assets/images/emoji/flag_tg.png Binary files differdeleted file mode 100644 index 826b73c9ac5..00000000000 --- a/app/assets/images/emoji/flag_tg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_th.png b/app/assets/images/emoji/flag_th.png Binary files differdeleted file mode 100644 index 93ff542c5a6..00000000000 --- a/app/assets/images/emoji/flag_th.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tj.png b/app/assets/images/emoji/flag_tj.png Binary files differdeleted file mode 100644 index 7a8a0b6190a..00000000000 --- a/app/assets/images/emoji/flag_tj.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tk.png b/app/assets/images/emoji/flag_tk.png Binary files differdeleted file mode 100644 index 2fa5a21b1bb..00000000000 --- a/app/assets/images/emoji/flag_tk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tl.png b/app/assets/images/emoji/flag_tl.png Binary files differdeleted file mode 100644 index 5b120eccc6f..00000000000 --- a/app/assets/images/emoji/flag_tl.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tm.png b/app/assets/images/emoji/flag_tm.png Binary files differdeleted file mode 100644 index c3c4f532302..00000000000 --- a/app/assets/images/emoji/flag_tm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tn.png b/app/assets/images/emoji/flag_tn.png Binary files differdeleted file mode 100644 index 58ef161229f..00000000000 --- a/app/assets/images/emoji/flag_tn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_to.png b/app/assets/images/emoji/flag_to.png Binary files differdeleted file mode 100644 index 1ffa7bb9d19..00000000000 --- a/app/assets/images/emoji/flag_to.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tr.png b/app/assets/images/emoji/flag_tr.png Binary files differdeleted file mode 100644 index 325251fae88..00000000000 --- a/app/assets/images/emoji/flag_tr.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tt.png b/app/assets/images/emoji/flag_tt.png Binary files differdeleted file mode 100644 index ed3bb39a300..00000000000 --- a/app/assets/images/emoji/flag_tt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tv.png b/app/assets/images/emoji/flag_tv.png Binary files differdeleted file mode 100644 index e82c65c7bb9..00000000000 --- a/app/assets/images/emoji/flag_tv.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tw.png b/app/assets/images/emoji/flag_tw.png Binary files differdeleted file mode 100644 index 3a8f00b5928..00000000000 --- a/app/assets/images/emoji/flag_tw.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_tz.png b/app/assets/images/emoji/flag_tz.png Binary files differdeleted file mode 100644 index 2a020853d4e..00000000000 --- a/app/assets/images/emoji/flag_tz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ua.png b/app/assets/images/emoji/flag_ua.png Binary files differdeleted file mode 100644 index cd84d1bbd36..00000000000 --- a/app/assets/images/emoji/flag_ua.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ug.png b/app/assets/images/emoji/flag_ug.png Binary files differdeleted file mode 100644 index dc97690eb55..00000000000 --- a/app/assets/images/emoji/flag_ug.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_um.png b/app/assets/images/emoji/flag_um.png Binary files differdeleted file mode 100644 index 4a7ee3cdf13..00000000000 --- a/app/assets/images/emoji/flag_um.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_us.png b/app/assets/images/emoji/flag_us.png Binary files differdeleted file mode 100644 index 9f730305860..00000000000 --- a/app/assets/images/emoji/flag_us.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_uy.png b/app/assets/images/emoji/flag_uy.png Binary files differdeleted file mode 100644 index b8002a697a6..00000000000 --- a/app/assets/images/emoji/flag_uy.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_uz.png b/app/assets/images/emoji/flag_uz.png Binary files differdeleted file mode 100644 index d56ca9bc424..00000000000 --- a/app/assets/images/emoji/flag_uz.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_va.png b/app/assets/images/emoji/flag_va.png Binary files differdeleted file mode 100644 index ddaf5e3141b..00000000000 --- a/app/assets/images/emoji/flag_va.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_vc.png b/app/assets/images/emoji/flag_vc.png Binary files differdeleted file mode 100644 index 43703c62a71..00000000000 --- a/app/assets/images/emoji/flag_vc.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ve.png b/app/assets/images/emoji/flag_ve.png Binary files differdeleted file mode 100644 index 1b62796824e..00000000000 --- a/app/assets/images/emoji/flag_ve.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_vg.png b/app/assets/images/emoji/flag_vg.png Binary files differdeleted file mode 100644 index 536f780f1c0..00000000000 --- a/app/assets/images/emoji/flag_vg.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_vi.png b/app/assets/images/emoji/flag_vi.png Binary files differdeleted file mode 100644 index 64102012cfe..00000000000 --- a/app/assets/images/emoji/flag_vi.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_vn.png b/app/assets/images/emoji/flag_vn.png Binary files differdeleted file mode 100644 index 427036046b6..00000000000 --- a/app/assets/images/emoji/flag_vn.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_vu.png b/app/assets/images/emoji/flag_vu.png Binary files differdeleted file mode 100644 index 706eba44070..00000000000 --- a/app/assets/images/emoji/flag_vu.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_wf.png b/app/assets/images/emoji/flag_wf.png Binary files differdeleted file mode 100644 index 70c761036bd..00000000000 --- a/app/assets/images/emoji/flag_wf.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_white.png b/app/assets/images/emoji/flag_white.png Binary files differdeleted file mode 100644 index 86d6e96d5e9..00000000000 --- a/app/assets/images/emoji/flag_white.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ws.png b/app/assets/images/emoji/flag_ws.png Binary files differdeleted file mode 100644 index a1ea0703141..00000000000 --- a/app/assets/images/emoji/flag_ws.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_xk.png b/app/assets/images/emoji/flag_xk.png Binary files differdeleted file mode 100644 index e587a446632..00000000000 --- a/app/assets/images/emoji/flag_xk.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_ye.png b/app/assets/images/emoji/flag_ye.png Binary files differdeleted file mode 100644 index eadfebd5f67..00000000000 --- a/app/assets/images/emoji/flag_ye.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_yt.png b/app/assets/images/emoji/flag_yt.png Binary files differdeleted file mode 100644 index c81fa6d886e..00000000000 --- a/app/assets/images/emoji/flag_yt.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_za.png b/app/assets/images/emoji/flag_za.png Binary files differdeleted file mode 100644 index f397ef5072f..00000000000 --- a/app/assets/images/emoji/flag_za.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_zm.png b/app/assets/images/emoji/flag_zm.png Binary files differdeleted file mode 100644 index 2494a31f662..00000000000 --- a/app/assets/images/emoji/flag_zm.png +++ /dev/null diff --git a/app/assets/images/emoji/flag_zw.png b/app/assets/images/emoji/flag_zw.png Binary files differdeleted file mode 100644 index e09b9652be6..00000000000 --- a/app/assets/images/emoji/flag_zw.png +++ /dev/null diff --git a/app/assets/images/emoji/flags.png b/app/assets/images/emoji/flags.png Binary files differdeleted file mode 100644 index 3b451035a3a..00000000000 --- a/app/assets/images/emoji/flags.png +++ /dev/null diff --git a/app/assets/images/emoji/flashlight.png b/app/assets/images/emoji/flashlight.png Binary files differdeleted file mode 100644 index eee36c25067..00000000000 --- a/app/assets/images/emoji/flashlight.png +++ /dev/null diff --git a/app/assets/images/emoji/fleur-de-lis.png b/app/assets/images/emoji/fleur-de-lis.png Binary files differdeleted file mode 100644 index c9250d27fa7..00000000000 --- a/app/assets/images/emoji/fleur-de-lis.png +++ /dev/null diff --git a/app/assets/images/emoji/floppy_disk.png b/app/assets/images/emoji/floppy_disk.png Binary files differdeleted file mode 100644 index 072a76d3c13..00000000000 --- a/app/assets/images/emoji/floppy_disk.png +++ /dev/null diff --git a/app/assets/images/emoji/flower_playing_cards.png b/app/assets/images/emoji/flower_playing_cards.png Binary files differdeleted file mode 100644 index 6766b044d95..00000000000 --- a/app/assets/images/emoji/flower_playing_cards.png +++ /dev/null diff --git a/app/assets/images/emoji/flushed.png b/app/assets/images/emoji/flushed.png Binary files differdeleted file mode 100644 index 829220bc470..00000000000 --- a/app/assets/images/emoji/flushed.png +++ /dev/null diff --git a/app/assets/images/emoji/fog.png b/app/assets/images/emoji/fog.png Binary files differdeleted file mode 100644 index 4e73c2de272..00000000000 --- a/app/assets/images/emoji/fog.png +++ /dev/null diff --git a/app/assets/images/emoji/foggy.png b/app/assets/images/emoji/foggy.png Binary files differdeleted file mode 100644 index 57702d8d3ac..00000000000 --- a/app/assets/images/emoji/foggy.png +++ /dev/null diff --git a/app/assets/images/emoji/football.png b/app/assets/images/emoji/football.png Binary files differdeleted file mode 100644 index 10366f41fce..00000000000 --- a/app/assets/images/emoji/football.png +++ /dev/null diff --git a/app/assets/images/emoji/footprints.png b/app/assets/images/emoji/footprints.png Binary files differdeleted file mode 100644 index b2673c5a1a8..00000000000 --- a/app/assets/images/emoji/footprints.png +++ /dev/null diff --git a/app/assets/images/emoji/fork_and_knife.png b/app/assets/images/emoji/fork_and_knife.png Binary files differdeleted file mode 100644 index 09f1feaea1c..00000000000 --- a/app/assets/images/emoji/fork_and_knife.png +++ /dev/null diff --git a/app/assets/images/emoji/fork_knife_plate.png b/app/assets/images/emoji/fork_knife_plate.png Binary files differdeleted file mode 100644 index 7411755f708..00000000000 --- a/app/assets/images/emoji/fork_knife_plate.png +++ /dev/null diff --git a/app/assets/images/emoji/fountain.png b/app/assets/images/emoji/fountain.png Binary files differdeleted file mode 100644 index 293f5d91c0f..00000000000 --- a/app/assets/images/emoji/fountain.png +++ /dev/null diff --git a/app/assets/images/emoji/four.png b/app/assets/images/emoji/four.png Binary files differdeleted file mode 100644 index b0e914aac45..00000000000 --- a/app/assets/images/emoji/four.png +++ /dev/null diff --git a/app/assets/images/emoji/four_leaf_clover.png b/app/assets/images/emoji/four_leaf_clover.png Binary files differdeleted file mode 100644 index fdedfcc2b4e..00000000000 --- a/app/assets/images/emoji/four_leaf_clover.png +++ /dev/null diff --git a/app/assets/images/emoji/fox.png b/app/assets/images/emoji/fox.png Binary files differdeleted file mode 100644 index 1ab339bf054..00000000000 --- a/app/assets/images/emoji/fox.png +++ /dev/null diff --git a/app/assets/images/emoji/frame_photo.png b/app/assets/images/emoji/frame_photo.png Binary files differdeleted file mode 100644 index 9fe84607bfd..00000000000 --- a/app/assets/images/emoji/frame_photo.png +++ /dev/null diff --git a/app/assets/images/emoji/free.png b/app/assets/images/emoji/free.png Binary files differdeleted file mode 100644 index b71956eb48a..00000000000 --- a/app/assets/images/emoji/free.png +++ /dev/null diff --git a/app/assets/images/emoji/french_bread.png b/app/assets/images/emoji/french_bread.png Binary files differdeleted file mode 100644 index 4c2c5639822..00000000000 --- a/app/assets/images/emoji/french_bread.png +++ /dev/null diff --git a/app/assets/images/emoji/fried_shrimp.png b/app/assets/images/emoji/fried_shrimp.png Binary files differdeleted file mode 100644 index 752ba7f1398..00000000000 --- a/app/assets/images/emoji/fried_shrimp.png +++ /dev/null diff --git a/app/assets/images/emoji/fries.png b/app/assets/images/emoji/fries.png Binary files differdeleted file mode 100644 index 4e2a4caacef..00000000000 --- a/app/assets/images/emoji/fries.png +++ /dev/null diff --git a/app/assets/images/emoji/frog.png b/app/assets/images/emoji/frog.png Binary files differdeleted file mode 100644 index 8825d1ad577..00000000000 --- a/app/assets/images/emoji/frog.png +++ /dev/null diff --git a/app/assets/images/emoji/frowning.png b/app/assets/images/emoji/frowning.png Binary files differdeleted file mode 100644 index 43ab6b0a1c1..00000000000 --- a/app/assets/images/emoji/frowning.png +++ /dev/null diff --git a/app/assets/images/emoji/frowning2.png b/app/assets/images/emoji/frowning2.png Binary files differdeleted file mode 100644 index 6ae71f233b9..00000000000 --- a/app/assets/images/emoji/frowning2.png +++ /dev/null diff --git a/app/assets/images/emoji/fuelpump.png b/app/assets/images/emoji/fuelpump.png Binary files differdeleted file mode 100644 index 05b18794474..00000000000 --- a/app/assets/images/emoji/fuelpump.png +++ /dev/null diff --git a/app/assets/images/emoji/full_moon.png b/app/assets/images/emoji/full_moon.png Binary files differdeleted file mode 100644 index c9a2d6aa7c9..00000000000 --- a/app/assets/images/emoji/full_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/full_moon_with_face.png b/app/assets/images/emoji/full_moon_with_face.png Binary files differdeleted file mode 100644 index a5c25bbaf64..00000000000 --- a/app/assets/images/emoji/full_moon_with_face.png +++ /dev/null diff --git a/app/assets/images/emoji/game_die.png b/app/assets/images/emoji/game_die.png Binary files differdeleted file mode 100644 index ad3626fe5e5..00000000000 --- a/app/assets/images/emoji/game_die.png +++ /dev/null diff --git a/app/assets/images/emoji/gay_pride_flag.png b/app/assets/images/emoji/gay_pride_flag.png Binary files differdeleted file mode 100644 index 1bec5f2ffd7..00000000000 --- a/app/assets/images/emoji/gay_pride_flag.png +++ /dev/null diff --git a/app/assets/images/emoji/gear.png b/app/assets/images/emoji/gear.png Binary files differdeleted file mode 100644 index 2a1cc2c0ff4..00000000000 --- a/app/assets/images/emoji/gear.png +++ /dev/null diff --git a/app/assets/images/emoji/gem.png b/app/assets/images/emoji/gem.png Binary files differdeleted file mode 100644 index db122d26a19..00000000000 --- a/app/assets/images/emoji/gem.png +++ /dev/null diff --git a/app/assets/images/emoji/gemini.png b/app/assets/images/emoji/gemini.png Binary files differdeleted file mode 100644 index 1a09698cf00..00000000000 --- a/app/assets/images/emoji/gemini.png +++ /dev/null diff --git a/app/assets/images/emoji/ghost.png b/app/assets/images/emoji/ghost.png Binary files differdeleted file mode 100644 index 5650bc0ed18..00000000000 --- a/app/assets/images/emoji/ghost.png +++ /dev/null diff --git a/app/assets/images/emoji/gift.png b/app/assets/images/emoji/gift.png Binary files differdeleted file mode 100644 index 844e2164560..00000000000 --- a/app/assets/images/emoji/gift.png +++ /dev/null diff --git a/app/assets/images/emoji/gift_heart.png b/app/assets/images/emoji/gift_heart.png Binary files differdeleted file mode 100644 index 902ceafe4d1..00000000000 --- a/app/assets/images/emoji/gift_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/girl.png b/app/assets/images/emoji/girl.png Binary files differdeleted file mode 100644 index dc1d4d08b39..00000000000 --- a/app/assets/images/emoji/girl.png +++ /dev/null diff --git a/app/assets/images/emoji/girl_tone1.png b/app/assets/images/emoji/girl_tone1.png Binary files differdeleted file mode 100644 index bb667e88651..00000000000 --- a/app/assets/images/emoji/girl_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/girl_tone2.png b/app/assets/images/emoji/girl_tone2.png Binary files differdeleted file mode 100644 index a59ed4a3f0d..00000000000 --- a/app/assets/images/emoji/girl_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/girl_tone3.png b/app/assets/images/emoji/girl_tone3.png Binary files differdeleted file mode 100644 index 517e7f2a7b0..00000000000 --- a/app/assets/images/emoji/girl_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/girl_tone4.png b/app/assets/images/emoji/girl_tone4.png Binary files differdeleted file mode 100644 index 542d96c8487..00000000000 --- a/app/assets/images/emoji/girl_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/girl_tone5.png b/app/assets/images/emoji/girl_tone5.png Binary files differdeleted file mode 100644 index 66b7c28c2df..00000000000 --- a/app/assets/images/emoji/girl_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/globe_with_meridians.png b/app/assets/images/emoji/globe_with_meridians.png Binary files differdeleted file mode 100644 index 82450c1a4ba..00000000000 --- a/app/assets/images/emoji/globe_with_meridians.png +++ /dev/null diff --git a/app/assets/images/emoji/goal.png b/app/assets/images/emoji/goal.png Binary files differdeleted file mode 100644 index df3a53da0fb..00000000000 --- a/app/assets/images/emoji/goal.png +++ /dev/null diff --git a/app/assets/images/emoji/goat.png b/app/assets/images/emoji/goat.png Binary files differdeleted file mode 100644 index f9d9e38a128..00000000000 --- a/app/assets/images/emoji/goat.png +++ /dev/null diff --git a/app/assets/images/emoji/golf.png b/app/assets/images/emoji/golf.png Binary files differdeleted file mode 100644 index f65a21d8a46..00000000000 --- a/app/assets/images/emoji/golf.png +++ /dev/null diff --git a/app/assets/images/emoji/golfer.png b/app/assets/images/emoji/golfer.png Binary files differdeleted file mode 100644 index 39c552de86d..00000000000 --- a/app/assets/images/emoji/golfer.png +++ /dev/null diff --git a/app/assets/images/emoji/gorilla.png b/app/assets/images/emoji/gorilla.png Binary files differdeleted file mode 100644 index acc51e13622..00000000000 --- a/app/assets/images/emoji/gorilla.png +++ /dev/null diff --git a/app/assets/images/emoji/grapes.png b/app/assets/images/emoji/grapes.png Binary files differdeleted file mode 100644 index 30d22218896..00000000000 --- a/app/assets/images/emoji/grapes.png +++ /dev/null diff --git a/app/assets/images/emoji/green_apple.png b/app/assets/images/emoji/green_apple.png Binary files differdeleted file mode 100644 index 5fd51bd3915..00000000000 --- a/app/assets/images/emoji/green_apple.png +++ /dev/null diff --git a/app/assets/images/emoji/green_book.png b/app/assets/images/emoji/green_book.png Binary files differdeleted file mode 100644 index e5e411cf3b5..00000000000 --- a/app/assets/images/emoji/green_book.png +++ /dev/null diff --git a/app/assets/images/emoji/green_heart.png b/app/assets/images/emoji/green_heart.png Binary files differdeleted file mode 100644 index c52d60a58be..00000000000 --- a/app/assets/images/emoji/green_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/grey_exclamation.png b/app/assets/images/emoji/grey_exclamation.png Binary files differdeleted file mode 100644 index 9b64da8bf7f..00000000000 --- a/app/assets/images/emoji/grey_exclamation.png +++ /dev/null diff --git a/app/assets/images/emoji/grey_question.png b/app/assets/images/emoji/grey_question.png Binary files differdeleted file mode 100644 index 6e7824c75f6..00000000000 --- a/app/assets/images/emoji/grey_question.png +++ /dev/null diff --git a/app/assets/images/emoji/grimacing.png b/app/assets/images/emoji/grimacing.png Binary files differdeleted file mode 100644 index 871b2f071c9..00000000000 --- a/app/assets/images/emoji/grimacing.png +++ /dev/null diff --git a/app/assets/images/emoji/grin.png b/app/assets/images/emoji/grin.png Binary files differdeleted file mode 100644 index 418d94c811b..00000000000 --- a/app/assets/images/emoji/grin.png +++ /dev/null diff --git a/app/assets/images/emoji/grinning.png b/app/assets/images/emoji/grinning.png Binary files differdeleted file mode 100644 index 3e8e0dab78c..00000000000 --- a/app/assets/images/emoji/grinning.png +++ /dev/null diff --git a/app/assets/images/emoji/guardsman.png b/app/assets/images/emoji/guardsman.png Binary files differdeleted file mode 100644 index 8d7ab3c473c..00000000000 --- a/app/assets/images/emoji/guardsman.png +++ /dev/null diff --git a/app/assets/images/emoji/guardsman_tone1.png b/app/assets/images/emoji/guardsman_tone1.png Binary files differdeleted file mode 100644 index cea9ba27468..00000000000 --- a/app/assets/images/emoji/guardsman_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/guardsman_tone2.png b/app/assets/images/emoji/guardsman_tone2.png Binary files differdeleted file mode 100644 index 037464e4028..00000000000 --- a/app/assets/images/emoji/guardsman_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/guardsman_tone3.png b/app/assets/images/emoji/guardsman_tone3.png Binary files differdeleted file mode 100644 index 0f6726fbe87..00000000000 --- a/app/assets/images/emoji/guardsman_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/guardsman_tone4.png b/app/assets/images/emoji/guardsman_tone4.png Binary files differdeleted file mode 100644 index 85fcf9a3b97..00000000000 --- a/app/assets/images/emoji/guardsman_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/guardsman_tone5.png b/app/assets/images/emoji/guardsman_tone5.png Binary files differdeleted file mode 100644 index e5f9ca7d5a2..00000000000 --- a/app/assets/images/emoji/guardsman_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/guitar.png b/app/assets/images/emoji/guitar.png Binary files differdeleted file mode 100644 index 43d752f1e3d..00000000000 --- a/app/assets/images/emoji/guitar.png +++ /dev/null diff --git a/app/assets/images/emoji/gun.png b/app/assets/images/emoji/gun.png Binary files differdeleted file mode 100644 index 89c5c244c7b..00000000000 --- a/app/assets/images/emoji/gun.png +++ /dev/null diff --git a/app/assets/images/emoji/haircut.png b/app/assets/images/emoji/haircut.png Binary files differdeleted file mode 100644 index 91266b12930..00000000000 --- a/app/assets/images/emoji/haircut.png +++ /dev/null diff --git a/app/assets/images/emoji/haircut_tone1.png b/app/assets/images/emoji/haircut_tone1.png Binary files differdeleted file mode 100644 index c743b74abeb..00000000000 --- a/app/assets/images/emoji/haircut_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/haircut_tone2.png b/app/assets/images/emoji/haircut_tone2.png Binary files differdeleted file mode 100644 index f144f8e55ce..00000000000 --- a/app/assets/images/emoji/haircut_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/haircut_tone3.png b/app/assets/images/emoji/haircut_tone3.png Binary files differdeleted file mode 100644 index d5ad19563ac..00000000000 --- a/app/assets/images/emoji/haircut_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/haircut_tone4.png b/app/assets/images/emoji/haircut_tone4.png Binary files differdeleted file mode 100644 index 244fd3af008..00000000000 --- a/app/assets/images/emoji/haircut_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/haircut_tone5.png b/app/assets/images/emoji/haircut_tone5.png Binary files differdeleted file mode 100644 index 20a94a88623..00000000000 --- a/app/assets/images/emoji/haircut_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/hamburger.png b/app/assets/images/emoji/hamburger.png Binary files differdeleted file mode 100644 index 3573b28a1fd..00000000000 --- a/app/assets/images/emoji/hamburger.png +++ /dev/null diff --git a/app/assets/images/emoji/hammer.png b/app/assets/images/emoji/hammer.png Binary files differdeleted file mode 100644 index 00736cce47d..00000000000 --- a/app/assets/images/emoji/hammer.png +++ /dev/null diff --git a/app/assets/images/emoji/hammer_pick.png b/app/assets/images/emoji/hammer_pick.png Binary files differdeleted file mode 100644 index 3bee30ec588..00000000000 --- a/app/assets/images/emoji/hammer_pick.png +++ /dev/null diff --git a/app/assets/images/emoji/hamster.png b/app/assets/images/emoji/hamster.png Binary files differdeleted file mode 100644 index 9a04388e4e7..00000000000 --- a/app/assets/images/emoji/hamster.png +++ /dev/null diff --git a/app/assets/images/emoji/hand_splayed.png b/app/assets/images/emoji/hand_splayed.png Binary files differdeleted file mode 100644 index fb5ae8ebb5a..00000000000 --- a/app/assets/images/emoji/hand_splayed.png +++ /dev/null diff --git a/app/assets/images/emoji/hand_splayed_tone1.png b/app/assets/images/emoji/hand_splayed_tone1.png Binary files differdeleted file mode 100644 index a7888e6bd23..00000000000 --- a/app/assets/images/emoji/hand_splayed_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/hand_splayed_tone2.png b/app/assets/images/emoji/hand_splayed_tone2.png Binary files differdeleted file mode 100644 index cc10fbc272d..00000000000 --- a/app/assets/images/emoji/hand_splayed_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/hand_splayed_tone3.png b/app/assets/images/emoji/hand_splayed_tone3.png Binary files differdeleted file mode 100644 index 707236ae8a4..00000000000 --- a/app/assets/images/emoji/hand_splayed_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/hand_splayed_tone4.png b/app/assets/images/emoji/hand_splayed_tone4.png Binary files differdeleted file mode 100644 index 1430df9c61f..00000000000 --- a/app/assets/images/emoji/hand_splayed_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/hand_splayed_tone5.png b/app/assets/images/emoji/hand_splayed_tone5.png Binary files differdeleted file mode 100644 index 80bec971b6b..00000000000 --- a/app/assets/images/emoji/hand_splayed_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/handbag.png b/app/assets/images/emoji/handbag.png Binary files differdeleted file mode 100644 index cbf75c5d25e..00000000000 --- a/app/assets/images/emoji/handbag.png +++ /dev/null diff --git a/app/assets/images/emoji/handball.png b/app/assets/images/emoji/handball.png Binary files differdeleted file mode 100644 index 1152f1344c7..00000000000 --- a/app/assets/images/emoji/handball.png +++ /dev/null diff --git a/app/assets/images/emoji/handball_tone1.png b/app/assets/images/emoji/handball_tone1.png Binary files differdeleted file mode 100644 index c26cac2df98..00000000000 --- a/app/assets/images/emoji/handball_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/handball_tone2.png b/app/assets/images/emoji/handball_tone2.png Binary files differdeleted file mode 100644 index 7baaf95a9a2..00000000000 --- a/app/assets/images/emoji/handball_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/handball_tone3.png b/app/assets/images/emoji/handball_tone3.png Binary files differdeleted file mode 100644 index 0e3a37c3d40..00000000000 --- a/app/assets/images/emoji/handball_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/handball_tone4.png b/app/assets/images/emoji/handball_tone4.png Binary files differdeleted file mode 100644 index e1233f38266..00000000000 --- a/app/assets/images/emoji/handball_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/handball_tone5.png b/app/assets/images/emoji/handball_tone5.png Binary files differdeleted file mode 100644 index 6b1eb9b64b0..00000000000 --- a/app/assets/images/emoji/handball_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/handshake.png b/app/assets/images/emoji/handshake.png Binary files differdeleted file mode 100644 index c5d35fd8138..00000000000 --- a/app/assets/images/emoji/handshake.png +++ /dev/null diff --git a/app/assets/images/emoji/handshake_tone1.png b/app/assets/images/emoji/handshake_tone1.png Binary files differdeleted file mode 100644 index 8f8fbb9bdca..00000000000 --- a/app/assets/images/emoji/handshake_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/handshake_tone2.png b/app/assets/images/emoji/handshake_tone2.png Binary files differdeleted file mode 100644 index 336a77a6d78..00000000000 --- a/app/assets/images/emoji/handshake_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/handshake_tone3.png b/app/assets/images/emoji/handshake_tone3.png Binary files differdeleted file mode 100644 index 95f62d4fecd..00000000000 --- a/app/assets/images/emoji/handshake_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/handshake_tone4.png b/app/assets/images/emoji/handshake_tone4.png Binary files differdeleted file mode 100644 index 2b0a6433886..00000000000 --- a/app/assets/images/emoji/handshake_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/handshake_tone5.png b/app/assets/images/emoji/handshake_tone5.png Binary files differdeleted file mode 100644 index 40189ee68e4..00000000000 --- a/app/assets/images/emoji/handshake_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/hash.png b/app/assets/images/emoji/hash.png Binary files differdeleted file mode 100644 index 6e26f0070b0..00000000000 --- a/app/assets/images/emoji/hash.png +++ /dev/null diff --git a/app/assets/images/emoji/hatched_chick.png b/app/assets/images/emoji/hatched_chick.png Binary files differdeleted file mode 100644 index 31dfb511e0e..00000000000 --- a/app/assets/images/emoji/hatched_chick.png +++ /dev/null diff --git a/app/assets/images/emoji/hatching_chick.png b/app/assets/images/emoji/hatching_chick.png Binary files differdeleted file mode 100644 index c5b0e8f3bcc..00000000000 --- a/app/assets/images/emoji/hatching_chick.png +++ /dev/null diff --git a/app/assets/images/emoji/head_bandage.png b/app/assets/images/emoji/head_bandage.png Binary files differdeleted file mode 100644 index 0be723085e0..00000000000 --- a/app/assets/images/emoji/head_bandage.png +++ /dev/null diff --git a/app/assets/images/emoji/headphones.png b/app/assets/images/emoji/headphones.png Binary files differdeleted file mode 100644 index e9fd34041d8..00000000000 --- a/app/assets/images/emoji/headphones.png +++ /dev/null diff --git a/app/assets/images/emoji/hear_no_evil.png b/app/assets/images/emoji/hear_no_evil.png Binary files differdeleted file mode 100644 index 74b6be0c6c5..00000000000 --- a/app/assets/images/emoji/hear_no_evil.png +++ /dev/null diff --git a/app/assets/images/emoji/heart.png b/app/assets/images/emoji/heart.png Binary files differdeleted file mode 100644 index 638cb72dc4e..00000000000 --- a/app/assets/images/emoji/heart.png +++ /dev/null diff --git a/app/assets/images/emoji/heart_decoration.png b/app/assets/images/emoji/heart_decoration.png Binary files differdeleted file mode 100644 index 5443f60bc63..00000000000 --- a/app/assets/images/emoji/heart_decoration.png +++ /dev/null diff --git a/app/assets/images/emoji/heart_exclamation.png b/app/assets/images/emoji/heart_exclamation.png Binary files differdeleted file mode 100644 index 91b520be40b..00000000000 --- a/app/assets/images/emoji/heart_exclamation.png +++ /dev/null diff --git a/app/assets/images/emoji/heart_eyes.png b/app/assets/images/emoji/heart_eyes.png Binary files differdeleted file mode 100644 index 73fbee29d4e..00000000000 --- a/app/assets/images/emoji/heart_eyes.png +++ /dev/null diff --git a/app/assets/images/emoji/heart_eyes_cat.png b/app/assets/images/emoji/heart_eyes_cat.png Binary files differdeleted file mode 100644 index bc5a833f9a1..00000000000 --- a/app/assets/images/emoji/heart_eyes_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/heartbeat.png b/app/assets/images/emoji/heartbeat.png Binary files differdeleted file mode 100644 index 0bcf2d1d567..00000000000 --- a/app/assets/images/emoji/heartbeat.png +++ /dev/null diff --git a/app/assets/images/emoji/heartpulse.png b/app/assets/images/emoji/heartpulse.png Binary files differdeleted file mode 100644 index d6e694e972f..00000000000 --- a/app/assets/images/emoji/heartpulse.png +++ /dev/null diff --git a/app/assets/images/emoji/hearts.png b/app/assets/images/emoji/hearts.png Binary files differdeleted file mode 100644 index 393c3ed5267..00000000000 --- a/app/assets/images/emoji/hearts.png +++ /dev/null diff --git a/app/assets/images/emoji/heavy_check_mark.png b/app/assets/images/emoji/heavy_check_mark.png Binary files differdeleted file mode 100644 index 03bd695377e..00000000000 --- a/app/assets/images/emoji/heavy_check_mark.png +++ /dev/null diff --git a/app/assets/images/emoji/heavy_division_sign.png b/app/assets/images/emoji/heavy_division_sign.png Binary files differdeleted file mode 100644 index df32ab21bea..00000000000 --- a/app/assets/images/emoji/heavy_division_sign.png +++ /dev/null diff --git a/app/assets/images/emoji/heavy_dollar_sign.png b/app/assets/images/emoji/heavy_dollar_sign.png Binary files differdeleted file mode 100644 index ef2c2e20590..00000000000 --- a/app/assets/images/emoji/heavy_dollar_sign.png +++ /dev/null diff --git a/app/assets/images/emoji/heavy_minus_sign.png b/app/assets/images/emoji/heavy_minus_sign.png Binary files differdeleted file mode 100644 index 054211caf12..00000000000 --- a/app/assets/images/emoji/heavy_minus_sign.png +++ /dev/null diff --git a/app/assets/images/emoji/heavy_multiplication_x.png b/app/assets/images/emoji/heavy_multiplication_x.png Binary files differdeleted file mode 100644 index e47cc1b685d..00000000000 --- a/app/assets/images/emoji/heavy_multiplication_x.png +++ /dev/null diff --git a/app/assets/images/emoji/heavy_plus_sign.png b/app/assets/images/emoji/heavy_plus_sign.png Binary files differdeleted file mode 100644 index 40799798aaf..00000000000 --- a/app/assets/images/emoji/heavy_plus_sign.png +++ /dev/null diff --git a/app/assets/images/emoji/helicopter.png b/app/assets/images/emoji/helicopter.png Binary files differdeleted file mode 100644 index 7ec5f39a51a..00000000000 --- a/app/assets/images/emoji/helicopter.png +++ /dev/null diff --git a/app/assets/images/emoji/helmet_with_cross.png b/app/assets/images/emoji/helmet_with_cross.png Binary files differdeleted file mode 100644 index 7140a676038..00000000000 --- a/app/assets/images/emoji/helmet_with_cross.png +++ /dev/null diff --git a/app/assets/images/emoji/herb.png b/app/assets/images/emoji/herb.png Binary files differdeleted file mode 100644 index d984d1562bb..00000000000 --- a/app/assets/images/emoji/herb.png +++ /dev/null diff --git a/app/assets/images/emoji/hibiscus.png b/app/assets/images/emoji/hibiscus.png Binary files differdeleted file mode 100644 index 39dd3524233..00000000000 --- a/app/assets/images/emoji/hibiscus.png +++ /dev/null diff --git a/app/assets/images/emoji/high_brightness.png b/app/assets/images/emoji/high_brightness.png Binary files differdeleted file mode 100644 index c41f2d5fd50..00000000000 --- a/app/assets/images/emoji/high_brightness.png +++ /dev/null diff --git a/app/assets/images/emoji/high_heel.png b/app/assets/images/emoji/high_heel.png Binary files differdeleted file mode 100644 index b331cbccc9d..00000000000 --- a/app/assets/images/emoji/high_heel.png +++ /dev/null diff --git a/app/assets/images/emoji/hockey.png b/app/assets/images/emoji/hockey.png Binary files differdeleted file mode 100644 index be94e9cbf73..00000000000 --- a/app/assets/images/emoji/hockey.png +++ /dev/null diff --git a/app/assets/images/emoji/hole.png b/app/assets/images/emoji/hole.png Binary files differdeleted file mode 100644 index 517d2ae0deb..00000000000 --- a/app/assets/images/emoji/hole.png +++ /dev/null diff --git a/app/assets/images/emoji/homes.png b/app/assets/images/emoji/homes.png Binary files differdeleted file mode 100644 index 6ab4a2a2651..00000000000 --- a/app/assets/images/emoji/homes.png +++ /dev/null diff --git a/app/assets/images/emoji/honey_pot.png b/app/assets/images/emoji/honey_pot.png Binary files differdeleted file mode 100644 index 9d8f592955e..00000000000 --- a/app/assets/images/emoji/honey_pot.png +++ /dev/null diff --git a/app/assets/images/emoji/horse.png b/app/assets/images/emoji/horse.png Binary files differdeleted file mode 100644 index 7cb1172f4e4..00000000000 --- a/app/assets/images/emoji/horse.png +++ /dev/null diff --git a/app/assets/images/emoji/horse_racing.png b/app/assets/images/emoji/horse_racing.png Binary files differdeleted file mode 100644 index addf9edac56..00000000000 --- a/app/assets/images/emoji/horse_racing.png +++ /dev/null diff --git a/app/assets/images/emoji/horse_racing_tone1.png b/app/assets/images/emoji/horse_racing_tone1.png Binary files differdeleted file mode 100644 index e9bf4092e98..00000000000 --- a/app/assets/images/emoji/horse_racing_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/horse_racing_tone2.png b/app/assets/images/emoji/horse_racing_tone2.png Binary files differdeleted file mode 100644 index 031bbc3d867..00000000000 --- a/app/assets/images/emoji/horse_racing_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/horse_racing_tone3.png b/app/assets/images/emoji/horse_racing_tone3.png Binary files differdeleted file mode 100644 index b40ef891f9b..00000000000 --- a/app/assets/images/emoji/horse_racing_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/horse_racing_tone4.png b/app/assets/images/emoji/horse_racing_tone4.png Binary files differdeleted file mode 100644 index e286cb85065..00000000000 --- a/app/assets/images/emoji/horse_racing_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/horse_racing_tone5.png b/app/assets/images/emoji/horse_racing_tone5.png Binary files differdeleted file mode 100644 index 453c51c6007..00000000000 --- a/app/assets/images/emoji/horse_racing_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/hospital.png b/app/assets/images/emoji/hospital.png Binary files differdeleted file mode 100644 index 1cbce4ae767..00000000000 --- a/app/assets/images/emoji/hospital.png +++ /dev/null diff --git a/app/assets/images/emoji/hot_pepper.png b/app/assets/images/emoji/hot_pepper.png Binary files differdeleted file mode 100644 index 266675bd577..00000000000 --- a/app/assets/images/emoji/hot_pepper.png +++ /dev/null diff --git a/app/assets/images/emoji/hotdog.png b/app/assets/images/emoji/hotdog.png Binary files differdeleted file mode 100644 index 3c3354d94cb..00000000000 --- a/app/assets/images/emoji/hotdog.png +++ /dev/null diff --git a/app/assets/images/emoji/hotel.png b/app/assets/images/emoji/hotel.png Binary files differdeleted file mode 100644 index ea8f4c4979a..00000000000 --- a/app/assets/images/emoji/hotel.png +++ /dev/null diff --git a/app/assets/images/emoji/hotsprings.png b/app/assets/images/emoji/hotsprings.png Binary files differdeleted file mode 100644 index 3d9df2d9475..00000000000 --- a/app/assets/images/emoji/hotsprings.png +++ /dev/null diff --git a/app/assets/images/emoji/hourglass.png b/app/assets/images/emoji/hourglass.png Binary files differdeleted file mode 100644 index a5db2d1d3f4..00000000000 --- a/app/assets/images/emoji/hourglass.png +++ /dev/null diff --git a/app/assets/images/emoji/hourglass_flowing_sand.png b/app/assets/images/emoji/hourglass_flowing_sand.png Binary files differdeleted file mode 100644 index b93b15ed6d8..00000000000 --- a/app/assets/images/emoji/hourglass_flowing_sand.png +++ /dev/null diff --git a/app/assets/images/emoji/house.png b/app/assets/images/emoji/house.png Binary files differdeleted file mode 100644 index 01c98a0ba92..00000000000 --- a/app/assets/images/emoji/house.png +++ /dev/null diff --git a/app/assets/images/emoji/house_abandoned.png b/app/assets/images/emoji/house_abandoned.png Binary files differdeleted file mode 100644 index c55e81de990..00000000000 --- a/app/assets/images/emoji/house_abandoned.png +++ /dev/null diff --git a/app/assets/images/emoji/house_with_garden.png b/app/assets/images/emoji/house_with_garden.png Binary files differdeleted file mode 100644 index 0aae41598ef..00000000000 --- a/app/assets/images/emoji/house_with_garden.png +++ /dev/null diff --git a/app/assets/images/emoji/hugging.png b/app/assets/images/emoji/hugging.png Binary files differdeleted file mode 100644 index 5bba6dc6d51..00000000000 --- a/app/assets/images/emoji/hugging.png +++ /dev/null diff --git a/app/assets/images/emoji/hushed.png b/app/assets/images/emoji/hushed.png Binary files differdeleted file mode 100644 index cad0e23132e..00000000000 --- a/app/assets/images/emoji/hushed.png +++ /dev/null diff --git a/app/assets/images/emoji/ice_cream.png b/app/assets/images/emoji/ice_cream.png Binary files differdeleted file mode 100644 index 94267b9c434..00000000000 --- a/app/assets/images/emoji/ice_cream.png +++ /dev/null diff --git a/app/assets/images/emoji/ice_skate.png b/app/assets/images/emoji/ice_skate.png Binary files differdeleted file mode 100644 index 8c449b0c039..00000000000 --- a/app/assets/images/emoji/ice_skate.png +++ /dev/null diff --git a/app/assets/images/emoji/icecream.png b/app/assets/images/emoji/icecream.png Binary files differdeleted file mode 100644 index 8f6546e31a5..00000000000 --- a/app/assets/images/emoji/icecream.png +++ /dev/null diff --git a/app/assets/images/emoji/id.png b/app/assets/images/emoji/id.png Binary files differdeleted file mode 100644 index 5bf69bf7ba8..00000000000 --- a/app/assets/images/emoji/id.png +++ /dev/null diff --git a/app/assets/images/emoji/ideograph_advantage.png b/app/assets/images/emoji/ideograph_advantage.png Binary files differdeleted file mode 100644 index 0c0d589caf0..00000000000 --- a/app/assets/images/emoji/ideograph_advantage.png +++ /dev/null diff --git a/app/assets/images/emoji/imp.png b/app/assets/images/emoji/imp.png Binary files differdeleted file mode 100644 index 9f9a9605539..00000000000 --- a/app/assets/images/emoji/imp.png +++ /dev/null diff --git a/app/assets/images/emoji/inbox_tray.png b/app/assets/images/emoji/inbox_tray.png Binary files differdeleted file mode 100644 index 41a6be2b0ee..00000000000 --- a/app/assets/images/emoji/inbox_tray.png +++ /dev/null diff --git a/app/assets/images/emoji/incoming_envelope.png b/app/assets/images/emoji/incoming_envelope.png Binary files differdeleted file mode 100644 index fd22e88182e..00000000000 --- a/app/assets/images/emoji/incoming_envelope.png +++ /dev/null diff --git a/app/assets/images/emoji/information_desk_person.png b/app/assets/images/emoji/information_desk_person.png Binary files differdeleted file mode 100644 index 55fc6294d25..00000000000 --- a/app/assets/images/emoji/information_desk_person.png +++ /dev/null diff --git a/app/assets/images/emoji/information_desk_person_tone1.png b/app/assets/images/emoji/information_desk_person_tone1.png Binary files differdeleted file mode 100644 index 3d9e2247940..00000000000 --- a/app/assets/images/emoji/information_desk_person_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/information_desk_person_tone2.png b/app/assets/images/emoji/information_desk_person_tone2.png Binary files differdeleted file mode 100644 index 879e8b7966d..00000000000 --- a/app/assets/images/emoji/information_desk_person_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/information_desk_person_tone3.png b/app/assets/images/emoji/information_desk_person_tone3.png Binary files differdeleted file mode 100644 index 307514eab67..00000000000 --- a/app/assets/images/emoji/information_desk_person_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/information_desk_person_tone4.png b/app/assets/images/emoji/information_desk_person_tone4.png Binary files differdeleted file mode 100644 index 297395dcb3f..00000000000 --- a/app/assets/images/emoji/information_desk_person_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/information_desk_person_tone5.png b/app/assets/images/emoji/information_desk_person_tone5.png Binary files differdeleted file mode 100644 index 26f8f22b28b..00000000000 --- a/app/assets/images/emoji/information_desk_person_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/information_source.png b/app/assets/images/emoji/information_source.png Binary files differdeleted file mode 100644 index 871f2db9314..00000000000 --- a/app/assets/images/emoji/information_source.png +++ /dev/null diff --git a/app/assets/images/emoji/innocent.png b/app/assets/images/emoji/innocent.png Binary files differdeleted file mode 100644 index 57f5151124f..00000000000 --- a/app/assets/images/emoji/innocent.png +++ /dev/null diff --git a/app/assets/images/emoji/interrobang.png b/app/assets/images/emoji/interrobang.png Binary files differdeleted file mode 100644 index 509813e9bb2..00000000000 --- a/app/assets/images/emoji/interrobang.png +++ /dev/null diff --git a/app/assets/images/emoji/iphone.png b/app/assets/images/emoji/iphone.png Binary files differdeleted file mode 100644 index fd377acf872..00000000000 --- a/app/assets/images/emoji/iphone.png +++ /dev/null diff --git a/app/assets/images/emoji/island.png b/app/assets/images/emoji/island.png Binary files differdeleted file mode 100644 index 7fd834389b7..00000000000 --- a/app/assets/images/emoji/island.png +++ /dev/null diff --git a/app/assets/images/emoji/izakaya_lantern.png b/app/assets/images/emoji/izakaya_lantern.png Binary files differdeleted file mode 100644 index dfd933f6f36..00000000000 --- a/app/assets/images/emoji/izakaya_lantern.png +++ /dev/null diff --git a/app/assets/images/emoji/jack_o_lantern.png b/app/assets/images/emoji/jack_o_lantern.png Binary files differdeleted file mode 100644 index 44c3fc0aec9..00000000000 --- a/app/assets/images/emoji/jack_o_lantern.png +++ /dev/null diff --git a/app/assets/images/emoji/japan.png b/app/assets/images/emoji/japan.png Binary files differdeleted file mode 100644 index d86d0a59e12..00000000000 --- a/app/assets/images/emoji/japan.png +++ /dev/null diff --git a/app/assets/images/emoji/japanese_castle.png b/app/assets/images/emoji/japanese_castle.png Binary files differdeleted file mode 100644 index 64b4e33a1ae..00000000000 --- a/app/assets/images/emoji/japanese_castle.png +++ /dev/null diff --git a/app/assets/images/emoji/japanese_goblin.png b/app/assets/images/emoji/japanese_goblin.png Binary files differdeleted file mode 100644 index 515c6a2250e..00000000000 --- a/app/assets/images/emoji/japanese_goblin.png +++ /dev/null diff --git a/app/assets/images/emoji/japanese_ogre.png b/app/assets/images/emoji/japanese_ogre.png Binary files differdeleted file mode 100644 index fe8670fdaf1..00000000000 --- a/app/assets/images/emoji/japanese_ogre.png +++ /dev/null diff --git a/app/assets/images/emoji/jeans.png b/app/assets/images/emoji/jeans.png Binary files differdeleted file mode 100644 index 2a6869d674c..00000000000 --- a/app/assets/images/emoji/jeans.png +++ /dev/null diff --git a/app/assets/images/emoji/joy.png b/app/assets/images/emoji/joy.png Binary files differdeleted file mode 100644 index 0ba3b1859d8..00000000000 --- a/app/assets/images/emoji/joy.png +++ /dev/null diff --git a/app/assets/images/emoji/joy_cat.png b/app/assets/images/emoji/joy_cat.png Binary files differdeleted file mode 100644 index aac353179aa..00000000000 --- a/app/assets/images/emoji/joy_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/joystick.png b/app/assets/images/emoji/joystick.png Binary files differdeleted file mode 100644 index 1ee1905434e..00000000000 --- a/app/assets/images/emoji/joystick.png +++ /dev/null diff --git a/app/assets/images/emoji/juggling.png b/app/assets/images/emoji/juggling.png Binary files differdeleted file mode 100644 index a37f6224a42..00000000000 --- a/app/assets/images/emoji/juggling.png +++ /dev/null diff --git a/app/assets/images/emoji/juggling_tone1.png b/app/assets/images/emoji/juggling_tone1.png Binary files differdeleted file mode 100644 index c18eda40031..00000000000 --- a/app/assets/images/emoji/juggling_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/juggling_tone2.png b/app/assets/images/emoji/juggling_tone2.png Binary files differdeleted file mode 100644 index de3b7a555b6..00000000000 --- a/app/assets/images/emoji/juggling_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/juggling_tone3.png b/app/assets/images/emoji/juggling_tone3.png Binary files differdeleted file mode 100644 index 74ab6d85458..00000000000 --- a/app/assets/images/emoji/juggling_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/juggling_tone4.png b/app/assets/images/emoji/juggling_tone4.png Binary files differdeleted file mode 100644 index 1c57823203f..00000000000 --- a/app/assets/images/emoji/juggling_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/juggling_tone5.png b/app/assets/images/emoji/juggling_tone5.png Binary files differdeleted file mode 100644 index c343d6ee98a..00000000000 --- a/app/assets/images/emoji/juggling_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/kaaba.png b/app/assets/images/emoji/kaaba.png Binary files differdeleted file mode 100644 index 1778c1138e4..00000000000 --- a/app/assets/images/emoji/kaaba.png +++ /dev/null diff --git a/app/assets/images/emoji/key.png b/app/assets/images/emoji/key.png Binary files differdeleted file mode 100644 index 319cd1b884c..00000000000 --- a/app/assets/images/emoji/key.png +++ /dev/null diff --git a/app/assets/images/emoji/key2.png b/app/assets/images/emoji/key2.png Binary files differdeleted file mode 100644 index e11d706c6c8..00000000000 --- a/app/assets/images/emoji/key2.png +++ /dev/null diff --git a/app/assets/images/emoji/keyboard.png b/app/assets/images/emoji/keyboard.png Binary files differdeleted file mode 100644 index 75027cb9af7..00000000000 --- a/app/assets/images/emoji/keyboard.png +++ /dev/null diff --git a/app/assets/images/emoji/kimono.png b/app/assets/images/emoji/kimono.png Binary files differdeleted file mode 100644 index abe851115d1..00000000000 --- a/app/assets/images/emoji/kimono.png +++ /dev/null diff --git a/app/assets/images/emoji/kiss.png b/app/assets/images/emoji/kiss.png Binary files differdeleted file mode 100644 index 85e6dcfc4e8..00000000000 --- a/app/assets/images/emoji/kiss.png +++ /dev/null diff --git a/app/assets/images/emoji/kiss_mm.png b/app/assets/images/emoji/kiss_mm.png Binary files differdeleted file mode 100644 index a9a0edae17c..00000000000 --- a/app/assets/images/emoji/kiss_mm.png +++ /dev/null diff --git a/app/assets/images/emoji/kiss_ww.png b/app/assets/images/emoji/kiss_ww.png Binary files differdeleted file mode 100644 index fdac73cbb1d..00000000000 --- a/app/assets/images/emoji/kiss_ww.png +++ /dev/null diff --git a/app/assets/images/emoji/kissing.png b/app/assets/images/emoji/kissing.png Binary files differdeleted file mode 100644 index 39d325fd8e3..00000000000 --- a/app/assets/images/emoji/kissing.png +++ /dev/null diff --git a/app/assets/images/emoji/kissing_cat.png b/app/assets/images/emoji/kissing_cat.png Binary files differdeleted file mode 100644 index 6e0bcc77540..00000000000 --- a/app/assets/images/emoji/kissing_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/kissing_closed_eyes.png b/app/assets/images/emoji/kissing_closed_eyes.png Binary files differdeleted file mode 100644 index b684d7d4d6c..00000000000 --- a/app/assets/images/emoji/kissing_closed_eyes.png +++ /dev/null diff --git a/app/assets/images/emoji/kissing_heart.png b/app/assets/images/emoji/kissing_heart.png Binary files differdeleted file mode 100644 index 0ff808fd614..00000000000 --- a/app/assets/images/emoji/kissing_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/kissing_smiling_eyes.png b/app/assets/images/emoji/kissing_smiling_eyes.png Binary files differdeleted file mode 100644 index e181f17099d..00000000000 --- a/app/assets/images/emoji/kissing_smiling_eyes.png +++ /dev/null diff --git a/app/assets/images/emoji/kiwi.png b/app/assets/images/emoji/kiwi.png Binary files differdeleted file mode 100644 index dfbd8258074..00000000000 --- a/app/assets/images/emoji/kiwi.png +++ /dev/null diff --git a/app/assets/images/emoji/knife.png b/app/assets/images/emoji/knife.png Binary files differdeleted file mode 100644 index 1acb9f3077b..00000000000 --- a/app/assets/images/emoji/knife.png +++ /dev/null diff --git a/app/assets/images/emoji/koala.png b/app/assets/images/emoji/koala.png Binary files differdeleted file mode 100644 index a0aa437a98c..00000000000 --- a/app/assets/images/emoji/koala.png +++ /dev/null diff --git a/app/assets/images/emoji/koko.png b/app/assets/images/emoji/koko.png Binary files differdeleted file mode 100644 index 6450eb44d90..00000000000 --- a/app/assets/images/emoji/koko.png +++ /dev/null diff --git a/app/assets/images/emoji/label.png b/app/assets/images/emoji/label.png Binary files differdeleted file mode 100644 index d41c9b4f1e1..00000000000 --- a/app/assets/images/emoji/label.png +++ /dev/null diff --git a/app/assets/images/emoji/large_blue_circle.png b/app/assets/images/emoji/large_blue_circle.png Binary files differdeleted file mode 100644 index 84078ef3127..00000000000 --- a/app/assets/images/emoji/large_blue_circle.png +++ /dev/null diff --git a/app/assets/images/emoji/large_blue_diamond.png b/app/assets/images/emoji/large_blue_diamond.png Binary files differdeleted file mode 100644 index 416a58bd5a8..00000000000 --- a/app/assets/images/emoji/large_blue_diamond.png +++ /dev/null diff --git a/app/assets/images/emoji/large_orange_diamond.png b/app/assets/images/emoji/large_orange_diamond.png Binary files differdeleted file mode 100644 index 73ff0ac36c8..00000000000 --- a/app/assets/images/emoji/large_orange_diamond.png +++ /dev/null diff --git a/app/assets/images/emoji/last_quarter_moon.png b/app/assets/images/emoji/last_quarter_moon.png Binary files differdeleted file mode 100644 index 0842a0dd408..00000000000 --- a/app/assets/images/emoji/last_quarter_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/last_quarter_moon_with_face.png b/app/assets/images/emoji/last_quarter_moon_with_face.png Binary files differdeleted file mode 100644 index 94099343c5d..00000000000 --- a/app/assets/images/emoji/last_quarter_moon_with_face.png +++ /dev/null diff --git a/app/assets/images/emoji/laughing.png b/app/assets/images/emoji/laughing.png Binary files differdeleted file mode 100644 index d94e9505ba1..00000000000 --- a/app/assets/images/emoji/laughing.png +++ /dev/null diff --git a/app/assets/images/emoji/leaves.png b/app/assets/images/emoji/leaves.png Binary files differdeleted file mode 100644 index 1e43e1af820..00000000000 --- a/app/assets/images/emoji/leaves.png +++ /dev/null diff --git a/app/assets/images/emoji/ledger.png b/app/assets/images/emoji/ledger.png Binary files differdeleted file mode 100644 index 13e7561a4bd..00000000000 --- a/app/assets/images/emoji/ledger.png +++ /dev/null diff --git a/app/assets/images/emoji/left_facing_fist.png b/app/assets/images/emoji/left_facing_fist.png Binary files differdeleted file mode 100644 index a9d9fd8d59c..00000000000 --- a/app/assets/images/emoji/left_facing_fist.png +++ /dev/null diff --git a/app/assets/images/emoji/left_facing_fist_tone1.png b/app/assets/images/emoji/left_facing_fist_tone1.png Binary files differdeleted file mode 100644 index 1262a6b4b69..00000000000 --- a/app/assets/images/emoji/left_facing_fist_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/left_facing_fist_tone2.png b/app/assets/images/emoji/left_facing_fist_tone2.png Binary files differdeleted file mode 100644 index 40bf70b82b2..00000000000 --- a/app/assets/images/emoji/left_facing_fist_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/left_facing_fist_tone3.png b/app/assets/images/emoji/left_facing_fist_tone3.png Binary files differdeleted file mode 100644 index 93f58145111..00000000000 --- a/app/assets/images/emoji/left_facing_fist_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/left_facing_fist_tone4.png b/app/assets/images/emoji/left_facing_fist_tone4.png Binary files differdeleted file mode 100644 index d82b5ec91f0..00000000000 --- a/app/assets/images/emoji/left_facing_fist_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/left_facing_fist_tone5.png b/app/assets/images/emoji/left_facing_fist_tone5.png Binary files differdeleted file mode 100644 index 09ae4cd492b..00000000000 --- a/app/assets/images/emoji/left_facing_fist_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/left_luggage.png b/app/assets/images/emoji/left_luggage.png Binary files differdeleted file mode 100644 index 887b23f3f25..00000000000 --- a/app/assets/images/emoji/left_luggage.png +++ /dev/null diff --git a/app/assets/images/emoji/left_right_arrow.png b/app/assets/images/emoji/left_right_arrow.png Binary files differdeleted file mode 100644 index 7937f24f2ac..00000000000 --- a/app/assets/images/emoji/left_right_arrow.png +++ /dev/null diff --git a/app/assets/images/emoji/leftwards_arrow_with_hook.png b/app/assets/images/emoji/leftwards_arrow_with_hook.png Binary files differdeleted file mode 100644 index ba45c2ad9e9..00000000000 --- a/app/assets/images/emoji/leftwards_arrow_with_hook.png +++ /dev/null diff --git a/app/assets/images/emoji/lemon.png b/app/assets/images/emoji/lemon.png Binary files differdeleted file mode 100644 index 9a7d95ca220..00000000000 --- a/app/assets/images/emoji/lemon.png +++ /dev/null diff --git a/app/assets/images/emoji/leo.png b/app/assets/images/emoji/leo.png Binary files differdeleted file mode 100644 index 30158d34de9..00000000000 --- a/app/assets/images/emoji/leo.png +++ /dev/null diff --git a/app/assets/images/emoji/leopard.png b/app/assets/images/emoji/leopard.png Binary files differdeleted file mode 100644 index 8aac3d49448..00000000000 --- a/app/assets/images/emoji/leopard.png +++ /dev/null diff --git a/app/assets/images/emoji/level_slider.png b/app/assets/images/emoji/level_slider.png Binary files differdeleted file mode 100644 index 720a3b34119..00000000000 --- a/app/assets/images/emoji/level_slider.png +++ /dev/null diff --git a/app/assets/images/emoji/levitate.png b/app/assets/images/emoji/levitate.png Binary files differdeleted file mode 100644 index 3dc315a3d91..00000000000 --- a/app/assets/images/emoji/levitate.png +++ /dev/null diff --git a/app/assets/images/emoji/libra.png b/app/assets/images/emoji/libra.png Binary files differdeleted file mode 100644 index 8fd133a357c..00000000000 --- a/app/assets/images/emoji/libra.png +++ /dev/null diff --git a/app/assets/images/emoji/lifter.png b/app/assets/images/emoji/lifter.png Binary files differdeleted file mode 100644 index afdeaa476af..00000000000 --- a/app/assets/images/emoji/lifter.png +++ /dev/null diff --git a/app/assets/images/emoji/lifter_tone1.png b/app/assets/images/emoji/lifter_tone1.png Binary files differdeleted file mode 100644 index febaad123ec..00000000000 --- a/app/assets/images/emoji/lifter_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/lifter_tone2.png b/app/assets/images/emoji/lifter_tone2.png Binary files differdeleted file mode 100644 index 27ae794a18e..00000000000 --- a/app/assets/images/emoji/lifter_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/lifter_tone3.png b/app/assets/images/emoji/lifter_tone3.png Binary files differdeleted file mode 100644 index 45c4c22c709..00000000000 --- a/app/assets/images/emoji/lifter_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/lifter_tone4.png b/app/assets/images/emoji/lifter_tone4.png Binary files differdeleted file mode 100644 index 67dd21d2464..00000000000 --- a/app/assets/images/emoji/lifter_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/lifter_tone5.png b/app/assets/images/emoji/lifter_tone5.png Binary files differdeleted file mode 100644 index fa0152038b6..00000000000 --- a/app/assets/images/emoji/lifter_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/light_rail.png b/app/assets/images/emoji/light_rail.png Binary files differdeleted file mode 100644 index a64829f5078..00000000000 --- a/app/assets/images/emoji/light_rail.png +++ /dev/null diff --git a/app/assets/images/emoji/link.png b/app/assets/images/emoji/link.png Binary files differdeleted file mode 100644 index ae20f0f8eec..00000000000 --- a/app/assets/images/emoji/link.png +++ /dev/null diff --git a/app/assets/images/emoji/lion_face.png b/app/assets/images/emoji/lion_face.png Binary files differdeleted file mode 100644 index 5062ab47ecf..00000000000 --- a/app/assets/images/emoji/lion_face.png +++ /dev/null diff --git a/app/assets/images/emoji/lips.png b/app/assets/images/emoji/lips.png Binary files differdeleted file mode 100644 index 35f3cc2006f..00000000000 --- a/app/assets/images/emoji/lips.png +++ /dev/null diff --git a/app/assets/images/emoji/lipstick.png b/app/assets/images/emoji/lipstick.png Binary files differdeleted file mode 100644 index 61a0c084c99..00000000000 --- a/app/assets/images/emoji/lipstick.png +++ /dev/null diff --git a/app/assets/images/emoji/lizard.png b/app/assets/images/emoji/lizard.png Binary files differdeleted file mode 100644 index 8363876050e..00000000000 --- a/app/assets/images/emoji/lizard.png +++ /dev/null diff --git a/app/assets/images/emoji/lock.png b/app/assets/images/emoji/lock.png Binary files differdeleted file mode 100644 index 5a739c46644..00000000000 --- a/app/assets/images/emoji/lock.png +++ /dev/null diff --git a/app/assets/images/emoji/lock_with_ink_pen.png b/app/assets/images/emoji/lock_with_ink_pen.png Binary files differdeleted file mode 100644 index 19a07d162fb..00000000000 --- a/app/assets/images/emoji/lock_with_ink_pen.png +++ /dev/null diff --git a/app/assets/images/emoji/lollipop.png b/app/assets/images/emoji/lollipop.png Binary files differdeleted file mode 100644 index ad76d7bf916..00000000000 --- a/app/assets/images/emoji/lollipop.png +++ /dev/null diff --git a/app/assets/images/emoji/loop.png b/app/assets/images/emoji/loop.png Binary files differdeleted file mode 100644 index 0b82c8fe315..00000000000 --- a/app/assets/images/emoji/loop.png +++ /dev/null diff --git a/app/assets/images/emoji/loud_sound.png b/app/assets/images/emoji/loud_sound.png Binary files differdeleted file mode 100644 index 8370033a539..00000000000 --- a/app/assets/images/emoji/loud_sound.png +++ /dev/null diff --git a/app/assets/images/emoji/loudspeaker.png b/app/assets/images/emoji/loudspeaker.png Binary files differdeleted file mode 100644 index 5fd76a95b82..00000000000 --- a/app/assets/images/emoji/loudspeaker.png +++ /dev/null diff --git a/app/assets/images/emoji/love_hotel.png b/app/assets/images/emoji/love_hotel.png Binary files differdeleted file mode 100644 index 5e136be6f8b..00000000000 --- a/app/assets/images/emoji/love_hotel.png +++ /dev/null diff --git a/app/assets/images/emoji/love_letter.png b/app/assets/images/emoji/love_letter.png Binary files differdeleted file mode 100644 index 3c3c767e784..00000000000 --- a/app/assets/images/emoji/love_letter.png +++ /dev/null diff --git a/app/assets/images/emoji/low_brightness.png b/app/assets/images/emoji/low_brightness.png Binary files differdeleted file mode 100644 index 543011d3961..00000000000 --- a/app/assets/images/emoji/low_brightness.png +++ /dev/null diff --git a/app/assets/images/emoji/lying_face.png b/app/assets/images/emoji/lying_face.png Binary files differdeleted file mode 100644 index 02827e2628b..00000000000 --- a/app/assets/images/emoji/lying_face.png +++ /dev/null diff --git a/app/assets/images/emoji/m.png b/app/assets/images/emoji/m.png Binary files differdeleted file mode 100644 index 8a3506fc1d7..00000000000 --- a/app/assets/images/emoji/m.png +++ /dev/null diff --git a/app/assets/images/emoji/mag.png b/app/assets/images/emoji/mag.png Binary files differdeleted file mode 100644 index 55487156ac6..00000000000 --- a/app/assets/images/emoji/mag.png +++ /dev/null diff --git a/app/assets/images/emoji/mag_right.png b/app/assets/images/emoji/mag_right.png Binary files differdeleted file mode 100644 index 0f4b1bca876..00000000000 --- a/app/assets/images/emoji/mag_right.png +++ /dev/null diff --git a/app/assets/images/emoji/mahjong.png b/app/assets/images/emoji/mahjong.png Binary files differdeleted file mode 100644 index 66fd32025b2..00000000000 --- a/app/assets/images/emoji/mahjong.png +++ /dev/null diff --git a/app/assets/images/emoji/mailbox.png b/app/assets/images/emoji/mailbox.png Binary files differdeleted file mode 100644 index ef5174e40dd..00000000000 --- a/app/assets/images/emoji/mailbox.png +++ /dev/null diff --git a/app/assets/images/emoji/mailbox_closed.png b/app/assets/images/emoji/mailbox_closed.png Binary files differdeleted file mode 100644 index ddc705db0d8..00000000000 --- a/app/assets/images/emoji/mailbox_closed.png +++ /dev/null diff --git a/app/assets/images/emoji/mailbox_with_mail.png b/app/assets/images/emoji/mailbox_with_mail.png Binary files differdeleted file mode 100644 index 5460616a5b1..00000000000 --- a/app/assets/images/emoji/mailbox_with_mail.png +++ /dev/null diff --git a/app/assets/images/emoji/mailbox_with_no_mail.png b/app/assets/images/emoji/mailbox_with_no_mail.png Binary files differdeleted file mode 100644 index f9aeee6b15a..00000000000 --- a/app/assets/images/emoji/mailbox_with_no_mail.png +++ /dev/null diff --git a/app/assets/images/emoji/man.png b/app/assets/images/emoji/man.png Binary files differdeleted file mode 100644 index 857a02e5146..00000000000 --- a/app/assets/images/emoji/man.png +++ /dev/null diff --git a/app/assets/images/emoji/man_dancing.png b/app/assets/images/emoji/man_dancing.png Binary files differdeleted file mode 100644 index ccff3bede5a..00000000000 --- a/app/assets/images/emoji/man_dancing.png +++ /dev/null diff --git a/app/assets/images/emoji/man_dancing_tone1.png b/app/assets/images/emoji/man_dancing_tone1.png Binary files differdeleted file mode 100644 index e0b9f82d905..00000000000 --- a/app/assets/images/emoji/man_dancing_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/man_dancing_tone2.png b/app/assets/images/emoji/man_dancing_tone2.png Binary files differdeleted file mode 100644 index a5beed56e2e..00000000000 --- a/app/assets/images/emoji/man_dancing_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/man_dancing_tone3.png b/app/assets/images/emoji/man_dancing_tone3.png Binary files differdeleted file mode 100644 index 2fa20180a6e..00000000000 --- a/app/assets/images/emoji/man_dancing_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/man_dancing_tone4.png b/app/assets/images/emoji/man_dancing_tone4.png Binary files differdeleted file mode 100644 index bd3528c83ba..00000000000 --- a/app/assets/images/emoji/man_dancing_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/man_dancing_tone5.png b/app/assets/images/emoji/man_dancing_tone5.png Binary files differdeleted file mode 100644 index 41fd4f880c9..00000000000 --- a/app/assets/images/emoji/man_dancing_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/man_in_tuxedo.png b/app/assets/images/emoji/man_in_tuxedo.png Binary files differdeleted file mode 100644 index 5f7e9303f89..00000000000 --- a/app/assets/images/emoji/man_in_tuxedo.png +++ /dev/null diff --git a/app/assets/images/emoji/man_in_tuxedo_tone1.png b/app/assets/images/emoji/man_in_tuxedo_tone1.png Binary files differdeleted file mode 100644 index 7b6b3acd99b..00000000000 --- a/app/assets/images/emoji/man_in_tuxedo_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/man_in_tuxedo_tone2.png b/app/assets/images/emoji/man_in_tuxedo_tone2.png Binary files differdeleted file mode 100644 index 7975191b360..00000000000 --- a/app/assets/images/emoji/man_in_tuxedo_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/man_in_tuxedo_tone3.png b/app/assets/images/emoji/man_in_tuxedo_tone3.png Binary files differdeleted file mode 100644 index a2816f600ae..00000000000 --- a/app/assets/images/emoji/man_in_tuxedo_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/man_in_tuxedo_tone4.png b/app/assets/images/emoji/man_in_tuxedo_tone4.png Binary files differdeleted file mode 100644 index ea8291760f9..00000000000 --- a/app/assets/images/emoji/man_in_tuxedo_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/man_in_tuxedo_tone5.png b/app/assets/images/emoji/man_in_tuxedo_tone5.png Binary files differdeleted file mode 100644 index c743e05fc5e..00000000000 --- a/app/assets/images/emoji/man_in_tuxedo_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/man_tone1.png b/app/assets/images/emoji/man_tone1.png Binary files differdeleted file mode 100644 index bb86e963a80..00000000000 --- a/app/assets/images/emoji/man_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/man_tone2.png b/app/assets/images/emoji/man_tone2.png Binary files differdeleted file mode 100644 index fdeeaff46f5..00000000000 --- a/app/assets/images/emoji/man_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/man_tone3.png b/app/assets/images/emoji/man_tone3.png Binary files differdeleted file mode 100644 index 7ae0b5df9cf..00000000000 --- a/app/assets/images/emoji/man_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/man_tone4.png b/app/assets/images/emoji/man_tone4.png Binary files differdeleted file mode 100644 index db14cde99b8..00000000000 --- a/app/assets/images/emoji/man_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/man_tone5.png b/app/assets/images/emoji/man_tone5.png Binary files differdeleted file mode 100644 index 7c67a70529c..00000000000 --- a/app/assets/images/emoji/man_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_gua_pi_mao.png b/app/assets/images/emoji/man_with_gua_pi_mao.png Binary files differdeleted file mode 100644 index 7841e13608d..00000000000 --- a/app/assets/images/emoji/man_with_gua_pi_mao.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png Binary files differdeleted file mode 100644 index 5b7b3def19c..00000000000 --- a/app/assets/images/emoji/man_with_gua_pi_mao_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png Binary files differdeleted file mode 100644 index c8b9cf87f4b..00000000000 --- a/app/assets/images/emoji/man_with_gua_pi_mao_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png Binary files differdeleted file mode 100644 index effdd0c4c84..00000000000 --- a/app/assets/images/emoji/man_with_gua_pi_mao_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png Binary files differdeleted file mode 100644 index f885ff46fa1..00000000000 --- a/app/assets/images/emoji/man_with_gua_pi_mao_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png b/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png Binary files differdeleted file mode 100644 index a6d55ca1380..00000000000 --- a/app/assets/images/emoji/man_with_gua_pi_mao_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_turban.png b/app/assets/images/emoji/man_with_turban.png Binary files differdeleted file mode 100644 index 51cf047f966..00000000000 --- a/app/assets/images/emoji/man_with_turban.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_turban_tone1.png b/app/assets/images/emoji/man_with_turban_tone1.png Binary files differdeleted file mode 100644 index 1e12ee4b231..00000000000 --- a/app/assets/images/emoji/man_with_turban_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_turban_tone2.png b/app/assets/images/emoji/man_with_turban_tone2.png Binary files differdeleted file mode 100644 index 37de4cceb23..00000000000 --- a/app/assets/images/emoji/man_with_turban_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_turban_tone3.png b/app/assets/images/emoji/man_with_turban_tone3.png Binary files differdeleted file mode 100644 index f607afd3450..00000000000 --- a/app/assets/images/emoji/man_with_turban_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_turban_tone4.png b/app/assets/images/emoji/man_with_turban_tone4.png Binary files differdeleted file mode 100644 index c05695888af..00000000000 --- a/app/assets/images/emoji/man_with_turban_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/man_with_turban_tone5.png b/app/assets/images/emoji/man_with_turban_tone5.png Binary files differdeleted file mode 100644 index 4b4ff64720b..00000000000 --- a/app/assets/images/emoji/man_with_turban_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/mans_shoe.png b/app/assets/images/emoji/mans_shoe.png Binary files differdeleted file mode 100644 index 4bf7541032c..00000000000 --- a/app/assets/images/emoji/mans_shoe.png +++ /dev/null diff --git a/app/assets/images/emoji/map.png b/app/assets/images/emoji/map.png Binary files differdeleted file mode 100644 index 15efe32c798..00000000000 --- a/app/assets/images/emoji/map.png +++ /dev/null diff --git a/app/assets/images/emoji/maple_leaf.png b/app/assets/images/emoji/maple_leaf.png Binary files differdeleted file mode 100644 index c49acea67f7..00000000000 --- a/app/assets/images/emoji/maple_leaf.png +++ /dev/null diff --git a/app/assets/images/emoji/martial_arts_uniform.png b/app/assets/images/emoji/martial_arts_uniform.png Binary files differdeleted file mode 100644 index 8d6114761f6..00000000000 --- a/app/assets/images/emoji/martial_arts_uniform.png +++ /dev/null diff --git a/app/assets/images/emoji/mask.png b/app/assets/images/emoji/mask.png Binary files differdeleted file mode 100644 index 1e800acd1c0..00000000000 --- a/app/assets/images/emoji/mask.png +++ /dev/null diff --git a/app/assets/images/emoji/massage.png b/app/assets/images/emoji/massage.png Binary files differdeleted file mode 100644 index b91d845e374..00000000000 --- a/app/assets/images/emoji/massage.png +++ /dev/null diff --git a/app/assets/images/emoji/massage_tone1.png b/app/assets/images/emoji/massage_tone1.png Binary files differdeleted file mode 100644 index e0f415d3186..00000000000 --- a/app/assets/images/emoji/massage_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/massage_tone2.png b/app/assets/images/emoji/massage_tone2.png Binary files differdeleted file mode 100644 index 0bb244a270b..00000000000 --- a/app/assets/images/emoji/massage_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/massage_tone3.png b/app/assets/images/emoji/massage_tone3.png Binary files differdeleted file mode 100644 index a117ee81a22..00000000000 --- a/app/assets/images/emoji/massage_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/massage_tone4.png b/app/assets/images/emoji/massage_tone4.png Binary files differdeleted file mode 100644 index 6f42ab017f4..00000000000 --- a/app/assets/images/emoji/massage_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/massage_tone5.png b/app/assets/images/emoji/massage_tone5.png Binary files differdeleted file mode 100644 index 6a388c0d0b5..00000000000 --- a/app/assets/images/emoji/massage_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/meat_on_bone.png b/app/assets/images/emoji/meat_on_bone.png Binary files differdeleted file mode 100644 index b20a59d1690..00000000000 --- a/app/assets/images/emoji/meat_on_bone.png +++ /dev/null diff --git a/app/assets/images/emoji/medal.png b/app/assets/images/emoji/medal.png Binary files differdeleted file mode 100644 index b85896b14da..00000000000 --- a/app/assets/images/emoji/medal.png +++ /dev/null diff --git a/app/assets/images/emoji/mega.png b/app/assets/images/emoji/mega.png Binary files differdeleted file mode 100644 index 4e6735188e3..00000000000 --- a/app/assets/images/emoji/mega.png +++ /dev/null diff --git a/app/assets/images/emoji/melon.png b/app/assets/images/emoji/melon.png Binary files differdeleted file mode 100644 index c01232d419d..00000000000 --- a/app/assets/images/emoji/melon.png +++ /dev/null diff --git a/app/assets/images/emoji/menorah.png b/app/assets/images/emoji/menorah.png Binary files differdeleted file mode 100644 index b4297362869..00000000000 --- a/app/assets/images/emoji/menorah.png +++ /dev/null diff --git a/app/assets/images/emoji/mens.png b/app/assets/images/emoji/mens.png Binary files differdeleted file mode 100644 index f5a1e1ba0cd..00000000000 --- a/app/assets/images/emoji/mens.png +++ /dev/null diff --git a/app/assets/images/emoji/metal.png b/app/assets/images/emoji/metal.png Binary files differdeleted file mode 100644 index 4aa6e7e0a44..00000000000 --- a/app/assets/images/emoji/metal.png +++ /dev/null diff --git a/app/assets/images/emoji/metal_tone1.png b/app/assets/images/emoji/metal_tone1.png Binary files differdeleted file mode 100644 index c080d2addbd..00000000000 --- a/app/assets/images/emoji/metal_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/metal_tone2.png b/app/assets/images/emoji/metal_tone2.png Binary files differdeleted file mode 100644 index 12313529bcf..00000000000 --- a/app/assets/images/emoji/metal_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/metal_tone3.png b/app/assets/images/emoji/metal_tone3.png Binary files differdeleted file mode 100644 index ca9be6ae67b..00000000000 --- a/app/assets/images/emoji/metal_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/metal_tone4.png b/app/assets/images/emoji/metal_tone4.png Binary files differdeleted file mode 100644 index abe28cbf890..00000000000 --- a/app/assets/images/emoji/metal_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/metal_tone5.png b/app/assets/images/emoji/metal_tone5.png Binary files differdeleted file mode 100644 index 0c6b5dd34ed..00000000000 --- a/app/assets/images/emoji/metal_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/metro.png b/app/assets/images/emoji/metro.png Binary files differdeleted file mode 100644 index 1de8f0551f3..00000000000 --- a/app/assets/images/emoji/metro.png +++ /dev/null diff --git a/app/assets/images/emoji/microphone.png b/app/assets/images/emoji/microphone.png Binary files differdeleted file mode 100644 index d4e6b0def25..00000000000 --- a/app/assets/images/emoji/microphone.png +++ /dev/null diff --git a/app/assets/images/emoji/microphone2.png b/app/assets/images/emoji/microphone2.png Binary files differdeleted file mode 100644 index cd9167654ff..00000000000 --- a/app/assets/images/emoji/microphone2.png +++ /dev/null diff --git a/app/assets/images/emoji/microscope.png b/app/assets/images/emoji/microscope.png Binary files differdeleted file mode 100644 index 90f5acf6a78..00000000000 --- a/app/assets/images/emoji/microscope.png +++ /dev/null diff --git a/app/assets/images/emoji/middle_finger.png b/app/assets/images/emoji/middle_finger.png Binary files differdeleted file mode 100644 index 697f7a25eb2..00000000000 --- a/app/assets/images/emoji/middle_finger.png +++ /dev/null diff --git a/app/assets/images/emoji/middle_finger_tone1.png b/app/assets/images/emoji/middle_finger_tone1.png Binary files differdeleted file mode 100644 index 61ef12a1548..00000000000 --- a/app/assets/images/emoji/middle_finger_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/middle_finger_tone2.png b/app/assets/images/emoji/middle_finger_tone2.png Binary files differdeleted file mode 100644 index c31a69be9af..00000000000 --- a/app/assets/images/emoji/middle_finger_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/middle_finger_tone3.png b/app/assets/images/emoji/middle_finger_tone3.png Binary files differdeleted file mode 100644 index 73ac216ce63..00000000000 --- a/app/assets/images/emoji/middle_finger_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/middle_finger_tone4.png b/app/assets/images/emoji/middle_finger_tone4.png Binary files differdeleted file mode 100644 index 80b8ab7706d..00000000000 --- a/app/assets/images/emoji/middle_finger_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/middle_finger_tone5.png b/app/assets/images/emoji/middle_finger_tone5.png Binary files differdeleted file mode 100644 index a8826b196e8..00000000000 --- a/app/assets/images/emoji/middle_finger_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/military_medal.png b/app/assets/images/emoji/military_medal.png Binary files differdeleted file mode 100644 index ecd3fb03584..00000000000 --- a/app/assets/images/emoji/military_medal.png +++ /dev/null diff --git a/app/assets/images/emoji/milk.png b/app/assets/images/emoji/milk.png Binary files differdeleted file mode 100644 index e4fcf2e64f3..00000000000 --- a/app/assets/images/emoji/milk.png +++ /dev/null diff --git a/app/assets/images/emoji/milky_way.png b/app/assets/images/emoji/milky_way.png Binary files differdeleted file mode 100644 index b2b8ac59c5e..00000000000 --- a/app/assets/images/emoji/milky_way.png +++ /dev/null diff --git a/app/assets/images/emoji/minibus.png b/app/assets/images/emoji/minibus.png Binary files differdeleted file mode 100644 index c60dd8f47ab..00000000000 --- a/app/assets/images/emoji/minibus.png +++ /dev/null diff --git a/app/assets/images/emoji/minidisc.png b/app/assets/images/emoji/minidisc.png Binary files differdeleted file mode 100644 index 9fa94cfbe74..00000000000 --- a/app/assets/images/emoji/minidisc.png +++ /dev/null diff --git a/app/assets/images/emoji/mobile_phone_off.png b/app/assets/images/emoji/mobile_phone_off.png Binary files differdeleted file mode 100644 index 8b661ec1c94..00000000000 --- a/app/assets/images/emoji/mobile_phone_off.png +++ /dev/null diff --git a/app/assets/images/emoji/money_mouth.png b/app/assets/images/emoji/money_mouth.png Binary files differdeleted file mode 100644 index 75fd1e90cb0..00000000000 --- a/app/assets/images/emoji/money_mouth.png +++ /dev/null diff --git a/app/assets/images/emoji/money_with_wings.png b/app/assets/images/emoji/money_with_wings.png Binary files differdeleted file mode 100644 index f022b04b3c2..00000000000 --- a/app/assets/images/emoji/money_with_wings.png +++ /dev/null diff --git a/app/assets/images/emoji/moneybag.png b/app/assets/images/emoji/moneybag.png Binary files differdeleted file mode 100644 index b9296be0902..00000000000 --- a/app/assets/images/emoji/moneybag.png +++ /dev/null diff --git a/app/assets/images/emoji/monkey.png b/app/assets/images/emoji/monkey.png Binary files differdeleted file mode 100644 index 9fae29448e3..00000000000 --- a/app/assets/images/emoji/monkey.png +++ /dev/null diff --git a/app/assets/images/emoji/monkey_face.png b/app/assets/images/emoji/monkey_face.png Binary files differdeleted file mode 100644 index 7cab9b91a82..00000000000 --- a/app/assets/images/emoji/monkey_face.png +++ /dev/null diff --git a/app/assets/images/emoji/monorail.png b/app/assets/images/emoji/monorail.png Binary files differdeleted file mode 100644 index 11eb1f574bf..00000000000 --- a/app/assets/images/emoji/monorail.png +++ /dev/null diff --git a/app/assets/images/emoji/mortar_board.png b/app/assets/images/emoji/mortar_board.png Binary files differdeleted file mode 100644 index 8b17ddd9d00..00000000000 --- a/app/assets/images/emoji/mortar_board.png +++ /dev/null diff --git a/app/assets/images/emoji/mosque.png b/app/assets/images/emoji/mosque.png Binary files differdeleted file mode 100644 index ef770b26d96..00000000000 --- a/app/assets/images/emoji/mosque.png +++ /dev/null diff --git a/app/assets/images/emoji/motor_scooter.png b/app/assets/images/emoji/motor_scooter.png Binary files differdeleted file mode 100644 index c5afa72d807..00000000000 --- a/app/assets/images/emoji/motor_scooter.png +++ /dev/null diff --git a/app/assets/images/emoji/motorboat.png b/app/assets/images/emoji/motorboat.png Binary files differdeleted file mode 100644 index 0506db1a40f..00000000000 --- a/app/assets/images/emoji/motorboat.png +++ /dev/null diff --git a/app/assets/images/emoji/motorcycle.png b/app/assets/images/emoji/motorcycle.png Binary files differdeleted file mode 100644 index 3d1d567e8ec..00000000000 --- a/app/assets/images/emoji/motorcycle.png +++ /dev/null diff --git a/app/assets/images/emoji/motorway.png b/app/assets/images/emoji/motorway.png Binary files differdeleted file mode 100644 index 8c3d3d03e3f..00000000000 --- a/app/assets/images/emoji/motorway.png +++ /dev/null diff --git a/app/assets/images/emoji/mount_fuji.png b/app/assets/images/emoji/mount_fuji.png Binary files differdeleted file mode 100644 index 88a54752458..00000000000 --- a/app/assets/images/emoji/mount_fuji.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain.png b/app/assets/images/emoji/mountain.png Binary files differdeleted file mode 100644 index 6722ebdd294..00000000000 --- a/app/assets/images/emoji/mountain.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_bicyclist.png b/app/assets/images/emoji/mountain_bicyclist.png Binary files differdeleted file mode 100644 index 41d3dc3ac6f..00000000000 --- a/app/assets/images/emoji/mountain_bicyclist.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_bicyclist_tone1.png b/app/assets/images/emoji/mountain_bicyclist_tone1.png Binary files differdeleted file mode 100644 index e9f1daf5e40..00000000000 --- a/app/assets/images/emoji/mountain_bicyclist_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_bicyclist_tone2.png b/app/assets/images/emoji/mountain_bicyclist_tone2.png Binary files differdeleted file mode 100644 index 555b9e29d4d..00000000000 --- a/app/assets/images/emoji/mountain_bicyclist_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_bicyclist_tone3.png b/app/assets/images/emoji/mountain_bicyclist_tone3.png Binary files differdeleted file mode 100644 index 7df5508ec8c..00000000000 --- a/app/assets/images/emoji/mountain_bicyclist_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_bicyclist_tone4.png b/app/assets/images/emoji/mountain_bicyclist_tone4.png Binary files differdeleted file mode 100644 index f94b3450697..00000000000 --- a/app/assets/images/emoji/mountain_bicyclist_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_bicyclist_tone5.png b/app/assets/images/emoji/mountain_bicyclist_tone5.png Binary files differdeleted file mode 100644 index 16a45861e1f..00000000000 --- a/app/assets/images/emoji/mountain_bicyclist_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_cableway.png b/app/assets/images/emoji/mountain_cableway.png Binary files differdeleted file mode 100644 index 1dea73ca53b..00000000000 --- a/app/assets/images/emoji/mountain_cableway.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_railway.png b/app/assets/images/emoji/mountain_railway.png Binary files differdeleted file mode 100644 index ade2218e469..00000000000 --- a/app/assets/images/emoji/mountain_railway.png +++ /dev/null diff --git a/app/assets/images/emoji/mountain_snow.png b/app/assets/images/emoji/mountain_snow.png Binary files differdeleted file mode 100644 index 76e1cfd8313..00000000000 --- a/app/assets/images/emoji/mountain_snow.png +++ /dev/null diff --git a/app/assets/images/emoji/mouse.png b/app/assets/images/emoji/mouse.png Binary files differdeleted file mode 100644 index 50afcd3262e..00000000000 --- a/app/assets/images/emoji/mouse.png +++ /dev/null diff --git a/app/assets/images/emoji/mouse2.png b/app/assets/images/emoji/mouse2.png Binary files differdeleted file mode 100644 index 20fb041f09f..00000000000 --- a/app/assets/images/emoji/mouse2.png +++ /dev/null diff --git a/app/assets/images/emoji/mouse_three_button.png b/app/assets/images/emoji/mouse_three_button.png Binary files differdeleted file mode 100644 index e84e96ff6e8..00000000000 --- a/app/assets/images/emoji/mouse_three_button.png +++ /dev/null diff --git a/app/assets/images/emoji/movie_camera.png b/app/assets/images/emoji/movie_camera.png Binary files differdeleted file mode 100644 index 4e73b130155..00000000000 --- a/app/assets/images/emoji/movie_camera.png +++ /dev/null diff --git a/app/assets/images/emoji/moyai.png b/app/assets/images/emoji/moyai.png Binary files differdeleted file mode 100644 index e6a7779c45b..00000000000 --- a/app/assets/images/emoji/moyai.png +++ /dev/null diff --git a/app/assets/images/emoji/mrs_claus.png b/app/assets/images/emoji/mrs_claus.png Binary files differdeleted file mode 100644 index 9cf2458df1a..00000000000 --- a/app/assets/images/emoji/mrs_claus.png +++ /dev/null diff --git a/app/assets/images/emoji/mrs_claus_tone1.png b/app/assets/images/emoji/mrs_claus_tone1.png Binary files differdeleted file mode 100644 index d8a695d7035..00000000000 --- a/app/assets/images/emoji/mrs_claus_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/mrs_claus_tone2.png b/app/assets/images/emoji/mrs_claus_tone2.png Binary files differdeleted file mode 100644 index 0e17e8c51f3..00000000000 --- a/app/assets/images/emoji/mrs_claus_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/mrs_claus_tone3.png b/app/assets/images/emoji/mrs_claus_tone3.png Binary files differdeleted file mode 100644 index c3ee4d1dfae..00000000000 --- a/app/assets/images/emoji/mrs_claus_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/mrs_claus_tone4.png b/app/assets/images/emoji/mrs_claus_tone4.png Binary files differdeleted file mode 100644 index 68a556da2fe..00000000000 --- a/app/assets/images/emoji/mrs_claus_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/mrs_claus_tone5.png b/app/assets/images/emoji/mrs_claus_tone5.png Binary files differdeleted file mode 100644 index ccab3c40ff2..00000000000 --- a/app/assets/images/emoji/mrs_claus_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/muscle.png b/app/assets/images/emoji/muscle.png Binary files differdeleted file mode 100644 index 7e67c1880f7..00000000000 --- a/app/assets/images/emoji/muscle.png +++ /dev/null diff --git a/app/assets/images/emoji/muscle_tone1.png b/app/assets/images/emoji/muscle_tone1.png Binary files differdeleted file mode 100644 index 1522942ce51..00000000000 --- a/app/assets/images/emoji/muscle_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/muscle_tone2.png b/app/assets/images/emoji/muscle_tone2.png Binary files differdeleted file mode 100644 index 569c6e832ca..00000000000 --- a/app/assets/images/emoji/muscle_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/muscle_tone3.png b/app/assets/images/emoji/muscle_tone3.png Binary files differdeleted file mode 100644 index 0a76b00fa89..00000000000 --- a/app/assets/images/emoji/muscle_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/muscle_tone4.png b/app/assets/images/emoji/muscle_tone4.png Binary files differdeleted file mode 100644 index f0cf31328e0..00000000000 --- a/app/assets/images/emoji/muscle_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/muscle_tone5.png b/app/assets/images/emoji/muscle_tone5.png Binary files differdeleted file mode 100644 index 4fda92460e8..00000000000 --- a/app/assets/images/emoji/muscle_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/mushroom.png b/app/assets/images/emoji/mushroom.png Binary files differdeleted file mode 100644 index dd85742ba2c..00000000000 --- a/app/assets/images/emoji/mushroom.png +++ /dev/null diff --git a/app/assets/images/emoji/musical_keyboard.png b/app/assets/images/emoji/musical_keyboard.png Binary files differdeleted file mode 100644 index 442b7456842..00000000000 --- a/app/assets/images/emoji/musical_keyboard.png +++ /dev/null diff --git a/app/assets/images/emoji/musical_note.png b/app/assets/images/emoji/musical_note.png Binary files differdeleted file mode 100644 index 06691ef61bb..00000000000 --- a/app/assets/images/emoji/musical_note.png +++ /dev/null diff --git a/app/assets/images/emoji/musical_score.png b/app/assets/images/emoji/musical_score.png Binary files differdeleted file mode 100644 index 47dc05a8ef5..00000000000 --- a/app/assets/images/emoji/musical_score.png +++ /dev/null diff --git a/app/assets/images/emoji/mute.png b/app/assets/images/emoji/mute.png Binary files differdeleted file mode 100644 index 7c1788e5075..00000000000 --- a/app/assets/images/emoji/mute.png +++ /dev/null diff --git a/app/assets/images/emoji/nail_care.png b/app/assets/images/emoji/nail_care.png Binary files differdeleted file mode 100644 index aa52af7050d..00000000000 --- a/app/assets/images/emoji/nail_care.png +++ /dev/null diff --git a/app/assets/images/emoji/nail_care_tone1.png b/app/assets/images/emoji/nail_care_tone1.png Binary files differdeleted file mode 100644 index 26e883dd244..00000000000 --- a/app/assets/images/emoji/nail_care_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/nail_care_tone2.png b/app/assets/images/emoji/nail_care_tone2.png Binary files differdeleted file mode 100644 index 61257b47ea3..00000000000 --- a/app/assets/images/emoji/nail_care_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/nail_care_tone3.png b/app/assets/images/emoji/nail_care_tone3.png Binary files differdeleted file mode 100644 index 29871b05f62..00000000000 --- a/app/assets/images/emoji/nail_care_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/nail_care_tone4.png b/app/assets/images/emoji/nail_care_tone4.png Binary files differdeleted file mode 100644 index 2881de0b17d..00000000000 --- a/app/assets/images/emoji/nail_care_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/nail_care_tone5.png b/app/assets/images/emoji/nail_care_tone5.png Binary files differdeleted file mode 100644 index a0b7c0a45a6..00000000000 --- a/app/assets/images/emoji/nail_care_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/name_badge.png b/app/assets/images/emoji/name_badge.png Binary files differdeleted file mode 100644 index ec5ee213e20..00000000000 --- a/app/assets/images/emoji/name_badge.png +++ /dev/null diff --git a/app/assets/images/emoji/nauseated_face.png b/app/assets/images/emoji/nauseated_face.png Binary files differdeleted file mode 100644 index a566c109c28..00000000000 --- a/app/assets/images/emoji/nauseated_face.png +++ /dev/null diff --git a/app/assets/images/emoji/necktie.png b/app/assets/images/emoji/necktie.png Binary files differdeleted file mode 100644 index 1804e7f3ff3..00000000000 --- a/app/assets/images/emoji/necktie.png +++ /dev/null diff --git a/app/assets/images/emoji/negative_squared_cross_mark.png b/app/assets/images/emoji/negative_squared_cross_mark.png Binary files differdeleted file mode 100644 index dae487f1f98..00000000000 --- a/app/assets/images/emoji/negative_squared_cross_mark.png +++ /dev/null diff --git a/app/assets/images/emoji/nerd.png b/app/assets/images/emoji/nerd.png Binary files differdeleted file mode 100644 index 7820bd581dc..00000000000 --- a/app/assets/images/emoji/nerd.png +++ /dev/null diff --git a/app/assets/images/emoji/neutral_face.png b/app/assets/images/emoji/neutral_face.png Binary files differdeleted file mode 100644 index 065d193afe4..00000000000 --- a/app/assets/images/emoji/neutral_face.png +++ /dev/null diff --git a/app/assets/images/emoji/new.png b/app/assets/images/emoji/new.png Binary files differdeleted file mode 100644 index b4f85488d1a..00000000000 --- a/app/assets/images/emoji/new.png +++ /dev/null diff --git a/app/assets/images/emoji/new_moon.png b/app/assets/images/emoji/new_moon.png Binary files differdeleted file mode 100644 index ecff72caa42..00000000000 --- a/app/assets/images/emoji/new_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/new_moon_with_face.png b/app/assets/images/emoji/new_moon_with_face.png Binary files differdeleted file mode 100644 index 150dd12400c..00000000000 --- a/app/assets/images/emoji/new_moon_with_face.png +++ /dev/null diff --git a/app/assets/images/emoji/newspaper.png b/app/assets/images/emoji/newspaper.png Binary files differdeleted file mode 100644 index 2aa8f060bde..00000000000 --- a/app/assets/images/emoji/newspaper.png +++ /dev/null diff --git a/app/assets/images/emoji/newspaper2.png b/app/assets/images/emoji/newspaper2.png Binary files differdeleted file mode 100644 index f64748df2b2..00000000000 --- a/app/assets/images/emoji/newspaper2.png +++ /dev/null diff --git a/app/assets/images/emoji/ng.png b/app/assets/images/emoji/ng.png Binary files differdeleted file mode 100644 index ee8d20f5ebc..00000000000 --- a/app/assets/images/emoji/ng.png +++ /dev/null diff --git a/app/assets/images/emoji/night_with_stars.png b/app/assets/images/emoji/night_with_stars.png Binary files differdeleted file mode 100644 index ca2018f456d..00000000000 --- a/app/assets/images/emoji/night_with_stars.png +++ /dev/null diff --git a/app/assets/images/emoji/nine.png b/app/assets/images/emoji/nine.png Binary files differdeleted file mode 100644 index 9fce3d1eca9..00000000000 --- a/app/assets/images/emoji/nine.png +++ /dev/null diff --git a/app/assets/images/emoji/no_bell.png b/app/assets/images/emoji/no_bell.png Binary files differdeleted file mode 100644 index 15cb38dd1e7..00000000000 --- a/app/assets/images/emoji/no_bell.png +++ /dev/null diff --git a/app/assets/images/emoji/no_bicycles.png b/app/assets/images/emoji/no_bicycles.png Binary files differdeleted file mode 100644 index 19c85421ce9..00000000000 --- a/app/assets/images/emoji/no_bicycles.png +++ /dev/null diff --git a/app/assets/images/emoji/no_entry.png b/app/assets/images/emoji/no_entry.png Binary files differdeleted file mode 100644 index 476800fc5c6..00000000000 --- a/app/assets/images/emoji/no_entry.png +++ /dev/null diff --git a/app/assets/images/emoji/no_entry_sign.png b/app/assets/images/emoji/no_entry_sign.png Binary files differdeleted file mode 100644 index d2efd65e74b..00000000000 --- a/app/assets/images/emoji/no_entry_sign.png +++ /dev/null diff --git a/app/assets/images/emoji/no_good.png b/app/assets/images/emoji/no_good.png Binary files differdeleted file mode 100644 index ed577100322..00000000000 --- a/app/assets/images/emoji/no_good.png +++ /dev/null diff --git a/app/assets/images/emoji/no_good_tone1.png b/app/assets/images/emoji/no_good_tone1.png Binary files differdeleted file mode 100644 index 5c1a3cbb884..00000000000 --- a/app/assets/images/emoji/no_good_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/no_good_tone2.png b/app/assets/images/emoji/no_good_tone2.png Binary files differdeleted file mode 100644 index 80d8021f8fe..00000000000 --- a/app/assets/images/emoji/no_good_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/no_good_tone3.png b/app/assets/images/emoji/no_good_tone3.png Binary files differdeleted file mode 100644 index 635e6a00815..00000000000 --- a/app/assets/images/emoji/no_good_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/no_good_tone4.png b/app/assets/images/emoji/no_good_tone4.png Binary files differdeleted file mode 100644 index b96e412a374..00000000000 --- a/app/assets/images/emoji/no_good_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/no_good_tone5.png b/app/assets/images/emoji/no_good_tone5.png Binary files differdeleted file mode 100644 index 9a7084afa0a..00000000000 --- a/app/assets/images/emoji/no_good_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/no_mobile_phones.png b/app/assets/images/emoji/no_mobile_phones.png Binary files differdeleted file mode 100644 index 7b1ae6ea579..00000000000 --- a/app/assets/images/emoji/no_mobile_phones.png +++ /dev/null diff --git a/app/assets/images/emoji/no_mouth.png b/app/assets/images/emoji/no_mouth.png Binary files differdeleted file mode 100644 index b642f6c1172..00000000000 --- a/app/assets/images/emoji/no_mouth.png +++ /dev/null diff --git a/app/assets/images/emoji/no_pedestrians.png b/app/assets/images/emoji/no_pedestrians.png Binary files differdeleted file mode 100644 index 286aa577a23..00000000000 --- a/app/assets/images/emoji/no_pedestrians.png +++ /dev/null diff --git a/app/assets/images/emoji/no_smoking.png b/app/assets/images/emoji/no_smoking.png Binary files differdeleted file mode 100644 index 586b8d29d05..00000000000 --- a/app/assets/images/emoji/no_smoking.png +++ /dev/null diff --git a/app/assets/images/emoji/non-potable_water.png b/app/assets/images/emoji/non-potable_water.png Binary files differdeleted file mode 100644 index 827d4193f4e..00000000000 --- a/app/assets/images/emoji/non-potable_water.png +++ /dev/null diff --git a/app/assets/images/emoji/nose.png b/app/assets/images/emoji/nose.png Binary files differdeleted file mode 100644 index 2f04ac5f98f..00000000000 --- a/app/assets/images/emoji/nose.png +++ /dev/null diff --git a/app/assets/images/emoji/nose_tone1.png b/app/assets/images/emoji/nose_tone1.png Binary files differdeleted file mode 100644 index 8008d17506e..00000000000 --- a/app/assets/images/emoji/nose_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/nose_tone2.png b/app/assets/images/emoji/nose_tone2.png Binary files differdeleted file mode 100644 index ac17f26e827..00000000000 --- a/app/assets/images/emoji/nose_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/nose_tone3.png b/app/assets/images/emoji/nose_tone3.png Binary files differdeleted file mode 100644 index d8b6cbe0f8e..00000000000 --- a/app/assets/images/emoji/nose_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/nose_tone4.png b/app/assets/images/emoji/nose_tone4.png Binary files differdeleted file mode 100644 index 004b2631e2e..00000000000 --- a/app/assets/images/emoji/nose_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/nose_tone5.png b/app/assets/images/emoji/nose_tone5.png Binary files differdeleted file mode 100644 index 7b33821f6c9..00000000000 --- a/app/assets/images/emoji/nose_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/notebook.png b/app/assets/images/emoji/notebook.png Binary files differdeleted file mode 100644 index f6c28b4915d..00000000000 --- a/app/assets/images/emoji/notebook.png +++ /dev/null diff --git a/app/assets/images/emoji/notebook_with_decorative_cover.png b/app/assets/images/emoji/notebook_with_decorative_cover.png Binary files differdeleted file mode 100644 index 03f566b6d2c..00000000000 --- a/app/assets/images/emoji/notebook_with_decorative_cover.png +++ /dev/null diff --git a/app/assets/images/emoji/notepad_spiral.png b/app/assets/images/emoji/notepad_spiral.png Binary files differdeleted file mode 100644 index 85faa10d8ea..00000000000 --- a/app/assets/images/emoji/notepad_spiral.png +++ /dev/null diff --git a/app/assets/images/emoji/notes.png b/app/assets/images/emoji/notes.png Binary files differdeleted file mode 100644 index 57d499aa181..00000000000 --- a/app/assets/images/emoji/notes.png +++ /dev/null diff --git a/app/assets/images/emoji/nut_and_bolt.png b/app/assets/images/emoji/nut_and_bolt.png Binary files differdeleted file mode 100644 index 4b9ae155319..00000000000 --- a/app/assets/images/emoji/nut_and_bolt.png +++ /dev/null diff --git a/app/assets/images/emoji/o.png b/app/assets/images/emoji/o.png Binary files differdeleted file mode 100644 index 3fe75ce4675..00000000000 --- a/app/assets/images/emoji/o.png +++ /dev/null diff --git a/app/assets/images/emoji/o2.png b/app/assets/images/emoji/o2.png Binary files differdeleted file mode 100644 index 73278ba194a..00000000000 --- a/app/assets/images/emoji/o2.png +++ /dev/null diff --git a/app/assets/images/emoji/ocean.png b/app/assets/images/emoji/ocean.png Binary files differdeleted file mode 100644 index 45ff1e87703..00000000000 --- a/app/assets/images/emoji/ocean.png +++ /dev/null diff --git a/app/assets/images/emoji/octagonal_sign.png b/app/assets/images/emoji/octagonal_sign.png Binary files differdeleted file mode 100644 index 5ed61004045..00000000000 --- a/app/assets/images/emoji/octagonal_sign.png +++ /dev/null diff --git a/app/assets/images/emoji/octopus.png b/app/assets/images/emoji/octopus.png Binary files differdeleted file mode 100644 index 72c84074aac..00000000000 --- a/app/assets/images/emoji/octopus.png +++ /dev/null diff --git a/app/assets/images/emoji/oden.png b/app/assets/images/emoji/oden.png Binary files differdeleted file mode 100644 index d38a849fece..00000000000 --- a/app/assets/images/emoji/oden.png +++ /dev/null diff --git a/app/assets/images/emoji/office.png b/app/assets/images/emoji/office.png Binary files differdeleted file mode 100644 index 7eee927d1b0..00000000000 --- a/app/assets/images/emoji/office.png +++ /dev/null diff --git a/app/assets/images/emoji/oil.png b/app/assets/images/emoji/oil.png Binary files differdeleted file mode 100644 index c4c4d42da8b..00000000000 --- a/app/assets/images/emoji/oil.png +++ /dev/null diff --git a/app/assets/images/emoji/ok.png b/app/assets/images/emoji/ok.png Binary files differdeleted file mode 100644 index d0d775532ff..00000000000 --- a/app/assets/images/emoji/ok.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_hand.png b/app/assets/images/emoji/ok_hand.png Binary files differdeleted file mode 100644 index 028d69b0de3..00000000000 --- a/app/assets/images/emoji/ok_hand.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_hand_tone1.png b/app/assets/images/emoji/ok_hand_tone1.png Binary files differdeleted file mode 100644 index cecf7b2ab5a..00000000000 --- a/app/assets/images/emoji/ok_hand_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_hand_tone2.png b/app/assets/images/emoji/ok_hand_tone2.png Binary files differdeleted file mode 100644 index c19239bcd3d..00000000000 --- a/app/assets/images/emoji/ok_hand_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_hand_tone3.png b/app/assets/images/emoji/ok_hand_tone3.png Binary files differdeleted file mode 100644 index 94b65b03ecd..00000000000 --- a/app/assets/images/emoji/ok_hand_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_hand_tone4.png b/app/assets/images/emoji/ok_hand_tone4.png Binary files differdeleted file mode 100644 index 03d26f08e6a..00000000000 --- a/app/assets/images/emoji/ok_hand_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_hand_tone5.png b/app/assets/images/emoji/ok_hand_tone5.png Binary files differdeleted file mode 100644 index d4b24086364..00000000000 --- a/app/assets/images/emoji/ok_hand_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_woman.png b/app/assets/images/emoji/ok_woman.png Binary files differdeleted file mode 100644 index 90a2c7469c4..00000000000 --- a/app/assets/images/emoji/ok_woman.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_woman_tone1.png b/app/assets/images/emoji/ok_woman_tone1.png Binary files differdeleted file mode 100644 index c99543e785b..00000000000 --- a/app/assets/images/emoji/ok_woman_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_woman_tone2.png b/app/assets/images/emoji/ok_woman_tone2.png Binary files differdeleted file mode 100644 index ad5fae813db..00000000000 --- a/app/assets/images/emoji/ok_woman_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_woman_tone3.png b/app/assets/images/emoji/ok_woman_tone3.png Binary files differdeleted file mode 100644 index 51bf4fab406..00000000000 --- a/app/assets/images/emoji/ok_woman_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_woman_tone4.png b/app/assets/images/emoji/ok_woman_tone4.png Binary files differdeleted file mode 100644 index ee3f9dc640a..00000000000 --- a/app/assets/images/emoji/ok_woman_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/ok_woman_tone5.png b/app/assets/images/emoji/ok_woman_tone5.png Binary files differdeleted file mode 100644 index 62a9d9237f7..00000000000 --- a/app/assets/images/emoji/ok_woman_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/older_man.png b/app/assets/images/emoji/older_man.png Binary files differdeleted file mode 100644 index 4ace4e6f308..00000000000 --- a/app/assets/images/emoji/older_man.png +++ /dev/null diff --git a/app/assets/images/emoji/older_man_tone1.png b/app/assets/images/emoji/older_man_tone1.png Binary files differdeleted file mode 100644 index ab459baace8..00000000000 --- a/app/assets/images/emoji/older_man_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/older_man_tone2.png b/app/assets/images/emoji/older_man_tone2.png Binary files differdeleted file mode 100644 index f4dfc7694ea..00000000000 --- a/app/assets/images/emoji/older_man_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/older_man_tone3.png b/app/assets/images/emoji/older_man_tone3.png Binary files differdeleted file mode 100644 index 5ffd11792f4..00000000000 --- a/app/assets/images/emoji/older_man_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/older_man_tone4.png b/app/assets/images/emoji/older_man_tone4.png Binary files differdeleted file mode 100644 index b350a764bfd..00000000000 --- a/app/assets/images/emoji/older_man_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/older_man_tone5.png b/app/assets/images/emoji/older_man_tone5.png Binary files differdeleted file mode 100644 index 05fe24a1708..00000000000 --- a/app/assets/images/emoji/older_man_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/older_woman.png b/app/assets/images/emoji/older_woman.png Binary files differdeleted file mode 100644 index 52dc4987143..00000000000 --- a/app/assets/images/emoji/older_woman.png +++ /dev/null diff --git a/app/assets/images/emoji/older_woman_tone1.png b/app/assets/images/emoji/older_woman_tone1.png Binary files differdeleted file mode 100644 index b49e821402c..00000000000 --- a/app/assets/images/emoji/older_woman_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/older_woman_tone2.png b/app/assets/images/emoji/older_woman_tone2.png Binary files differdeleted file mode 100644 index e86bf5ab3b7..00000000000 --- a/app/assets/images/emoji/older_woman_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/older_woman_tone3.png b/app/assets/images/emoji/older_woman_tone3.png Binary files differdeleted file mode 100644 index 83fc14b0874..00000000000 --- a/app/assets/images/emoji/older_woman_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/older_woman_tone4.png b/app/assets/images/emoji/older_woman_tone4.png Binary files differdeleted file mode 100644 index e4aa8a424d4..00000000000 --- a/app/assets/images/emoji/older_woman_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/older_woman_tone5.png b/app/assets/images/emoji/older_woman_tone5.png Binary files differdeleted file mode 100644 index 4009012bb0a..00000000000 --- a/app/assets/images/emoji/older_woman_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/om_symbol.png b/app/assets/images/emoji/om_symbol.png Binary files differdeleted file mode 100644 index a35c63c459c..00000000000 --- a/app/assets/images/emoji/om_symbol.png +++ /dev/null diff --git a/app/assets/images/emoji/on.png b/app/assets/images/emoji/on.png Binary files differdeleted file mode 100644 index a0c371ae21e..00000000000 --- a/app/assets/images/emoji/on.png +++ /dev/null diff --git a/app/assets/images/emoji/oncoming_automobile.png b/app/assets/images/emoji/oncoming_automobile.png Binary files differdeleted file mode 100644 index 3c7e1d52e63..00000000000 --- a/app/assets/images/emoji/oncoming_automobile.png +++ /dev/null diff --git a/app/assets/images/emoji/oncoming_bus.png b/app/assets/images/emoji/oncoming_bus.png Binary files differdeleted file mode 100644 index ad91e256c7f..00000000000 --- a/app/assets/images/emoji/oncoming_bus.png +++ /dev/null diff --git a/app/assets/images/emoji/oncoming_police_car.png b/app/assets/images/emoji/oncoming_police_car.png Binary files differdeleted file mode 100644 index c9109c85b5d..00000000000 --- a/app/assets/images/emoji/oncoming_police_car.png +++ /dev/null diff --git a/app/assets/images/emoji/oncoming_taxi.png b/app/assets/images/emoji/oncoming_taxi.png Binary files differdeleted file mode 100644 index fea14e45846..00000000000 --- a/app/assets/images/emoji/oncoming_taxi.png +++ /dev/null diff --git a/app/assets/images/emoji/one.png b/app/assets/images/emoji/one.png Binary files differdeleted file mode 100644 index e6d84b80128..00000000000 --- a/app/assets/images/emoji/one.png +++ /dev/null diff --git a/app/assets/images/emoji/open_file_folder.png b/app/assets/images/emoji/open_file_folder.png Binary files differdeleted file mode 100644 index 3993b09222f..00000000000 --- a/app/assets/images/emoji/open_file_folder.png +++ /dev/null diff --git a/app/assets/images/emoji/open_hands.png b/app/assets/images/emoji/open_hands.png Binary files differdeleted file mode 100644 index 1cf75c9101e..00000000000 --- a/app/assets/images/emoji/open_hands.png +++ /dev/null diff --git a/app/assets/images/emoji/open_hands_tone1.png b/app/assets/images/emoji/open_hands_tone1.png Binary files differdeleted file mode 100644 index 352d2614f11..00000000000 --- a/app/assets/images/emoji/open_hands_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/open_hands_tone2.png b/app/assets/images/emoji/open_hands_tone2.png Binary files differdeleted file mode 100644 index 70824a50c73..00000000000 --- a/app/assets/images/emoji/open_hands_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/open_hands_tone3.png b/app/assets/images/emoji/open_hands_tone3.png Binary files differdeleted file mode 100644 index d7d136bd3db..00000000000 --- a/app/assets/images/emoji/open_hands_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/open_hands_tone4.png b/app/assets/images/emoji/open_hands_tone4.png Binary files differdeleted file mode 100644 index df4eaa711e7..00000000000 --- a/app/assets/images/emoji/open_hands_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/open_hands_tone5.png b/app/assets/images/emoji/open_hands_tone5.png Binary files differdeleted file mode 100644 index 7dc04eaebd8..00000000000 --- a/app/assets/images/emoji/open_hands_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/open_mouth.png b/app/assets/images/emoji/open_mouth.png Binary files differdeleted file mode 100644 index a62cd27e148..00000000000 --- a/app/assets/images/emoji/open_mouth.png +++ /dev/null diff --git a/app/assets/images/emoji/ophiuchus.png b/app/assets/images/emoji/ophiuchus.png Binary files differdeleted file mode 100644 index 0a780a700da..00000000000 --- a/app/assets/images/emoji/ophiuchus.png +++ /dev/null diff --git a/app/assets/images/emoji/orange_book.png b/app/assets/images/emoji/orange_book.png Binary files differdeleted file mode 100644 index ab40e6ae6a2..00000000000 --- a/app/assets/images/emoji/orange_book.png +++ /dev/null diff --git a/app/assets/images/emoji/orthodox_cross.png b/app/assets/images/emoji/orthodox_cross.png Binary files differdeleted file mode 100644 index 0530e33a4d4..00000000000 --- a/app/assets/images/emoji/orthodox_cross.png +++ /dev/null diff --git a/app/assets/images/emoji/outbox_tray.png b/app/assets/images/emoji/outbox_tray.png Binary files differdeleted file mode 100644 index 46493ed5b2c..00000000000 --- a/app/assets/images/emoji/outbox_tray.png +++ /dev/null diff --git a/app/assets/images/emoji/owl.png b/app/assets/images/emoji/owl.png Binary files differdeleted file mode 100644 index fa6815480c3..00000000000 --- a/app/assets/images/emoji/owl.png +++ /dev/null diff --git a/app/assets/images/emoji/ox.png b/app/assets/images/emoji/ox.png Binary files differdeleted file mode 100644 index badf5708f2f..00000000000 --- a/app/assets/images/emoji/ox.png +++ /dev/null diff --git a/app/assets/images/emoji/package.png b/app/assets/images/emoji/package.png Binary files differdeleted file mode 100644 index 85431756ad8..00000000000 --- a/app/assets/images/emoji/package.png +++ /dev/null diff --git a/app/assets/images/emoji/page_facing_up.png b/app/assets/images/emoji/page_facing_up.png Binary files differdeleted file mode 100644 index ba4ed757e01..00000000000 --- a/app/assets/images/emoji/page_facing_up.png +++ /dev/null diff --git a/app/assets/images/emoji/page_with_curl.png b/app/assets/images/emoji/page_with_curl.png Binary files differdeleted file mode 100644 index 06355319c74..00000000000 --- a/app/assets/images/emoji/page_with_curl.png +++ /dev/null diff --git a/app/assets/images/emoji/pager.png b/app/assets/images/emoji/pager.png Binary files differdeleted file mode 100644 index b24b99306a2..00000000000 --- a/app/assets/images/emoji/pager.png +++ /dev/null diff --git a/app/assets/images/emoji/paintbrush.png b/app/assets/images/emoji/paintbrush.png Binary files differdeleted file mode 100644 index 28bffbaa3c9..00000000000 --- a/app/assets/images/emoji/paintbrush.png +++ /dev/null diff --git a/app/assets/images/emoji/palm_tree.png b/app/assets/images/emoji/palm_tree.png Binary files differdeleted file mode 100644 index 4bbb10f4f19..00000000000 --- a/app/assets/images/emoji/palm_tree.png +++ /dev/null diff --git a/app/assets/images/emoji/pancakes.png b/app/assets/images/emoji/pancakes.png Binary files differdeleted file mode 100644 index 6223d1a28e9..00000000000 --- a/app/assets/images/emoji/pancakes.png +++ /dev/null diff --git a/app/assets/images/emoji/panda_face.png b/app/assets/images/emoji/panda_face.png Binary files differdeleted file mode 100644 index 978382775ce..00000000000 --- a/app/assets/images/emoji/panda_face.png +++ /dev/null diff --git a/app/assets/images/emoji/paperclip.png b/app/assets/images/emoji/paperclip.png Binary files differdeleted file mode 100644 index 8cd8d4f8750..00000000000 --- a/app/assets/images/emoji/paperclip.png +++ /dev/null diff --git a/app/assets/images/emoji/paperclips.png b/app/assets/images/emoji/paperclips.png Binary files differdeleted file mode 100644 index 76021e8c705..00000000000 --- a/app/assets/images/emoji/paperclips.png +++ /dev/null diff --git a/app/assets/images/emoji/park.png b/app/assets/images/emoji/park.png Binary files differdeleted file mode 100644 index 63ec7016301..00000000000 --- a/app/assets/images/emoji/park.png +++ /dev/null diff --git a/app/assets/images/emoji/parking.png b/app/assets/images/emoji/parking.png Binary files differdeleted file mode 100644 index 7be7dac27e8..00000000000 --- a/app/assets/images/emoji/parking.png +++ /dev/null diff --git a/app/assets/images/emoji/part_alternation_mark.png b/app/assets/images/emoji/part_alternation_mark.png Binary files differdeleted file mode 100644 index 70453d41528..00000000000 --- a/app/assets/images/emoji/part_alternation_mark.png +++ /dev/null diff --git a/app/assets/images/emoji/partly_sunny.png b/app/assets/images/emoji/partly_sunny.png Binary files differdeleted file mode 100644 index a55e59c344c..00000000000 --- a/app/assets/images/emoji/partly_sunny.png +++ /dev/null diff --git a/app/assets/images/emoji/passport_control.png b/app/assets/images/emoji/passport_control.png Binary files differdeleted file mode 100644 index 079e34ee4d4..00000000000 --- a/app/assets/images/emoji/passport_control.png +++ /dev/null diff --git a/app/assets/images/emoji/pause_button.png b/app/assets/images/emoji/pause_button.png Binary files differdeleted file mode 100644 index 4f07e7ebfd7..00000000000 --- a/app/assets/images/emoji/pause_button.png +++ /dev/null diff --git a/app/assets/images/emoji/peace.png b/app/assets/images/emoji/peace.png Binary files differdeleted file mode 100644 index 86033faf477..00000000000 --- a/app/assets/images/emoji/peace.png +++ /dev/null diff --git a/app/assets/images/emoji/peach.png b/app/assets/images/emoji/peach.png Binary files differdeleted file mode 100644 index 9ab57cbb758..00000000000 --- a/app/assets/images/emoji/peach.png +++ /dev/null diff --git a/app/assets/images/emoji/peanuts.png b/app/assets/images/emoji/peanuts.png Binary files differdeleted file mode 100644 index b64fadad010..00000000000 --- a/app/assets/images/emoji/peanuts.png +++ /dev/null diff --git a/app/assets/images/emoji/pear.png b/app/assets/images/emoji/pear.png Binary files differdeleted file mode 100644 index 3869f718bcf..00000000000 --- a/app/assets/images/emoji/pear.png +++ /dev/null diff --git a/app/assets/images/emoji/pen_ballpoint.png b/app/assets/images/emoji/pen_ballpoint.png Binary files differdeleted file mode 100644 index 6ef7a342433..00000000000 --- a/app/assets/images/emoji/pen_ballpoint.png +++ /dev/null diff --git a/app/assets/images/emoji/pen_fountain.png b/app/assets/images/emoji/pen_fountain.png Binary files differdeleted file mode 100644 index 3ca4bd2c231..00000000000 --- a/app/assets/images/emoji/pen_fountain.png +++ /dev/null diff --git a/app/assets/images/emoji/pencil.png b/app/assets/images/emoji/pencil.png Binary files differdeleted file mode 100644 index edc6155e168..00000000000 --- a/app/assets/images/emoji/pencil.png +++ /dev/null diff --git a/app/assets/images/emoji/pencil2.png b/app/assets/images/emoji/pencil2.png Binary files differdeleted file mode 100644 index 3833d590fa2..00000000000 --- a/app/assets/images/emoji/pencil2.png +++ /dev/null diff --git a/app/assets/images/emoji/penguin.png b/app/assets/images/emoji/penguin.png Binary files differdeleted file mode 100644 index c0064fb9734..00000000000 --- a/app/assets/images/emoji/penguin.png +++ /dev/null diff --git a/app/assets/images/emoji/pensive.png b/app/assets/images/emoji/pensive.png Binary files differdeleted file mode 100644 index 490fb566954..00000000000 --- a/app/assets/images/emoji/pensive.png +++ /dev/null diff --git a/app/assets/images/emoji/performing_arts.png b/app/assets/images/emoji/performing_arts.png Binary files differdeleted file mode 100644 index 685441fdaa1..00000000000 --- a/app/assets/images/emoji/performing_arts.png +++ /dev/null diff --git a/app/assets/images/emoji/persevere.png b/app/assets/images/emoji/persevere.png Binary files differdeleted file mode 100644 index 646a05fe908..00000000000 --- a/app/assets/images/emoji/persevere.png +++ /dev/null diff --git a/app/assets/images/emoji/person_frowning.png b/app/assets/images/emoji/person_frowning.png Binary files differdeleted file mode 100644 index 579324959a1..00000000000 --- a/app/assets/images/emoji/person_frowning.png +++ /dev/null diff --git a/app/assets/images/emoji/person_frowning_tone1.png b/app/assets/images/emoji/person_frowning_tone1.png Binary files differdeleted file mode 100644 index 21d3bb43923..00000000000 --- a/app/assets/images/emoji/person_frowning_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/person_frowning_tone2.png b/app/assets/images/emoji/person_frowning_tone2.png Binary files differdeleted file mode 100644 index 973f5fc8382..00000000000 --- a/app/assets/images/emoji/person_frowning_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/person_frowning_tone3.png b/app/assets/images/emoji/person_frowning_tone3.png Binary files differdeleted file mode 100644 index 41fbcc78816..00000000000 --- a/app/assets/images/emoji/person_frowning_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/person_frowning_tone4.png b/app/assets/images/emoji/person_frowning_tone4.png Binary files differdeleted file mode 100644 index 5a37c741030..00000000000 --- a/app/assets/images/emoji/person_frowning_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/person_frowning_tone5.png b/app/assets/images/emoji/person_frowning_tone5.png Binary files differdeleted file mode 100644 index e08141f3efe..00000000000 --- a/app/assets/images/emoji/person_frowning_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_blond_hair.png b/app/assets/images/emoji/person_with_blond_hair.png Binary files differdeleted file mode 100644 index ad6f01a7dda..00000000000 --- a/app/assets/images/emoji/person_with_blond_hair.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_blond_hair_tone1.png b/app/assets/images/emoji/person_with_blond_hair_tone1.png Binary files differdeleted file mode 100644 index 7d18ef24445..00000000000 --- a/app/assets/images/emoji/person_with_blond_hair_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_blond_hair_tone2.png b/app/assets/images/emoji/person_with_blond_hair_tone2.png Binary files differdeleted file mode 100644 index dae1307315c..00000000000 --- a/app/assets/images/emoji/person_with_blond_hair_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_blond_hair_tone3.png b/app/assets/images/emoji/person_with_blond_hair_tone3.png Binary files differdeleted file mode 100644 index 684677e8e5a..00000000000 --- a/app/assets/images/emoji/person_with_blond_hair_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_blond_hair_tone4.png b/app/assets/images/emoji/person_with_blond_hair_tone4.png Binary files differdeleted file mode 100644 index 012be0b51f8..00000000000 --- a/app/assets/images/emoji/person_with_blond_hair_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_blond_hair_tone5.png b/app/assets/images/emoji/person_with_blond_hair_tone5.png Binary files differdeleted file mode 100644 index d4ecc4cf44b..00000000000 --- a/app/assets/images/emoji/person_with_blond_hair_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_pouting_face.png b/app/assets/images/emoji/person_with_pouting_face.png Binary files differdeleted file mode 100644 index 10eb0571078..00000000000 --- a/app/assets/images/emoji/person_with_pouting_face.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_pouting_face_tone1.png b/app/assets/images/emoji/person_with_pouting_face_tone1.png Binary files differdeleted file mode 100644 index 57e826b75a4..00000000000 --- a/app/assets/images/emoji/person_with_pouting_face_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_pouting_face_tone2.png b/app/assets/images/emoji/person_with_pouting_face_tone2.png Binary files differdeleted file mode 100644 index 3f317c0c25f..00000000000 --- a/app/assets/images/emoji/person_with_pouting_face_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_pouting_face_tone3.png b/app/assets/images/emoji/person_with_pouting_face_tone3.png Binary files differdeleted file mode 100644 index d2fbb6c20bf..00000000000 --- a/app/assets/images/emoji/person_with_pouting_face_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_pouting_face_tone4.png b/app/assets/images/emoji/person_with_pouting_face_tone4.png Binary files differdeleted file mode 100644 index 643ceb4a5c5..00000000000 --- a/app/assets/images/emoji/person_with_pouting_face_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/person_with_pouting_face_tone5.png b/app/assets/images/emoji/person_with_pouting_face_tone5.png Binary files differdeleted file mode 100644 index b2eb6859c32..00000000000 --- a/app/assets/images/emoji/person_with_pouting_face_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/pick.png b/app/assets/images/emoji/pick.png Binary files differdeleted file mode 100644 index 6370fe6d791..00000000000 --- a/app/assets/images/emoji/pick.png +++ /dev/null diff --git a/app/assets/images/emoji/pig.png b/app/assets/images/emoji/pig.png Binary files differdeleted file mode 100644 index afe05ca1676..00000000000 --- a/app/assets/images/emoji/pig.png +++ /dev/null diff --git a/app/assets/images/emoji/pig2.png b/app/assets/images/emoji/pig2.png Binary files differdeleted file mode 100644 index 5f31c1a2d75..00000000000 --- a/app/assets/images/emoji/pig2.png +++ /dev/null diff --git a/app/assets/images/emoji/pig_nose.png b/app/assets/images/emoji/pig_nose.png Binary files differdeleted file mode 100644 index 3610ae4a910..00000000000 --- a/app/assets/images/emoji/pig_nose.png +++ /dev/null diff --git a/app/assets/images/emoji/pill.png b/app/assets/images/emoji/pill.png Binary files differdeleted file mode 100644 index 1d4530e77a3..00000000000 --- a/app/assets/images/emoji/pill.png +++ /dev/null diff --git a/app/assets/images/emoji/pineapple.png b/app/assets/images/emoji/pineapple.png Binary files differdeleted file mode 100644 index c89a1606462..00000000000 --- a/app/assets/images/emoji/pineapple.png +++ /dev/null diff --git a/app/assets/images/emoji/ping_pong.png b/app/assets/images/emoji/ping_pong.png Binary files differdeleted file mode 100644 index ff3c51727d1..00000000000 --- a/app/assets/images/emoji/ping_pong.png +++ /dev/null diff --git a/app/assets/images/emoji/pisces.png b/app/assets/images/emoji/pisces.png Binary files differdeleted file mode 100644 index 7f6f646a95c..00000000000 --- a/app/assets/images/emoji/pisces.png +++ /dev/null diff --git a/app/assets/images/emoji/pizza.png b/app/assets/images/emoji/pizza.png Binary files differdeleted file mode 100644 index e07365cb398..00000000000 --- a/app/assets/images/emoji/pizza.png +++ /dev/null diff --git a/app/assets/images/emoji/place_of_worship.png b/app/assets/images/emoji/place_of_worship.png Binary files differdeleted file mode 100644 index 207d59cce85..00000000000 --- a/app/assets/images/emoji/place_of_worship.png +++ /dev/null diff --git a/app/assets/images/emoji/play_pause.png b/app/assets/images/emoji/play_pause.png Binary files differdeleted file mode 100644 index a9f857139ac..00000000000 --- a/app/assets/images/emoji/play_pause.png +++ /dev/null diff --git a/app/assets/images/emoji/point_down.png b/app/assets/images/emoji/point_down.png Binary files differdeleted file mode 100644 index 00d3d13ab5c..00000000000 --- a/app/assets/images/emoji/point_down.png +++ /dev/null diff --git a/app/assets/images/emoji/point_down_tone1.png b/app/assets/images/emoji/point_down_tone1.png Binary files differdeleted file mode 100644 index 140f157d8c7..00000000000 --- a/app/assets/images/emoji/point_down_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/point_down_tone2.png b/app/assets/images/emoji/point_down_tone2.png Binary files differdeleted file mode 100644 index d518544f7fa..00000000000 --- a/app/assets/images/emoji/point_down_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/point_down_tone3.png b/app/assets/images/emoji/point_down_tone3.png Binary files differdeleted file mode 100644 index 018b688b8b7..00000000000 --- a/app/assets/images/emoji/point_down_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/point_down_tone4.png b/app/assets/images/emoji/point_down_tone4.png Binary files differdeleted file mode 100644 index 98845bf6f72..00000000000 --- a/app/assets/images/emoji/point_down_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/point_down_tone5.png b/app/assets/images/emoji/point_down_tone5.png Binary files differdeleted file mode 100644 index 9a9b039a9fc..00000000000 --- a/app/assets/images/emoji/point_down_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/point_left.png b/app/assets/images/emoji/point_left.png Binary files differdeleted file mode 100644 index 599fa2e3cf1..00000000000 --- a/app/assets/images/emoji/point_left.png +++ /dev/null diff --git a/app/assets/images/emoji/point_left_tone1.png b/app/assets/images/emoji/point_left_tone1.png Binary files differdeleted file mode 100644 index 88e2c306076..00000000000 --- a/app/assets/images/emoji/point_left_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/point_left_tone2.png b/app/assets/images/emoji/point_left_tone2.png Binary files differdeleted file mode 100644 index d3c89d87c5f..00000000000 --- a/app/assets/images/emoji/point_left_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/point_left_tone3.png b/app/assets/images/emoji/point_left_tone3.png Binary files differdeleted file mode 100644 index b23b9167358..00000000000 --- a/app/assets/images/emoji/point_left_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/point_left_tone4.png b/app/assets/images/emoji/point_left_tone4.png Binary files differdeleted file mode 100644 index 3093f325c27..00000000000 --- a/app/assets/images/emoji/point_left_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/point_left_tone5.png b/app/assets/images/emoji/point_left_tone5.png Binary files differdeleted file mode 100644 index 2b4cbfa120c..00000000000 --- a/app/assets/images/emoji/point_left_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/point_right.png b/app/assets/images/emoji/point_right.png Binary files differdeleted file mode 100644 index 93a3cd34aa5..00000000000 --- a/app/assets/images/emoji/point_right.png +++ /dev/null diff --git a/app/assets/images/emoji/point_right_tone1.png b/app/assets/images/emoji/point_right_tone1.png Binary files differdeleted file mode 100644 index 4a28c6bbc89..00000000000 --- a/app/assets/images/emoji/point_right_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/point_right_tone2.png b/app/assets/images/emoji/point_right_tone2.png Binary files differdeleted file mode 100644 index 7cb13231733..00000000000 --- a/app/assets/images/emoji/point_right_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/point_right_tone3.png b/app/assets/images/emoji/point_right_tone3.png Binary files differdeleted file mode 100644 index 5514807d71a..00000000000 --- a/app/assets/images/emoji/point_right_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/point_right_tone4.png b/app/assets/images/emoji/point_right_tone4.png Binary files differdeleted file mode 100644 index b8541d6440d..00000000000 --- a/app/assets/images/emoji/point_right_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/point_right_tone5.png b/app/assets/images/emoji/point_right_tone5.png Binary files differdeleted file mode 100644 index 1b7aab07bb1..00000000000 --- a/app/assets/images/emoji/point_right_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up.png b/app/assets/images/emoji/point_up.png Binary files differdeleted file mode 100644 index f4978ff0f00..00000000000 --- a/app/assets/images/emoji/point_up.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_2.png b/app/assets/images/emoji/point_up_2.png Binary files differdeleted file mode 100644 index bc496dfeae4..00000000000 --- a/app/assets/images/emoji/point_up_2.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_2_tone1.png b/app/assets/images/emoji/point_up_2_tone1.png Binary files differdeleted file mode 100644 index a12a7e78430..00000000000 --- a/app/assets/images/emoji/point_up_2_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_2_tone2.png b/app/assets/images/emoji/point_up_2_tone2.png Binary files differdeleted file mode 100644 index cdff40ceab0..00000000000 --- a/app/assets/images/emoji/point_up_2_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_2_tone3.png b/app/assets/images/emoji/point_up_2_tone3.png Binary files differdeleted file mode 100644 index a07ce9e5ae8..00000000000 --- a/app/assets/images/emoji/point_up_2_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_2_tone4.png b/app/assets/images/emoji/point_up_2_tone4.png Binary files differdeleted file mode 100644 index 4f86c88ba42..00000000000 --- a/app/assets/images/emoji/point_up_2_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_2_tone5.png b/app/assets/images/emoji/point_up_2_tone5.png Binary files differdeleted file mode 100644 index ed1b26c35d3..00000000000 --- a/app/assets/images/emoji/point_up_2_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_tone1.png b/app/assets/images/emoji/point_up_tone1.png Binary files differdeleted file mode 100644 index 6a9db21d64c..00000000000 --- a/app/assets/images/emoji/point_up_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_tone2.png b/app/assets/images/emoji/point_up_tone2.png Binary files differdeleted file mode 100644 index 15aa9ea0e05..00000000000 --- a/app/assets/images/emoji/point_up_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_tone3.png b/app/assets/images/emoji/point_up_tone3.png Binary files differdeleted file mode 100644 index 652b73a9c5d..00000000000 --- a/app/assets/images/emoji/point_up_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_tone4.png b/app/assets/images/emoji/point_up_tone4.png Binary files differdeleted file mode 100644 index 692bad926e9..00000000000 --- a/app/assets/images/emoji/point_up_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/point_up_tone5.png b/app/assets/images/emoji/point_up_tone5.png Binary files differdeleted file mode 100644 index 1e1b10fb71c..00000000000 --- a/app/assets/images/emoji/point_up_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/police_car.png b/app/assets/images/emoji/police_car.png Binary files differdeleted file mode 100644 index 3da4253de7e..00000000000 --- a/app/assets/images/emoji/police_car.png +++ /dev/null diff --git a/app/assets/images/emoji/poodle.png b/app/assets/images/emoji/poodle.png Binary files differdeleted file mode 100644 index 8ec39e396af..00000000000 --- a/app/assets/images/emoji/poodle.png +++ /dev/null diff --git a/app/assets/images/emoji/poop.png b/app/assets/images/emoji/poop.png Binary files differdeleted file mode 100644 index 10b15e72d56..00000000000 --- a/app/assets/images/emoji/poop.png +++ /dev/null diff --git a/app/assets/images/emoji/popcorn.png b/app/assets/images/emoji/popcorn.png Binary files differdeleted file mode 100644 index 36853e381d4..00000000000 --- a/app/assets/images/emoji/popcorn.png +++ /dev/null diff --git a/app/assets/images/emoji/post_office.png b/app/assets/images/emoji/post_office.png Binary files differdeleted file mode 100644 index a23848f9aa0..00000000000 --- a/app/assets/images/emoji/post_office.png +++ /dev/null diff --git a/app/assets/images/emoji/postal_horn.png b/app/assets/images/emoji/postal_horn.png Binary files differdeleted file mode 100644 index c173b8dbd67..00000000000 --- a/app/assets/images/emoji/postal_horn.png +++ /dev/null diff --git a/app/assets/images/emoji/postbox.png b/app/assets/images/emoji/postbox.png Binary files differdeleted file mode 100644 index 07c9c4ab3d6..00000000000 --- a/app/assets/images/emoji/postbox.png +++ /dev/null diff --git a/app/assets/images/emoji/potable_water.png b/app/assets/images/emoji/potable_water.png Binary files differdeleted file mode 100644 index 2c610049459..00000000000 --- a/app/assets/images/emoji/potable_water.png +++ /dev/null diff --git a/app/assets/images/emoji/potato.png b/app/assets/images/emoji/potato.png Binary files differdeleted file mode 100644 index 70350ca2c0a..00000000000 --- a/app/assets/images/emoji/potato.png +++ /dev/null diff --git a/app/assets/images/emoji/pouch.png b/app/assets/images/emoji/pouch.png Binary files differdeleted file mode 100644 index 8795c6c66ff..00000000000 --- a/app/assets/images/emoji/pouch.png +++ /dev/null diff --git a/app/assets/images/emoji/poultry_leg.png b/app/assets/images/emoji/poultry_leg.png Binary files differdeleted file mode 100644 index eea4a53a2f9..00000000000 --- a/app/assets/images/emoji/poultry_leg.png +++ /dev/null diff --git a/app/assets/images/emoji/pound.png b/app/assets/images/emoji/pound.png Binary files differdeleted file mode 100644 index a0d4c4099e9..00000000000 --- a/app/assets/images/emoji/pound.png +++ /dev/null diff --git a/app/assets/images/emoji/pouting_cat.png b/app/assets/images/emoji/pouting_cat.png Binary files differdeleted file mode 100644 index 41ddfeab42b..00000000000 --- a/app/assets/images/emoji/pouting_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/pray.png b/app/assets/images/emoji/pray.png Binary files differdeleted file mode 100644 index 8347f2435be..00000000000 --- a/app/assets/images/emoji/pray.png +++ /dev/null diff --git a/app/assets/images/emoji/pray_tone1.png b/app/assets/images/emoji/pray_tone1.png Binary files differdeleted file mode 100644 index 060ef257172..00000000000 --- a/app/assets/images/emoji/pray_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/pray_tone2.png b/app/assets/images/emoji/pray_tone2.png Binary files differdeleted file mode 100644 index 56dc607c07a..00000000000 --- a/app/assets/images/emoji/pray_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/pray_tone3.png b/app/assets/images/emoji/pray_tone3.png Binary files differdeleted file mode 100644 index 0f33b862008..00000000000 --- a/app/assets/images/emoji/pray_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/pray_tone4.png b/app/assets/images/emoji/pray_tone4.png Binary files differdeleted file mode 100644 index 2ea8dc11657..00000000000 --- a/app/assets/images/emoji/pray_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/pray_tone5.png b/app/assets/images/emoji/pray_tone5.png Binary files differdeleted file mode 100644 index 2128a6c4703..00000000000 --- a/app/assets/images/emoji/pray_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/prayer_beads.png b/app/assets/images/emoji/prayer_beads.png Binary files differdeleted file mode 100644 index a4b6dfcc62e..00000000000 --- a/app/assets/images/emoji/prayer_beads.png +++ /dev/null diff --git a/app/assets/images/emoji/pregnant_woman.png b/app/assets/images/emoji/pregnant_woman.png Binary files differdeleted file mode 100644 index 084e83a414a..00000000000 --- a/app/assets/images/emoji/pregnant_woman.png +++ /dev/null diff --git a/app/assets/images/emoji/pregnant_woman_tone1.png b/app/assets/images/emoji/pregnant_woman_tone1.png Binary files differdeleted file mode 100644 index a78703b33aa..00000000000 --- a/app/assets/images/emoji/pregnant_woman_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/pregnant_woman_tone2.png b/app/assets/images/emoji/pregnant_woman_tone2.png Binary files differdeleted file mode 100644 index 0068c6c4a77..00000000000 --- a/app/assets/images/emoji/pregnant_woman_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/pregnant_woman_tone3.png b/app/assets/images/emoji/pregnant_woman_tone3.png Binary files differdeleted file mode 100644 index 3206296b684..00000000000 --- a/app/assets/images/emoji/pregnant_woman_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/pregnant_woman_tone4.png b/app/assets/images/emoji/pregnant_woman_tone4.png Binary files differdeleted file mode 100644 index 120fda5cd8c..00000000000 --- a/app/assets/images/emoji/pregnant_woman_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/pregnant_woman_tone5.png b/app/assets/images/emoji/pregnant_woman_tone5.png Binary files differdeleted file mode 100644 index 569bfdf05ce..00000000000 --- a/app/assets/images/emoji/pregnant_woman_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/prince.png b/app/assets/images/emoji/prince.png Binary files differdeleted file mode 100644 index 38d69344c84..00000000000 --- a/app/assets/images/emoji/prince.png +++ /dev/null diff --git a/app/assets/images/emoji/prince_tone1.png b/app/assets/images/emoji/prince_tone1.png Binary files differdeleted file mode 100644 index 849930c8887..00000000000 --- a/app/assets/images/emoji/prince_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/prince_tone2.png b/app/assets/images/emoji/prince_tone2.png Binary files differdeleted file mode 100644 index 23d8b3b1285..00000000000 --- a/app/assets/images/emoji/prince_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/prince_tone3.png b/app/assets/images/emoji/prince_tone3.png Binary files differdeleted file mode 100644 index db6dfff0647..00000000000 --- a/app/assets/images/emoji/prince_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/prince_tone4.png b/app/assets/images/emoji/prince_tone4.png Binary files differdeleted file mode 100644 index 8e10f8be6a8..00000000000 --- a/app/assets/images/emoji/prince_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/prince_tone5.png b/app/assets/images/emoji/prince_tone5.png Binary files differdeleted file mode 100644 index 138d4ea7048..00000000000 --- a/app/assets/images/emoji/prince_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/princess.png b/app/assets/images/emoji/princess.png Binary files differdeleted file mode 100644 index 879e9fa8c5d..00000000000 --- a/app/assets/images/emoji/princess.png +++ /dev/null diff --git a/app/assets/images/emoji/princess_tone1.png b/app/assets/images/emoji/princess_tone1.png Binary files differdeleted file mode 100644 index c28078cdc36..00000000000 --- a/app/assets/images/emoji/princess_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/princess_tone2.png b/app/assets/images/emoji/princess_tone2.png Binary files differdeleted file mode 100644 index dcd20e6ecd4..00000000000 --- a/app/assets/images/emoji/princess_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/princess_tone3.png b/app/assets/images/emoji/princess_tone3.png Binary files differdeleted file mode 100644 index cde6f315c56..00000000000 --- a/app/assets/images/emoji/princess_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/princess_tone4.png b/app/assets/images/emoji/princess_tone4.png Binary files differdeleted file mode 100644 index c71e69caaef..00000000000 --- a/app/assets/images/emoji/princess_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/princess_tone5.png b/app/assets/images/emoji/princess_tone5.png Binary files differdeleted file mode 100644 index 063e2645910..00000000000 --- a/app/assets/images/emoji/princess_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/printer.png b/app/assets/images/emoji/printer.png Binary files differdeleted file mode 100644 index 027c830f0fe..00000000000 --- a/app/assets/images/emoji/printer.png +++ /dev/null diff --git a/app/assets/images/emoji/projector.png b/app/assets/images/emoji/projector.png Binary files differdeleted file mode 100644 index ce9ab0daa28..00000000000 --- a/app/assets/images/emoji/projector.png +++ /dev/null diff --git a/app/assets/images/emoji/punch.png b/app/assets/images/emoji/punch.png Binary files differdeleted file mode 100644 index b14ca5f5211..00000000000 --- a/app/assets/images/emoji/punch.png +++ /dev/null diff --git a/app/assets/images/emoji/punch_tone1.png b/app/assets/images/emoji/punch_tone1.png Binary files differdeleted file mode 100644 index 93c7d17fb47..00000000000 --- a/app/assets/images/emoji/punch_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/punch_tone2.png b/app/assets/images/emoji/punch_tone2.png Binary files differdeleted file mode 100644 index c0a1af6e10a..00000000000 --- a/app/assets/images/emoji/punch_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/punch_tone3.png b/app/assets/images/emoji/punch_tone3.png Binary files differdeleted file mode 100644 index 1458b021201..00000000000 --- a/app/assets/images/emoji/punch_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/punch_tone4.png b/app/assets/images/emoji/punch_tone4.png Binary files differdeleted file mode 100644 index c1466bfcdef..00000000000 --- a/app/assets/images/emoji/punch_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/punch_tone5.png b/app/assets/images/emoji/punch_tone5.png Binary files differdeleted file mode 100644 index 00b4ddb8953..00000000000 --- a/app/assets/images/emoji/punch_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/purple_heart.png b/app/assets/images/emoji/purple_heart.png Binary files differdeleted file mode 100644 index 95c53a9ade6..00000000000 --- a/app/assets/images/emoji/purple_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/purse.png b/app/assets/images/emoji/purse.png Binary files differdeleted file mode 100644 index 981346193c5..00000000000 --- a/app/assets/images/emoji/purse.png +++ /dev/null diff --git a/app/assets/images/emoji/pushpin.png b/app/assets/images/emoji/pushpin.png Binary files differdeleted file mode 100644 index 57e07d7f4cc..00000000000 --- a/app/assets/images/emoji/pushpin.png +++ /dev/null diff --git a/app/assets/images/emoji/put_litter_in_its_place.png b/app/assets/images/emoji/put_litter_in_its_place.png Binary files differdeleted file mode 100644 index 82a84f9a375..00000000000 --- a/app/assets/images/emoji/put_litter_in_its_place.png +++ /dev/null diff --git a/app/assets/images/emoji/question.png b/app/assets/images/emoji/question.png Binary files differdeleted file mode 100644 index 5a58f3458aa..00000000000 --- a/app/assets/images/emoji/question.png +++ /dev/null diff --git a/app/assets/images/emoji/rabbit.png b/app/assets/images/emoji/rabbit.png Binary files differdeleted file mode 100644 index ea75ab0426e..00000000000 --- a/app/assets/images/emoji/rabbit.png +++ /dev/null diff --git a/app/assets/images/emoji/rabbit2.png b/app/assets/images/emoji/rabbit2.png Binary files differdeleted file mode 100644 index 2c8a29c642f..00000000000 --- a/app/assets/images/emoji/rabbit2.png +++ /dev/null diff --git a/app/assets/images/emoji/race_car.png b/app/assets/images/emoji/race_car.png Binary files differdeleted file mode 100644 index fe3f045f446..00000000000 --- a/app/assets/images/emoji/race_car.png +++ /dev/null diff --git a/app/assets/images/emoji/racehorse.png b/app/assets/images/emoji/racehorse.png Binary files differdeleted file mode 100644 index b3e73cc8903..00000000000 --- a/app/assets/images/emoji/racehorse.png +++ /dev/null diff --git a/app/assets/images/emoji/radio.png b/app/assets/images/emoji/radio.png Binary files differdeleted file mode 100644 index dec381fa242..00000000000 --- a/app/assets/images/emoji/radio.png +++ /dev/null diff --git a/app/assets/images/emoji/radio_button.png b/app/assets/images/emoji/radio_button.png Binary files differdeleted file mode 100644 index 3a23449d917..00000000000 --- a/app/assets/images/emoji/radio_button.png +++ /dev/null diff --git a/app/assets/images/emoji/radioactive.png b/app/assets/images/emoji/radioactive.png Binary files differdeleted file mode 100644 index 3b46199fe37..00000000000 --- a/app/assets/images/emoji/radioactive.png +++ /dev/null diff --git a/app/assets/images/emoji/rage.png b/app/assets/images/emoji/rage.png Binary files differdeleted file mode 100644 index 9d739bd40ad..00000000000 --- a/app/assets/images/emoji/rage.png +++ /dev/null diff --git a/app/assets/images/emoji/railway_car.png b/app/assets/images/emoji/railway_car.png Binary files differdeleted file mode 100644 index a9acbf13008..00000000000 --- a/app/assets/images/emoji/railway_car.png +++ /dev/null diff --git a/app/assets/images/emoji/railway_track.png b/app/assets/images/emoji/railway_track.png Binary files differdeleted file mode 100644 index e1a7a0d1430..00000000000 --- a/app/assets/images/emoji/railway_track.png +++ /dev/null diff --git a/app/assets/images/emoji/rainbow.png b/app/assets/images/emoji/rainbow.png Binary files differdeleted file mode 100644 index 154735d7147..00000000000 --- a/app/assets/images/emoji/rainbow.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_back_of_hand.png b/app/assets/images/emoji/raised_back_of_hand.png Binary files differdeleted file mode 100644 index 479234294b4..00000000000 --- a/app/assets/images/emoji/raised_back_of_hand.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_back_of_hand_tone1.png b/app/assets/images/emoji/raised_back_of_hand_tone1.png Binary files differdeleted file mode 100644 index 813d28499b5..00000000000 --- a/app/assets/images/emoji/raised_back_of_hand_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_back_of_hand_tone2.png b/app/assets/images/emoji/raised_back_of_hand_tone2.png Binary files differdeleted file mode 100644 index 192ff795e37..00000000000 --- a/app/assets/images/emoji/raised_back_of_hand_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_back_of_hand_tone3.png b/app/assets/images/emoji/raised_back_of_hand_tone3.png Binary files differdeleted file mode 100644 index 61a727abe6b..00000000000 --- a/app/assets/images/emoji/raised_back_of_hand_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_back_of_hand_tone4.png b/app/assets/images/emoji/raised_back_of_hand_tone4.png Binary files differdeleted file mode 100644 index 2e83da511f5..00000000000 --- a/app/assets/images/emoji/raised_back_of_hand_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_back_of_hand_tone5.png b/app/assets/images/emoji/raised_back_of_hand_tone5.png Binary files differdeleted file mode 100644 index d7a5b95a02c..00000000000 --- a/app/assets/images/emoji/raised_back_of_hand_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hand.png b/app/assets/images/emoji/raised_hand.png Binary files differdeleted file mode 100644 index 6b2954315d1..00000000000 --- a/app/assets/images/emoji/raised_hand.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hand_tone1.png b/app/assets/images/emoji/raised_hand_tone1.png Binary files differdeleted file mode 100644 index 3b752902c07..00000000000 --- a/app/assets/images/emoji/raised_hand_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hand_tone2.png b/app/assets/images/emoji/raised_hand_tone2.png Binary files differdeleted file mode 100644 index 44e2a514c60..00000000000 --- a/app/assets/images/emoji/raised_hand_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hand_tone3.png b/app/assets/images/emoji/raised_hand_tone3.png Binary files differdeleted file mode 100644 index 5bb62a7528a..00000000000 --- a/app/assets/images/emoji/raised_hand_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hand_tone4.png b/app/assets/images/emoji/raised_hand_tone4.png Binary files differdeleted file mode 100644 index c7f8c9ec270..00000000000 --- a/app/assets/images/emoji/raised_hand_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hand_tone5.png b/app/assets/images/emoji/raised_hand_tone5.png Binary files differdeleted file mode 100644 index c601b58a73e..00000000000 --- a/app/assets/images/emoji/raised_hand_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hands.png b/app/assets/images/emoji/raised_hands.png Binary files differdeleted file mode 100644 index c0155f728e7..00000000000 --- a/app/assets/images/emoji/raised_hands.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hands_tone1.png b/app/assets/images/emoji/raised_hands_tone1.png Binary files differdeleted file mode 100644 index 1168b8236b6..00000000000 --- a/app/assets/images/emoji/raised_hands_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hands_tone2.png b/app/assets/images/emoji/raised_hands_tone2.png Binary files differdeleted file mode 100644 index 322de622903..00000000000 --- a/app/assets/images/emoji/raised_hands_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hands_tone3.png b/app/assets/images/emoji/raised_hands_tone3.png Binary files differdeleted file mode 100644 index 2aa24e05ae1..00000000000 --- a/app/assets/images/emoji/raised_hands_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hands_tone4.png b/app/assets/images/emoji/raised_hands_tone4.png Binary files differdeleted file mode 100644 index f31bf0db992..00000000000 --- a/app/assets/images/emoji/raised_hands_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/raised_hands_tone5.png b/app/assets/images/emoji/raised_hands_tone5.png Binary files differdeleted file mode 100644 index 5e95067f98b..00000000000 --- a/app/assets/images/emoji/raised_hands_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/raising_hand.png b/app/assets/images/emoji/raising_hand.png Binary files differdeleted file mode 100644 index 2880708c0cc..00000000000 --- a/app/assets/images/emoji/raising_hand.png +++ /dev/null diff --git a/app/assets/images/emoji/raising_hand_tone1.png b/app/assets/images/emoji/raising_hand_tone1.png Binary files differdeleted file mode 100644 index 1c90e3e2689..00000000000 --- a/app/assets/images/emoji/raising_hand_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/raising_hand_tone2.png b/app/assets/images/emoji/raising_hand_tone2.png Binary files differdeleted file mode 100644 index 82c3ef2bfc5..00000000000 --- a/app/assets/images/emoji/raising_hand_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/raising_hand_tone3.png b/app/assets/images/emoji/raising_hand_tone3.png Binary files differdeleted file mode 100644 index 1b1da2aa0ca..00000000000 --- a/app/assets/images/emoji/raising_hand_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/raising_hand_tone4.png b/app/assets/images/emoji/raising_hand_tone4.png Binary files differdeleted file mode 100644 index e453855c01f..00000000000 --- a/app/assets/images/emoji/raising_hand_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/raising_hand_tone5.png b/app/assets/images/emoji/raising_hand_tone5.png Binary files differdeleted file mode 100644 index b86200fd844..00000000000 --- a/app/assets/images/emoji/raising_hand_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/ram.png b/app/assets/images/emoji/ram.png Binary files differdeleted file mode 100644 index 52a44464c9b..00000000000 --- a/app/assets/images/emoji/ram.png +++ /dev/null diff --git a/app/assets/images/emoji/ramen.png b/app/assets/images/emoji/ramen.png Binary files differdeleted file mode 100644 index c1cb7cd7384..00000000000 --- a/app/assets/images/emoji/ramen.png +++ /dev/null diff --git a/app/assets/images/emoji/rat.png b/app/assets/images/emoji/rat.png Binary files differdeleted file mode 100644 index 86219144f10..00000000000 --- a/app/assets/images/emoji/rat.png +++ /dev/null diff --git a/app/assets/images/emoji/record_button.png b/app/assets/images/emoji/record_button.png Binary files differdeleted file mode 100644 index ada52830fce..00000000000 --- a/app/assets/images/emoji/record_button.png +++ /dev/null diff --git a/app/assets/images/emoji/recycle.png b/app/assets/images/emoji/recycle.png Binary files differdeleted file mode 100644 index 9221f095c37..00000000000 --- a/app/assets/images/emoji/recycle.png +++ /dev/null diff --git a/app/assets/images/emoji/red_car.png b/app/assets/images/emoji/red_car.png Binary files differdeleted file mode 100644 index b3e6a774dea..00000000000 --- a/app/assets/images/emoji/red_car.png +++ /dev/null diff --git a/app/assets/images/emoji/red_circle.png b/app/assets/images/emoji/red_circle.png Binary files differdeleted file mode 100644 index 4bef930d92f..00000000000 --- a/app/assets/images/emoji/red_circle.png +++ /dev/null diff --git a/app/assets/images/emoji/registered.png b/app/assets/images/emoji/registered.png Binary files differdeleted file mode 100644 index 53ef9f2d4e6..00000000000 --- a/app/assets/images/emoji/registered.png +++ /dev/null diff --git a/app/assets/images/emoji/relaxed.png b/app/assets/images/emoji/relaxed.png Binary files differdeleted file mode 100644 index e9e53c03d45..00000000000 --- a/app/assets/images/emoji/relaxed.png +++ /dev/null diff --git a/app/assets/images/emoji/relieved.png b/app/assets/images/emoji/relieved.png Binary files differdeleted file mode 100644 index 715ad0bf53f..00000000000 --- a/app/assets/images/emoji/relieved.png +++ /dev/null diff --git a/app/assets/images/emoji/reminder_ribbon.png b/app/assets/images/emoji/reminder_ribbon.png Binary files differdeleted file mode 100644 index 3988bbd094c..00000000000 --- a/app/assets/images/emoji/reminder_ribbon.png +++ /dev/null diff --git a/app/assets/images/emoji/repeat.png b/app/assets/images/emoji/repeat.png Binary files differdeleted file mode 100644 index 540ce4e0fba..00000000000 --- a/app/assets/images/emoji/repeat.png +++ /dev/null diff --git a/app/assets/images/emoji/repeat_one.png b/app/assets/images/emoji/repeat_one.png Binary files differdeleted file mode 100644 index 9567e83337f..00000000000 --- a/app/assets/images/emoji/repeat_one.png +++ /dev/null diff --git a/app/assets/images/emoji/restroom.png b/app/assets/images/emoji/restroom.png Binary files differdeleted file mode 100644 index 9588e0f0ef7..00000000000 --- a/app/assets/images/emoji/restroom.png +++ /dev/null diff --git a/app/assets/images/emoji/revolving_hearts.png b/app/assets/images/emoji/revolving_hearts.png Binary files differdeleted file mode 100644 index 7b9d1948f73..00000000000 --- a/app/assets/images/emoji/revolving_hearts.png +++ /dev/null diff --git a/app/assets/images/emoji/rewind.png b/app/assets/images/emoji/rewind.png Binary files differdeleted file mode 100644 index e22e2bd3da5..00000000000 --- a/app/assets/images/emoji/rewind.png +++ /dev/null diff --git a/app/assets/images/emoji/rhino.png b/app/assets/images/emoji/rhino.png Binary files differdeleted file mode 100644 index 12f4e0d9d9b..00000000000 --- a/app/assets/images/emoji/rhino.png +++ /dev/null diff --git a/app/assets/images/emoji/ribbon.png b/app/assets/images/emoji/ribbon.png Binary files differdeleted file mode 100644 index 0f253c3d8c8..00000000000 --- a/app/assets/images/emoji/ribbon.png +++ /dev/null diff --git a/app/assets/images/emoji/rice.png b/app/assets/images/emoji/rice.png Binary files differdeleted file mode 100644 index 6e3ac7956b1..00000000000 --- a/app/assets/images/emoji/rice.png +++ /dev/null diff --git a/app/assets/images/emoji/rice_ball.png b/app/assets/images/emoji/rice_ball.png Binary files differdeleted file mode 100644 index d3d8ee25cb8..00000000000 --- a/app/assets/images/emoji/rice_ball.png +++ /dev/null diff --git a/app/assets/images/emoji/rice_cracker.png b/app/assets/images/emoji/rice_cracker.png Binary files differdeleted file mode 100644 index 7fbd08e4ff9..00000000000 --- a/app/assets/images/emoji/rice_cracker.png +++ /dev/null diff --git a/app/assets/images/emoji/rice_scene.png b/app/assets/images/emoji/rice_scene.png Binary files differdeleted file mode 100644 index 1a28426592a..00000000000 --- a/app/assets/images/emoji/rice_scene.png +++ /dev/null diff --git a/app/assets/images/emoji/right_facing_fist.png b/app/assets/images/emoji/right_facing_fist.png Binary files differdeleted file mode 100644 index 754ed066d2c..00000000000 --- a/app/assets/images/emoji/right_facing_fist.png +++ /dev/null diff --git a/app/assets/images/emoji/right_facing_fist_tone1.png b/app/assets/images/emoji/right_facing_fist_tone1.png Binary files differdeleted file mode 100644 index 33ded2f61a6..00000000000 --- a/app/assets/images/emoji/right_facing_fist_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/right_facing_fist_tone2.png b/app/assets/images/emoji/right_facing_fist_tone2.png Binary files differdeleted file mode 100644 index 88054e335c7..00000000000 --- a/app/assets/images/emoji/right_facing_fist_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/right_facing_fist_tone3.png b/app/assets/images/emoji/right_facing_fist_tone3.png Binary files differdeleted file mode 100644 index 84b9f5da7f7..00000000000 --- a/app/assets/images/emoji/right_facing_fist_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/right_facing_fist_tone4.png b/app/assets/images/emoji/right_facing_fist_tone4.png Binary files differdeleted file mode 100644 index e741cfea68b..00000000000 --- a/app/assets/images/emoji/right_facing_fist_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/right_facing_fist_tone5.png b/app/assets/images/emoji/right_facing_fist_tone5.png Binary files differdeleted file mode 100644 index cf66d760c1f..00000000000 --- a/app/assets/images/emoji/right_facing_fist_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/ring.png b/app/assets/images/emoji/ring.png Binary files differdeleted file mode 100644 index 87d227adb74..00000000000 --- a/app/assets/images/emoji/ring.png +++ /dev/null diff --git a/app/assets/images/emoji/robot.png b/app/assets/images/emoji/robot.png Binary files differdeleted file mode 100644 index 7cc62612c6a..00000000000 --- a/app/assets/images/emoji/robot.png +++ /dev/null diff --git a/app/assets/images/emoji/rocket.png b/app/assets/images/emoji/rocket.png Binary files differdeleted file mode 100644 index 0d8da089a37..00000000000 --- a/app/assets/images/emoji/rocket.png +++ /dev/null diff --git a/app/assets/images/emoji/rofl.png b/app/assets/images/emoji/rofl.png Binary files differdeleted file mode 100644 index b1736fedfeb..00000000000 --- a/app/assets/images/emoji/rofl.png +++ /dev/null diff --git a/app/assets/images/emoji/roller_coaster.png b/app/assets/images/emoji/roller_coaster.png Binary files differdeleted file mode 100644 index 5b849e071e8..00000000000 --- a/app/assets/images/emoji/roller_coaster.png +++ /dev/null diff --git a/app/assets/images/emoji/rolling_eyes.png b/app/assets/images/emoji/rolling_eyes.png Binary files differdeleted file mode 100644 index 2f77b9fc3b9..00000000000 --- a/app/assets/images/emoji/rolling_eyes.png +++ /dev/null diff --git a/app/assets/images/emoji/rooster.png b/app/assets/images/emoji/rooster.png Binary files differdeleted file mode 100644 index bbf2bbff97a..00000000000 --- a/app/assets/images/emoji/rooster.png +++ /dev/null diff --git a/app/assets/images/emoji/rose.png b/app/assets/images/emoji/rose.png Binary files differdeleted file mode 100644 index 52c286d31ce..00000000000 --- a/app/assets/images/emoji/rose.png +++ /dev/null diff --git a/app/assets/images/emoji/rosette.png b/app/assets/images/emoji/rosette.png Binary files differdeleted file mode 100644 index 8030e494bcf..00000000000 --- a/app/assets/images/emoji/rosette.png +++ /dev/null diff --git a/app/assets/images/emoji/rotating_light.png b/app/assets/images/emoji/rotating_light.png Binary files differdeleted file mode 100644 index cad66b0afef..00000000000 --- a/app/assets/images/emoji/rotating_light.png +++ /dev/null diff --git a/app/assets/images/emoji/round_pushpin.png b/app/assets/images/emoji/round_pushpin.png Binary files differdeleted file mode 100644 index 28b9d72866e..00000000000 --- a/app/assets/images/emoji/round_pushpin.png +++ /dev/null diff --git a/app/assets/images/emoji/rowboat.png b/app/assets/images/emoji/rowboat.png Binary files differdeleted file mode 100644 index dd4dfc095d9..00000000000 --- a/app/assets/images/emoji/rowboat.png +++ /dev/null diff --git a/app/assets/images/emoji/rowboat_tone1.png b/app/assets/images/emoji/rowboat_tone1.png Binary files differdeleted file mode 100644 index 5e5d18548cb..00000000000 --- a/app/assets/images/emoji/rowboat_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/rowboat_tone2.png b/app/assets/images/emoji/rowboat_tone2.png Binary files differdeleted file mode 100644 index 9b123ef8871..00000000000 --- a/app/assets/images/emoji/rowboat_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/rowboat_tone3.png b/app/assets/images/emoji/rowboat_tone3.png Binary files differdeleted file mode 100644 index 8ebd89a55f5..00000000000 --- a/app/assets/images/emoji/rowboat_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/rowboat_tone4.png b/app/assets/images/emoji/rowboat_tone4.png Binary files differdeleted file mode 100644 index 2b0d04f8725..00000000000 --- a/app/assets/images/emoji/rowboat_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/rowboat_tone5.png b/app/assets/images/emoji/rowboat_tone5.png Binary files differdeleted file mode 100644 index b346f2dfc84..00000000000 --- a/app/assets/images/emoji/rowboat_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/rugby_football.png b/app/assets/images/emoji/rugby_football.png Binary files differdeleted file mode 100644 index b1872273436..00000000000 --- a/app/assets/images/emoji/rugby_football.png +++ /dev/null diff --git a/app/assets/images/emoji/runner.png b/app/assets/images/emoji/runner.png Binary files differdeleted file mode 100644 index e914915976a..00000000000 --- a/app/assets/images/emoji/runner.png +++ /dev/null diff --git a/app/assets/images/emoji/runner_tone1.png b/app/assets/images/emoji/runner_tone1.png Binary files differdeleted file mode 100644 index 9355239a52d..00000000000 --- a/app/assets/images/emoji/runner_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/runner_tone2.png b/app/assets/images/emoji/runner_tone2.png Binary files differdeleted file mode 100644 index 6112fd5c376..00000000000 --- a/app/assets/images/emoji/runner_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/runner_tone3.png b/app/assets/images/emoji/runner_tone3.png Binary files differdeleted file mode 100644 index 625ec708f48..00000000000 --- a/app/assets/images/emoji/runner_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/runner_tone4.png b/app/assets/images/emoji/runner_tone4.png Binary files differdeleted file mode 100644 index 242f1b56337..00000000000 --- a/app/assets/images/emoji/runner_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/runner_tone5.png b/app/assets/images/emoji/runner_tone5.png Binary files differdeleted file mode 100644 index 2976c6f019f..00000000000 --- a/app/assets/images/emoji/runner_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/running_shirt_with_sash.png b/app/assets/images/emoji/running_shirt_with_sash.png Binary files differdeleted file mode 100644 index 6d83c06b803..00000000000 --- a/app/assets/images/emoji/running_shirt_with_sash.png +++ /dev/null diff --git a/app/assets/images/emoji/sa.png b/app/assets/images/emoji/sa.png Binary files differdeleted file mode 100644 index 900f9633247..00000000000 --- a/app/assets/images/emoji/sa.png +++ /dev/null diff --git a/app/assets/images/emoji/sagittarius.png b/app/assets/images/emoji/sagittarius.png Binary files differdeleted file mode 100644 index f8d94ff2923..00000000000 --- a/app/assets/images/emoji/sagittarius.png +++ /dev/null diff --git a/app/assets/images/emoji/sailboat.png b/app/assets/images/emoji/sailboat.png Binary files differdeleted file mode 100644 index 772ef11da5d..00000000000 --- a/app/assets/images/emoji/sailboat.png +++ /dev/null diff --git a/app/assets/images/emoji/sake.png b/app/assets/images/emoji/sake.png Binary files differdeleted file mode 100644 index 2933f5672c4..00000000000 --- a/app/assets/images/emoji/sake.png +++ /dev/null diff --git a/app/assets/images/emoji/salad.png b/app/assets/images/emoji/salad.png Binary files differdeleted file mode 100644 index c89f9341158..00000000000 --- a/app/assets/images/emoji/salad.png +++ /dev/null diff --git a/app/assets/images/emoji/sandal.png b/app/assets/images/emoji/sandal.png Binary files differdeleted file mode 100644 index 9d9f5122b7a..00000000000 --- a/app/assets/images/emoji/sandal.png +++ /dev/null diff --git a/app/assets/images/emoji/santa.png b/app/assets/images/emoji/santa.png Binary files differdeleted file mode 100644 index bc83ab80d52..00000000000 --- a/app/assets/images/emoji/santa.png +++ /dev/null diff --git a/app/assets/images/emoji/santa_tone1.png b/app/assets/images/emoji/santa_tone1.png Binary files differdeleted file mode 100644 index 5233ffb7174..00000000000 --- a/app/assets/images/emoji/santa_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/santa_tone2.png b/app/assets/images/emoji/santa_tone2.png Binary files differdeleted file mode 100644 index 4e845438197..00000000000 --- a/app/assets/images/emoji/santa_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/santa_tone3.png b/app/assets/images/emoji/santa_tone3.png Binary files differdeleted file mode 100644 index 7fc4f33b60f..00000000000 --- a/app/assets/images/emoji/santa_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/santa_tone4.png b/app/assets/images/emoji/santa_tone4.png Binary files differdeleted file mode 100644 index d1d5a15132d..00000000000 --- a/app/assets/images/emoji/santa_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/santa_tone5.png b/app/assets/images/emoji/santa_tone5.png Binary files differdeleted file mode 100644 index 4d697a01f24..00000000000 --- a/app/assets/images/emoji/santa_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/satellite.png b/app/assets/images/emoji/satellite.png Binary files differdeleted file mode 100644 index db0372795f4..00000000000 --- a/app/assets/images/emoji/satellite.png +++ /dev/null diff --git a/app/assets/images/emoji/satellite_orbital.png b/app/assets/images/emoji/satellite_orbital.png Binary files differdeleted file mode 100644 index 4ba55d6e297..00000000000 --- a/app/assets/images/emoji/satellite_orbital.png +++ /dev/null diff --git a/app/assets/images/emoji/saxophone.png b/app/assets/images/emoji/saxophone.png Binary files differdeleted file mode 100644 index a392faec291..00000000000 --- a/app/assets/images/emoji/saxophone.png +++ /dev/null diff --git a/app/assets/images/emoji/scales.png b/app/assets/images/emoji/scales.png Binary files differdeleted file mode 100644 index 0757eda1684..00000000000 --- a/app/assets/images/emoji/scales.png +++ /dev/null diff --git a/app/assets/images/emoji/school.png b/app/assets/images/emoji/school.png Binary files differdeleted file mode 100644 index 269759534f0..00000000000 --- a/app/assets/images/emoji/school.png +++ /dev/null diff --git a/app/assets/images/emoji/school_satchel.png b/app/assets/images/emoji/school_satchel.png Binary files differdeleted file mode 100644 index 9997c86e7dc..00000000000 --- a/app/assets/images/emoji/school_satchel.png +++ /dev/null diff --git a/app/assets/images/emoji/scissors.png b/app/assets/images/emoji/scissors.png Binary files differdeleted file mode 100644 index 270571c8cdd..00000000000 --- a/app/assets/images/emoji/scissors.png +++ /dev/null diff --git a/app/assets/images/emoji/scooter.png b/app/assets/images/emoji/scooter.png Binary files differdeleted file mode 100644 index 4ab7ef59cd2..00000000000 --- a/app/assets/images/emoji/scooter.png +++ /dev/null diff --git a/app/assets/images/emoji/scorpion.png b/app/assets/images/emoji/scorpion.png Binary files differdeleted file mode 100644 index 449a6b281c9..00000000000 --- a/app/assets/images/emoji/scorpion.png +++ /dev/null diff --git a/app/assets/images/emoji/scorpius.png b/app/assets/images/emoji/scorpius.png Binary files differdeleted file mode 100644 index c31a9920455..00000000000 --- a/app/assets/images/emoji/scorpius.png +++ /dev/null diff --git a/app/assets/images/emoji/scream.png b/app/assets/images/emoji/scream.png Binary files differdeleted file mode 100644 index c3bea9f2510..00000000000 --- a/app/assets/images/emoji/scream.png +++ /dev/null diff --git a/app/assets/images/emoji/scream_cat.png b/app/assets/images/emoji/scream_cat.png Binary files differdeleted file mode 100644 index 15803ad8e6e..00000000000 --- a/app/assets/images/emoji/scream_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/scroll.png b/app/assets/images/emoji/scroll.png Binary files differdeleted file mode 100644 index 50ee5dcd4b9..00000000000 --- a/app/assets/images/emoji/scroll.png +++ /dev/null diff --git a/app/assets/images/emoji/seat.png b/app/assets/images/emoji/seat.png Binary files differdeleted file mode 100644 index a6d72d95adb..00000000000 --- a/app/assets/images/emoji/seat.png +++ /dev/null diff --git a/app/assets/images/emoji/second_place.png b/app/assets/images/emoji/second_place.png Binary files differdeleted file mode 100644 index 17b011268b6..00000000000 --- a/app/assets/images/emoji/second_place.png +++ /dev/null diff --git a/app/assets/images/emoji/secret.png b/app/assets/images/emoji/secret.png Binary files differdeleted file mode 100644 index 5fd72608e60..00000000000 --- a/app/assets/images/emoji/secret.png +++ /dev/null diff --git a/app/assets/images/emoji/see_no_evil.png b/app/assets/images/emoji/see_no_evil.png Binary files differdeleted file mode 100644 index 5187e474531..00000000000 --- a/app/assets/images/emoji/see_no_evil.png +++ /dev/null diff --git a/app/assets/images/emoji/seedling.png b/app/assets/images/emoji/seedling.png Binary files differdeleted file mode 100644 index ae0948bcfd6..00000000000 --- a/app/assets/images/emoji/seedling.png +++ /dev/null diff --git a/app/assets/images/emoji/selfie.png b/app/assets/images/emoji/selfie.png Binary files differdeleted file mode 100644 index 6a1ba75c7e3..00000000000 --- a/app/assets/images/emoji/selfie.png +++ /dev/null diff --git a/app/assets/images/emoji/selfie_tone1.png b/app/assets/images/emoji/selfie_tone1.png Binary files differdeleted file mode 100644 index 290e075b56f..00000000000 --- a/app/assets/images/emoji/selfie_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/selfie_tone2.png b/app/assets/images/emoji/selfie_tone2.png Binary files differdeleted file mode 100644 index fcd9595b643..00000000000 --- a/app/assets/images/emoji/selfie_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/selfie_tone3.png b/app/assets/images/emoji/selfie_tone3.png Binary files differdeleted file mode 100644 index f3a22fdf435..00000000000 --- a/app/assets/images/emoji/selfie_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/selfie_tone4.png b/app/assets/images/emoji/selfie_tone4.png Binary files differdeleted file mode 100644 index cdecf6d9f4e..00000000000 --- a/app/assets/images/emoji/selfie_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/selfie_tone5.png b/app/assets/images/emoji/selfie_tone5.png Binary files differdeleted file mode 100644 index 86acbb6c202..00000000000 --- a/app/assets/images/emoji/selfie_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/seven.png b/app/assets/images/emoji/seven.png Binary files differdeleted file mode 100644 index 9b3476ae7c7..00000000000 --- a/app/assets/images/emoji/seven.png +++ /dev/null diff --git a/app/assets/images/emoji/shallow_pan_of_food.png b/app/assets/images/emoji/shallow_pan_of_food.png Binary files differdeleted file mode 100644 index 663a1006acd..00000000000 --- a/app/assets/images/emoji/shallow_pan_of_food.png +++ /dev/null diff --git a/app/assets/images/emoji/shamrock.png b/app/assets/images/emoji/shamrock.png Binary files differdeleted file mode 100644 index f202aecfe6f..00000000000 --- a/app/assets/images/emoji/shamrock.png +++ /dev/null diff --git a/app/assets/images/emoji/shark.png b/app/assets/images/emoji/shark.png Binary files differdeleted file mode 100644 index c75076d57d8..00000000000 --- a/app/assets/images/emoji/shark.png +++ /dev/null diff --git a/app/assets/images/emoji/shaved_ice.png b/app/assets/images/emoji/shaved_ice.png Binary files differdeleted file mode 100644 index 36dfb53ca93..00000000000 --- a/app/assets/images/emoji/shaved_ice.png +++ /dev/null diff --git a/app/assets/images/emoji/sheep.png b/app/assets/images/emoji/sheep.png Binary files differdeleted file mode 100644 index 102b8a52b28..00000000000 --- a/app/assets/images/emoji/sheep.png +++ /dev/null diff --git a/app/assets/images/emoji/shell.png b/app/assets/images/emoji/shell.png Binary files differdeleted file mode 100644 index 55721629f62..00000000000 --- a/app/assets/images/emoji/shell.png +++ /dev/null diff --git a/app/assets/images/emoji/shield.png b/app/assets/images/emoji/shield.png Binary files differdeleted file mode 100644 index 610bf033ce0..00000000000 --- a/app/assets/images/emoji/shield.png +++ /dev/null diff --git a/app/assets/images/emoji/shinto_shrine.png b/app/assets/images/emoji/shinto_shrine.png Binary files differdeleted file mode 100644 index 5a344975bf3..00000000000 --- a/app/assets/images/emoji/shinto_shrine.png +++ /dev/null diff --git a/app/assets/images/emoji/ship.png b/app/assets/images/emoji/ship.png Binary files differdeleted file mode 100644 index 62d54f7d6c9..00000000000 --- a/app/assets/images/emoji/ship.png +++ /dev/null diff --git a/app/assets/images/emoji/shirt.png b/app/assets/images/emoji/shirt.png Binary files differdeleted file mode 100644 index af08dec8b59..00000000000 --- a/app/assets/images/emoji/shirt.png +++ /dev/null diff --git a/app/assets/images/emoji/shopping_bags.png b/app/assets/images/emoji/shopping_bags.png Binary files differdeleted file mode 100644 index 99f2a2b13ac..00000000000 --- a/app/assets/images/emoji/shopping_bags.png +++ /dev/null diff --git a/app/assets/images/emoji/shopping_cart.png b/app/assets/images/emoji/shopping_cart.png Binary files differdeleted file mode 100644 index 1086fe6e456..00000000000 --- a/app/assets/images/emoji/shopping_cart.png +++ /dev/null diff --git a/app/assets/images/emoji/shower.png b/app/assets/images/emoji/shower.png Binary files differdeleted file mode 100644 index 156776a2e52..00000000000 --- a/app/assets/images/emoji/shower.png +++ /dev/null diff --git a/app/assets/images/emoji/shrimp.png b/app/assets/images/emoji/shrimp.png Binary files differdeleted file mode 100644 index 49eff28a71e..00000000000 --- a/app/assets/images/emoji/shrimp.png +++ /dev/null diff --git a/app/assets/images/emoji/shrug.png b/app/assets/images/emoji/shrug.png Binary files differdeleted file mode 100644 index 76e63bfac77..00000000000 --- a/app/assets/images/emoji/shrug.png +++ /dev/null diff --git a/app/assets/images/emoji/shrug_tone1.png b/app/assets/images/emoji/shrug_tone1.png Binary files differdeleted file mode 100644 index 1c895e64468..00000000000 --- a/app/assets/images/emoji/shrug_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/shrug_tone2.png b/app/assets/images/emoji/shrug_tone2.png Binary files differdeleted file mode 100644 index 4e3ca8f8bac..00000000000 --- a/app/assets/images/emoji/shrug_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/shrug_tone3.png b/app/assets/images/emoji/shrug_tone3.png Binary files differdeleted file mode 100644 index d1b16a19bb5..00000000000 --- a/app/assets/images/emoji/shrug_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/shrug_tone4.png b/app/assets/images/emoji/shrug_tone4.png Binary files differdeleted file mode 100644 index 5fbef3f2255..00000000000 --- a/app/assets/images/emoji/shrug_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/shrug_tone5.png b/app/assets/images/emoji/shrug_tone5.png Binary files differdeleted file mode 100644 index 4af2e28bc5c..00000000000 --- a/app/assets/images/emoji/shrug_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/signal_strength.png b/app/assets/images/emoji/signal_strength.png Binary files differdeleted file mode 100644 index ee2b5a4b519..00000000000 --- a/app/assets/images/emoji/signal_strength.png +++ /dev/null diff --git a/app/assets/images/emoji/six.png b/app/assets/images/emoji/six.png Binary files differdeleted file mode 100644 index 371b3acef2c..00000000000 --- a/app/assets/images/emoji/six.png +++ /dev/null diff --git a/app/assets/images/emoji/six_pointed_star.png b/app/assets/images/emoji/six_pointed_star.png Binary files differdeleted file mode 100644 index 2eb1707458b..00000000000 --- a/app/assets/images/emoji/six_pointed_star.png +++ /dev/null diff --git a/app/assets/images/emoji/ski.png b/app/assets/images/emoji/ski.png Binary files differdeleted file mode 100644 index 4a2d2c12306..00000000000 --- a/app/assets/images/emoji/ski.png +++ /dev/null diff --git a/app/assets/images/emoji/skier.png b/app/assets/images/emoji/skier.png Binary files differdeleted file mode 100644 index 2eb3bdce2af..00000000000 --- a/app/assets/images/emoji/skier.png +++ /dev/null diff --git a/app/assets/images/emoji/skull.png b/app/assets/images/emoji/skull.png Binary files differdeleted file mode 100644 index 26abb17296a..00000000000 --- a/app/assets/images/emoji/skull.png +++ /dev/null diff --git a/app/assets/images/emoji/skull_crossbones.png b/app/assets/images/emoji/skull_crossbones.png Binary files differdeleted file mode 100644 index b459df9227a..00000000000 --- a/app/assets/images/emoji/skull_crossbones.png +++ /dev/null diff --git a/app/assets/images/emoji/sleeping.png b/app/assets/images/emoji/sleeping.png Binary files differdeleted file mode 100644 index 9ecf600d6d8..00000000000 --- a/app/assets/images/emoji/sleeping.png +++ /dev/null diff --git a/app/assets/images/emoji/sleeping_accommodation.png b/app/assets/images/emoji/sleeping_accommodation.png Binary files differdeleted file mode 100644 index c739e7fb69b..00000000000 --- a/app/assets/images/emoji/sleeping_accommodation.png +++ /dev/null diff --git a/app/assets/images/emoji/sleepy.png b/app/assets/images/emoji/sleepy.png Binary files differdeleted file mode 100644 index 836b4107717..00000000000 --- a/app/assets/images/emoji/sleepy.png +++ /dev/null diff --git a/app/assets/images/emoji/slight_frown.png b/app/assets/images/emoji/slight_frown.png Binary files differdeleted file mode 100644 index b2f1d983d36..00000000000 --- a/app/assets/images/emoji/slight_frown.png +++ /dev/null diff --git a/app/assets/images/emoji/slight_smile.png b/app/assets/images/emoji/slight_smile.png Binary files differdeleted file mode 100644 index ddd7d65dd3d..00000000000 --- a/app/assets/images/emoji/slight_smile.png +++ /dev/null diff --git a/app/assets/images/emoji/slot_machine.png b/app/assets/images/emoji/slot_machine.png Binary files differdeleted file mode 100644 index ee71b6c268c..00000000000 --- a/app/assets/images/emoji/slot_machine.png +++ /dev/null diff --git a/app/assets/images/emoji/small_blue_diamond.png b/app/assets/images/emoji/small_blue_diamond.png Binary files differdeleted file mode 100644 index b86b5bc4db3..00000000000 --- a/app/assets/images/emoji/small_blue_diamond.png +++ /dev/null diff --git a/app/assets/images/emoji/small_orange_diamond.png b/app/assets/images/emoji/small_orange_diamond.png Binary files differdeleted file mode 100644 index e1c6ed9b2f8..00000000000 --- a/app/assets/images/emoji/small_orange_diamond.png +++ /dev/null diff --git a/app/assets/images/emoji/small_red_triangle.png b/app/assets/images/emoji/small_red_triangle.png Binary files differdeleted file mode 100644 index 785887c195a..00000000000 --- a/app/assets/images/emoji/small_red_triangle.png +++ /dev/null diff --git a/app/assets/images/emoji/small_red_triangle_down.png b/app/assets/images/emoji/small_red_triangle_down.png Binary files differdeleted file mode 100644 index a83beff1914..00000000000 --- a/app/assets/images/emoji/small_red_triangle_down.png +++ /dev/null diff --git a/app/assets/images/emoji/smile.png b/app/assets/images/emoji/smile.png Binary files differdeleted file mode 100644 index aa47ffe978c..00000000000 --- a/app/assets/images/emoji/smile.png +++ /dev/null diff --git a/app/assets/images/emoji/smile_cat.png b/app/assets/images/emoji/smile_cat.png Binary files differdeleted file mode 100644 index 6f25f11dd3a..00000000000 --- a/app/assets/images/emoji/smile_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/smiley.png b/app/assets/images/emoji/smiley.png Binary files differdeleted file mode 100644 index 30957a65968..00000000000 --- a/app/assets/images/emoji/smiley.png +++ /dev/null diff --git a/app/assets/images/emoji/smiley_cat.png b/app/assets/images/emoji/smiley_cat.png Binary files differdeleted file mode 100644 index 163b57a3427..00000000000 --- a/app/assets/images/emoji/smiley_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/smiling_imp.png b/app/assets/images/emoji/smiling_imp.png Binary files differdeleted file mode 100644 index cc2c5f1ec72..00000000000 --- a/app/assets/images/emoji/smiling_imp.png +++ /dev/null diff --git a/app/assets/images/emoji/smirk.png b/app/assets/images/emoji/smirk.png Binary files differdeleted file mode 100644 index 87852109988..00000000000 --- a/app/assets/images/emoji/smirk.png +++ /dev/null diff --git a/app/assets/images/emoji/smirk_cat.png b/app/assets/images/emoji/smirk_cat.png Binary files differdeleted file mode 100644 index 9ac5954c199..00000000000 --- a/app/assets/images/emoji/smirk_cat.png +++ /dev/null diff --git a/app/assets/images/emoji/smoking.png b/app/assets/images/emoji/smoking.png Binary files differdeleted file mode 100644 index 910f648c8f9..00000000000 --- a/app/assets/images/emoji/smoking.png +++ /dev/null diff --git a/app/assets/images/emoji/snail.png b/app/assets/images/emoji/snail.png Binary files differdeleted file mode 100644 index f4ea071e2d3..00000000000 --- a/app/assets/images/emoji/snail.png +++ /dev/null diff --git a/app/assets/images/emoji/snake.png b/app/assets/images/emoji/snake.png Binary files differdeleted file mode 100644 index d0278a28d8c..00000000000 --- a/app/assets/images/emoji/snake.png +++ /dev/null diff --git a/app/assets/images/emoji/sneezing_face.png b/app/assets/images/emoji/sneezing_face.png Binary files differdeleted file mode 100644 index ccf07d4b64d..00000000000 --- a/app/assets/images/emoji/sneezing_face.png +++ /dev/null diff --git a/app/assets/images/emoji/snowboarder.png b/app/assets/images/emoji/snowboarder.png Binary files differdeleted file mode 100644 index 6361c0f2c9d..00000000000 --- a/app/assets/images/emoji/snowboarder.png +++ /dev/null diff --git a/app/assets/images/emoji/snowflake.png b/app/assets/images/emoji/snowflake.png Binary files differdeleted file mode 100644 index db319a77ec6..00000000000 --- a/app/assets/images/emoji/snowflake.png +++ /dev/null diff --git a/app/assets/images/emoji/snowman.png b/app/assets/images/emoji/snowman.png Binary files differdeleted file mode 100644 index 20c177c2aff..00000000000 --- a/app/assets/images/emoji/snowman.png +++ /dev/null diff --git a/app/assets/images/emoji/snowman2.png b/app/assets/images/emoji/snowman2.png Binary files differdeleted file mode 100644 index 896f28502af..00000000000 --- a/app/assets/images/emoji/snowman2.png +++ /dev/null diff --git a/app/assets/images/emoji/sob.png b/app/assets/images/emoji/sob.png Binary files differdeleted file mode 100644 index 52e3517a1ee..00000000000 --- a/app/assets/images/emoji/sob.png +++ /dev/null diff --git a/app/assets/images/emoji/soccer.png b/app/assets/images/emoji/soccer.png Binary files differdeleted file mode 100644 index 28cfa218d6d..00000000000 --- a/app/assets/images/emoji/soccer.png +++ /dev/null diff --git a/app/assets/images/emoji/soon.png b/app/assets/images/emoji/soon.png Binary files differdeleted file mode 100644 index 8cdfd86690d..00000000000 --- a/app/assets/images/emoji/soon.png +++ /dev/null diff --git a/app/assets/images/emoji/sos.png b/app/assets/images/emoji/sos.png Binary files differdeleted file mode 100644 index d7d8c9953e4..00000000000 --- a/app/assets/images/emoji/sos.png +++ /dev/null diff --git a/app/assets/images/emoji/sound.png b/app/assets/images/emoji/sound.png Binary files differdeleted file mode 100644 index e75ddca53ba..00000000000 --- a/app/assets/images/emoji/sound.png +++ /dev/null diff --git a/app/assets/images/emoji/space_invader.png b/app/assets/images/emoji/space_invader.png Binary files differdeleted file mode 100644 index 2e73f5f32e5..00000000000 --- a/app/assets/images/emoji/space_invader.png +++ /dev/null diff --git a/app/assets/images/emoji/spades.png b/app/assets/images/emoji/spades.png Binary files differdeleted file mode 100644 index f822f184cb0..00000000000 --- a/app/assets/images/emoji/spades.png +++ /dev/null diff --git a/app/assets/images/emoji/spaghetti.png b/app/assets/images/emoji/spaghetti.png Binary files differdeleted file mode 100644 index 89c24a321f1..00000000000 --- a/app/assets/images/emoji/spaghetti.png +++ /dev/null diff --git a/app/assets/images/emoji/sparkle.png b/app/assets/images/emoji/sparkle.png Binary files differdeleted file mode 100644 index 6aa7b6ec9cf..00000000000 --- a/app/assets/images/emoji/sparkle.png +++ /dev/null diff --git a/app/assets/images/emoji/sparkler.png b/app/assets/images/emoji/sparkler.png Binary files differdeleted file mode 100644 index 30339cd6e09..00000000000 --- a/app/assets/images/emoji/sparkler.png +++ /dev/null diff --git a/app/assets/images/emoji/sparkles.png b/app/assets/images/emoji/sparkles.png Binary files differdeleted file mode 100644 index 169bc10b023..00000000000 --- a/app/assets/images/emoji/sparkles.png +++ /dev/null diff --git a/app/assets/images/emoji/sparkling_heart.png b/app/assets/images/emoji/sparkling_heart.png Binary files differdeleted file mode 100644 index 6709269454e..00000000000 --- a/app/assets/images/emoji/sparkling_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/speak_no_evil.png b/app/assets/images/emoji/speak_no_evil.png Binary files differdeleted file mode 100644 index 9d9e07c974b..00000000000 --- a/app/assets/images/emoji/speak_no_evil.png +++ /dev/null diff --git a/app/assets/images/emoji/speaker.png b/app/assets/images/emoji/speaker.png Binary files differdeleted file mode 100644 index 7bcffb8fc43..00000000000 --- a/app/assets/images/emoji/speaker.png +++ /dev/null diff --git a/app/assets/images/emoji/speaking_head.png b/app/assets/images/emoji/speaking_head.png Binary files differdeleted file mode 100644 index 2df93aaae09..00000000000 --- a/app/assets/images/emoji/speaking_head.png +++ /dev/null diff --git a/app/assets/images/emoji/speech_balloon.png b/app/assets/images/emoji/speech_balloon.png Binary files differdeleted file mode 100644 index a34ef741733..00000000000 --- a/app/assets/images/emoji/speech_balloon.png +++ /dev/null diff --git a/app/assets/images/emoji/speech_left.png b/app/assets/images/emoji/speech_left.png Binary files differdeleted file mode 100644 index 00c05959bcd..00000000000 --- a/app/assets/images/emoji/speech_left.png +++ /dev/null diff --git a/app/assets/images/emoji/speedboat.png b/app/assets/images/emoji/speedboat.png Binary files differdeleted file mode 100644 index 74059d12de1..00000000000 --- a/app/assets/images/emoji/speedboat.png +++ /dev/null diff --git a/app/assets/images/emoji/spider.png b/app/assets/images/emoji/spider.png Binary files differdeleted file mode 100644 index 3849fa90b94..00000000000 --- a/app/assets/images/emoji/spider.png +++ /dev/null diff --git a/app/assets/images/emoji/spider_web.png b/app/assets/images/emoji/spider_web.png Binary files differdeleted file mode 100644 index ba448ee7fba..00000000000 --- a/app/assets/images/emoji/spider_web.png +++ /dev/null diff --git a/app/assets/images/emoji/spoon.png b/app/assets/images/emoji/spoon.png Binary files differdeleted file mode 100644 index 3c4da766aee..00000000000 --- a/app/assets/images/emoji/spoon.png +++ /dev/null diff --git a/app/assets/images/emoji/spy.png b/app/assets/images/emoji/spy.png Binary files differdeleted file mode 100644 index a729e9584d6..00000000000 --- a/app/assets/images/emoji/spy.png +++ /dev/null diff --git a/app/assets/images/emoji/spy_tone1.png b/app/assets/images/emoji/spy_tone1.png Binary files differdeleted file mode 100644 index 2d1c022caee..00000000000 --- a/app/assets/images/emoji/spy_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/spy_tone2.png b/app/assets/images/emoji/spy_tone2.png Binary files differdeleted file mode 100644 index 548b9c26f5d..00000000000 --- a/app/assets/images/emoji/spy_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/spy_tone3.png b/app/assets/images/emoji/spy_tone3.png Binary files differdeleted file mode 100644 index b023f4b18e1..00000000000 --- a/app/assets/images/emoji/spy_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/spy_tone4.png b/app/assets/images/emoji/spy_tone4.png Binary files differdeleted file mode 100644 index d8300af492d..00000000000 --- a/app/assets/images/emoji/spy_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/spy_tone5.png b/app/assets/images/emoji/spy_tone5.png Binary files differdeleted file mode 100644 index ca1462595fa..00000000000 --- a/app/assets/images/emoji/spy_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/squid.png b/app/assets/images/emoji/squid.png Binary files differdeleted file mode 100644 index d2af223f0cb..00000000000 --- a/app/assets/images/emoji/squid.png +++ /dev/null diff --git a/app/assets/images/emoji/stadium.png b/app/assets/images/emoji/stadium.png Binary files differdeleted file mode 100644 index 00cd6db5e29..00000000000 --- a/app/assets/images/emoji/stadium.png +++ /dev/null diff --git a/app/assets/images/emoji/star.png b/app/assets/images/emoji/star.png Binary files differdeleted file mode 100644 index c930947076e..00000000000 --- a/app/assets/images/emoji/star.png +++ /dev/null diff --git a/app/assets/images/emoji/star2.png b/app/assets/images/emoji/star2.png Binary files differdeleted file mode 100644 index 2f5cba592db..00000000000 --- a/app/assets/images/emoji/star2.png +++ /dev/null diff --git a/app/assets/images/emoji/star_and_crescent.png b/app/assets/images/emoji/star_and_crescent.png Binary files differdeleted file mode 100644 index e182636457d..00000000000 --- a/app/assets/images/emoji/star_and_crescent.png +++ /dev/null diff --git a/app/assets/images/emoji/star_of_david.png b/app/assets/images/emoji/star_of_david.png Binary files differdeleted file mode 100644 index fc59d0dde24..00000000000 --- a/app/assets/images/emoji/star_of_david.png +++ /dev/null diff --git a/app/assets/images/emoji/stars.png b/app/assets/images/emoji/stars.png Binary files differdeleted file mode 100644 index aa45384d1c6..00000000000 --- a/app/assets/images/emoji/stars.png +++ /dev/null diff --git a/app/assets/images/emoji/station.png b/app/assets/images/emoji/station.png Binary files differdeleted file mode 100644 index 5c26fee529c..00000000000 --- a/app/assets/images/emoji/station.png +++ /dev/null diff --git a/app/assets/images/emoji/statue_of_liberty.png b/app/assets/images/emoji/statue_of_liberty.png Binary files differdeleted file mode 100644 index 05df8289b59..00000000000 --- a/app/assets/images/emoji/statue_of_liberty.png +++ /dev/null diff --git a/app/assets/images/emoji/steam_locomotive.png b/app/assets/images/emoji/steam_locomotive.png Binary files differdeleted file mode 100644 index 9ac0d999c4c..00000000000 --- a/app/assets/images/emoji/steam_locomotive.png +++ /dev/null diff --git a/app/assets/images/emoji/stew.png b/app/assets/images/emoji/stew.png Binary files differdeleted file mode 100644 index 6b3f010c17a..00000000000 --- a/app/assets/images/emoji/stew.png +++ /dev/null diff --git a/app/assets/images/emoji/stop_button.png b/app/assets/images/emoji/stop_button.png Binary files differdeleted file mode 100644 index cfa99988ac2..00000000000 --- a/app/assets/images/emoji/stop_button.png +++ /dev/null diff --git a/app/assets/images/emoji/stopwatch.png b/app/assets/images/emoji/stopwatch.png Binary files differdeleted file mode 100644 index 8fae1c9a898..00000000000 --- a/app/assets/images/emoji/stopwatch.png +++ /dev/null diff --git a/app/assets/images/emoji/straight_ruler.png b/app/assets/images/emoji/straight_ruler.png Binary files differdeleted file mode 100644 index 1017b7433a1..00000000000 --- a/app/assets/images/emoji/straight_ruler.png +++ /dev/null diff --git a/app/assets/images/emoji/strawberry.png b/app/assets/images/emoji/strawberry.png Binary files differdeleted file mode 100644 index 7bb86f0b29c..00000000000 --- a/app/assets/images/emoji/strawberry.png +++ /dev/null diff --git a/app/assets/images/emoji/stuck_out_tongue.png b/app/assets/images/emoji/stuck_out_tongue.png Binary files differdeleted file mode 100644 index 25757341f96..00000000000 --- a/app/assets/images/emoji/stuck_out_tongue.png +++ /dev/null diff --git a/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png b/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png Binary files differdeleted file mode 100644 index 5c0401e9b1d..00000000000 --- a/app/assets/images/emoji/stuck_out_tongue_closed_eyes.png +++ /dev/null diff --git a/app/assets/images/emoji/stuck_out_tongue_winking_eye.png b/app/assets/images/emoji/stuck_out_tongue_winking_eye.png Binary files differdeleted file mode 100644 index 4817eaa3dc6..00000000000 --- a/app/assets/images/emoji/stuck_out_tongue_winking_eye.png +++ /dev/null diff --git a/app/assets/images/emoji/stuffed_flatbread.png b/app/assets/images/emoji/stuffed_flatbread.png Binary files differdeleted file mode 100644 index a2e10df40a5..00000000000 --- a/app/assets/images/emoji/stuffed_flatbread.png +++ /dev/null diff --git a/app/assets/images/emoji/sun_with_face.png b/app/assets/images/emoji/sun_with_face.png Binary files differdeleted file mode 100644 index 14a4ea971db..00000000000 --- a/app/assets/images/emoji/sun_with_face.png +++ /dev/null diff --git a/app/assets/images/emoji/sunflower.png b/app/assets/images/emoji/sunflower.png Binary files differdeleted file mode 100644 index 08cc07761ea..00000000000 --- a/app/assets/images/emoji/sunflower.png +++ /dev/null diff --git a/app/assets/images/emoji/sunglasses.png b/app/assets/images/emoji/sunglasses.png Binary files differdeleted file mode 100644 index 20011735110..00000000000 --- a/app/assets/images/emoji/sunglasses.png +++ /dev/null diff --git a/app/assets/images/emoji/sunny.png b/app/assets/images/emoji/sunny.png Binary files differdeleted file mode 100644 index fd521ae31a7..00000000000 --- a/app/assets/images/emoji/sunny.png +++ /dev/null diff --git a/app/assets/images/emoji/sunrise.png b/app/assets/images/emoji/sunrise.png Binary files differdeleted file mode 100644 index 4ad36003c20..00000000000 --- a/app/assets/images/emoji/sunrise.png +++ /dev/null diff --git a/app/assets/images/emoji/sunrise_over_mountains.png b/app/assets/images/emoji/sunrise_over_mountains.png Binary files differdeleted file mode 100644 index 2b99307344d..00000000000 --- a/app/assets/images/emoji/sunrise_over_mountains.png +++ /dev/null diff --git a/app/assets/images/emoji/surfer.png b/app/assets/images/emoji/surfer.png Binary files differdeleted file mode 100644 index 3ab017adf4b..00000000000 --- a/app/assets/images/emoji/surfer.png +++ /dev/null diff --git a/app/assets/images/emoji/surfer_tone1.png b/app/assets/images/emoji/surfer_tone1.png Binary files differdeleted file mode 100644 index b5faaa524cc..00000000000 --- a/app/assets/images/emoji/surfer_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/surfer_tone2.png b/app/assets/images/emoji/surfer_tone2.png Binary files differdeleted file mode 100644 index 6d92e412ff1..00000000000 --- a/app/assets/images/emoji/surfer_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/surfer_tone3.png b/app/assets/images/emoji/surfer_tone3.png Binary files differdeleted file mode 100644 index f05ef59496e..00000000000 --- a/app/assets/images/emoji/surfer_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/surfer_tone4.png b/app/assets/images/emoji/surfer_tone4.png Binary files differdeleted file mode 100644 index 35e143d19dc..00000000000 --- a/app/assets/images/emoji/surfer_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/surfer_tone5.png b/app/assets/images/emoji/surfer_tone5.png Binary files differdeleted file mode 100644 index 38917658eac..00000000000 --- a/app/assets/images/emoji/surfer_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/sushi.png b/app/assets/images/emoji/sushi.png Binary files differdeleted file mode 100644 index f171fd2f7a1..00000000000 --- a/app/assets/images/emoji/sushi.png +++ /dev/null diff --git a/app/assets/images/emoji/suspension_railway.png b/app/assets/images/emoji/suspension_railway.png Binary files differdeleted file mode 100644 index a59d5f48c24..00000000000 --- a/app/assets/images/emoji/suspension_railway.png +++ /dev/null diff --git a/app/assets/images/emoji/sweat.png b/app/assets/images/emoji/sweat.png Binary files differdeleted file mode 100644 index f0dae7b7893..00000000000 --- a/app/assets/images/emoji/sweat.png +++ /dev/null diff --git a/app/assets/images/emoji/sweat_drops.png b/app/assets/images/emoji/sweat_drops.png Binary files differdeleted file mode 100644 index 4106117ebc8..00000000000 --- a/app/assets/images/emoji/sweat_drops.png +++ /dev/null diff --git a/app/assets/images/emoji/sweat_smile.png b/app/assets/images/emoji/sweat_smile.png Binary files differdeleted file mode 100644 index cb18d9c899b..00000000000 --- a/app/assets/images/emoji/sweat_smile.png +++ /dev/null diff --git a/app/assets/images/emoji/sweet_potato.png b/app/assets/images/emoji/sweet_potato.png Binary files differdeleted file mode 100644 index 92a425f2e20..00000000000 --- a/app/assets/images/emoji/sweet_potato.png +++ /dev/null diff --git a/app/assets/images/emoji/swimmer.png b/app/assets/images/emoji/swimmer.png Binary files differdeleted file mode 100644 index 55b4d72f9a7..00000000000 --- a/app/assets/images/emoji/swimmer.png +++ /dev/null diff --git a/app/assets/images/emoji/swimmer_tone1.png b/app/assets/images/emoji/swimmer_tone1.png Binary files differdeleted file mode 100644 index 38441c9ca9a..00000000000 --- a/app/assets/images/emoji/swimmer_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/swimmer_tone2.png b/app/assets/images/emoji/swimmer_tone2.png Binary files differdeleted file mode 100644 index b0d43112444..00000000000 --- a/app/assets/images/emoji/swimmer_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/swimmer_tone3.png b/app/assets/images/emoji/swimmer_tone3.png Binary files differdeleted file mode 100644 index 211e77e2aa0..00000000000 --- a/app/assets/images/emoji/swimmer_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/swimmer_tone4.png b/app/assets/images/emoji/swimmer_tone4.png Binary files differdeleted file mode 100644 index f34c34db9d2..00000000000 --- a/app/assets/images/emoji/swimmer_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/swimmer_tone5.png b/app/assets/images/emoji/swimmer_tone5.png Binary files differdeleted file mode 100644 index 3e9231ff868..00000000000 --- a/app/assets/images/emoji/swimmer_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/symbols.png b/app/assets/images/emoji/symbols.png Binary files differdeleted file mode 100644 index ac2fc1f358f..00000000000 --- a/app/assets/images/emoji/symbols.png +++ /dev/null diff --git a/app/assets/images/emoji/synagogue.png b/app/assets/images/emoji/synagogue.png Binary files differdeleted file mode 100644 index ee347904c80..00000000000 --- a/app/assets/images/emoji/synagogue.png +++ /dev/null diff --git a/app/assets/images/emoji/syringe.png b/app/assets/images/emoji/syringe.png Binary files differdeleted file mode 100644 index 71c1a9528d5..00000000000 --- a/app/assets/images/emoji/syringe.png +++ /dev/null diff --git a/app/assets/images/emoji/taco.png b/app/assets/images/emoji/taco.png Binary files differdeleted file mode 100644 index 10e847a4619..00000000000 --- a/app/assets/images/emoji/taco.png +++ /dev/null diff --git a/app/assets/images/emoji/tada.png b/app/assets/images/emoji/tada.png Binary files differdeleted file mode 100644 index 0244d60f269..00000000000 --- a/app/assets/images/emoji/tada.png +++ /dev/null diff --git a/app/assets/images/emoji/tanabata_tree.png b/app/assets/images/emoji/tanabata_tree.png Binary files differdeleted file mode 100644 index 46fcb3a1aac..00000000000 --- a/app/assets/images/emoji/tanabata_tree.png +++ /dev/null diff --git a/app/assets/images/emoji/tangerine.png b/app/assets/images/emoji/tangerine.png Binary files differdeleted file mode 100644 index ab14e5378db..00000000000 --- a/app/assets/images/emoji/tangerine.png +++ /dev/null diff --git a/app/assets/images/emoji/taurus.png b/app/assets/images/emoji/taurus.png Binary files differdeleted file mode 100644 index b2a370df42b..00000000000 --- a/app/assets/images/emoji/taurus.png +++ /dev/null diff --git a/app/assets/images/emoji/taxi.png b/app/assets/images/emoji/taxi.png Binary files differdeleted file mode 100644 index 55f4cc84797..00000000000 --- a/app/assets/images/emoji/taxi.png +++ /dev/null diff --git a/app/assets/images/emoji/tea.png b/app/assets/images/emoji/tea.png Binary files differdeleted file mode 100644 index b53b98f0c45..00000000000 --- a/app/assets/images/emoji/tea.png +++ /dev/null diff --git a/app/assets/images/emoji/telephone.png b/app/assets/images/emoji/telephone.png Binary files differdeleted file mode 100644 index a1e69f566bc..00000000000 --- a/app/assets/images/emoji/telephone.png +++ /dev/null diff --git a/app/assets/images/emoji/telephone_receiver.png b/app/assets/images/emoji/telephone_receiver.png Binary files differdeleted file mode 100644 index 69388316c35..00000000000 --- a/app/assets/images/emoji/telephone_receiver.png +++ /dev/null diff --git a/app/assets/images/emoji/telescope.png b/app/assets/images/emoji/telescope.png Binary files differdeleted file mode 100644 index d63154614b5..00000000000 --- a/app/assets/images/emoji/telescope.png +++ /dev/null diff --git a/app/assets/images/emoji/ten.png b/app/assets/images/emoji/ten.png Binary files differdeleted file mode 100644 index 782d4004962..00000000000 --- a/app/assets/images/emoji/ten.png +++ /dev/null diff --git a/app/assets/images/emoji/tennis.png b/app/assets/images/emoji/tennis.png Binary files differdeleted file mode 100644 index 7e68ba8f301..00000000000 --- a/app/assets/images/emoji/tennis.png +++ /dev/null diff --git a/app/assets/images/emoji/tent.png b/app/assets/images/emoji/tent.png Binary files differdeleted file mode 100644 index 3fddcfc56eb..00000000000 --- a/app/assets/images/emoji/tent.png +++ /dev/null diff --git a/app/assets/images/emoji/thermometer.png b/app/assets/images/emoji/thermometer.png Binary files differdeleted file mode 100644 index b1147392426..00000000000 --- a/app/assets/images/emoji/thermometer.png +++ /dev/null diff --git a/app/assets/images/emoji/thermometer_face.png b/app/assets/images/emoji/thermometer_face.png Binary files differdeleted file mode 100644 index 8fc57387563..00000000000 --- a/app/assets/images/emoji/thermometer_face.png +++ /dev/null diff --git a/app/assets/images/emoji/thinking.png b/app/assets/images/emoji/thinking.png Binary files differdeleted file mode 100644 index c18f6fd14ad..00000000000 --- a/app/assets/images/emoji/thinking.png +++ /dev/null diff --git a/app/assets/images/emoji/third_place.png b/app/assets/images/emoji/third_place.png Binary files differdeleted file mode 100644 index 636e04a5950..00000000000 --- a/app/assets/images/emoji/third_place.png +++ /dev/null diff --git a/app/assets/images/emoji/thought_balloon.png b/app/assets/images/emoji/thought_balloon.png Binary files differdeleted file mode 100644 index 72fe8fa7022..00000000000 --- a/app/assets/images/emoji/thought_balloon.png +++ /dev/null diff --git a/app/assets/images/emoji/three.png b/app/assets/images/emoji/three.png Binary files differdeleted file mode 100644 index dbaa6183e72..00000000000 --- a/app/assets/images/emoji/three.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsdown.png b/app/assets/images/emoji/thumbsdown.png Binary files differdeleted file mode 100644 index b63da2f20a8..00000000000 --- a/app/assets/images/emoji/thumbsdown.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsdown_tone1.png b/app/assets/images/emoji/thumbsdown_tone1.png Binary files differdeleted file mode 100644 index a1631af8e92..00000000000 --- a/app/assets/images/emoji/thumbsdown_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsdown_tone2.png b/app/assets/images/emoji/thumbsdown_tone2.png Binary files differdeleted file mode 100644 index 85fff82d595..00000000000 --- a/app/assets/images/emoji/thumbsdown_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsdown_tone3.png b/app/assets/images/emoji/thumbsdown_tone3.png Binary files differdeleted file mode 100644 index eeba3be80fd..00000000000 --- a/app/assets/images/emoji/thumbsdown_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsdown_tone4.png b/app/assets/images/emoji/thumbsdown_tone4.png Binary files differdeleted file mode 100644 index 1addafdaed0..00000000000 --- a/app/assets/images/emoji/thumbsdown_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsdown_tone5.png b/app/assets/images/emoji/thumbsdown_tone5.png Binary files differdeleted file mode 100644 index 37ec07b5721..00000000000 --- a/app/assets/images/emoji/thumbsdown_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsup.png b/app/assets/images/emoji/thumbsup.png Binary files differdeleted file mode 100644 index f9e6f13a34f..00000000000 --- a/app/assets/images/emoji/thumbsup.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsup_tone1.png b/app/assets/images/emoji/thumbsup_tone1.png Binary files differdeleted file mode 100644 index 39684cd5cc7..00000000000 --- a/app/assets/images/emoji/thumbsup_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsup_tone2.png b/app/assets/images/emoji/thumbsup_tone2.png Binary files differdeleted file mode 100644 index a9b59723573..00000000000 --- a/app/assets/images/emoji/thumbsup_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsup_tone3.png b/app/assets/images/emoji/thumbsup_tone3.png Binary files differdeleted file mode 100644 index c5e29167015..00000000000 --- a/app/assets/images/emoji/thumbsup_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsup_tone4.png b/app/assets/images/emoji/thumbsup_tone4.png Binary files differdeleted file mode 100644 index 5bf4857a884..00000000000 --- a/app/assets/images/emoji/thumbsup_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/thumbsup_tone5.png b/app/assets/images/emoji/thumbsup_tone5.png Binary files differdeleted file mode 100644 index d829f787c61..00000000000 --- a/app/assets/images/emoji/thumbsup_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/thunder_cloud_rain.png b/app/assets/images/emoji/thunder_cloud_rain.png Binary files differdeleted file mode 100644 index 31a26a1b6ee..00000000000 --- a/app/assets/images/emoji/thunder_cloud_rain.png +++ /dev/null diff --git a/app/assets/images/emoji/ticket.png b/app/assets/images/emoji/ticket.png Binary files differdeleted file mode 100644 index 605936bb6b3..00000000000 --- a/app/assets/images/emoji/ticket.png +++ /dev/null diff --git a/app/assets/images/emoji/tickets.png b/app/assets/images/emoji/tickets.png Binary files differdeleted file mode 100644 index e510f4a7a50..00000000000 --- a/app/assets/images/emoji/tickets.png +++ /dev/null diff --git a/app/assets/images/emoji/tiger.png b/app/assets/images/emoji/tiger.png Binary files differdeleted file mode 100644 index a4d3ef086d4..00000000000 --- a/app/assets/images/emoji/tiger.png +++ /dev/null diff --git a/app/assets/images/emoji/tiger2.png b/app/assets/images/emoji/tiger2.png Binary files differdeleted file mode 100644 index 871a8b74d56..00000000000 --- a/app/assets/images/emoji/tiger2.png +++ /dev/null diff --git a/app/assets/images/emoji/timer.png b/app/assets/images/emoji/timer.png Binary files differdeleted file mode 100644 index 8a3be574c24..00000000000 --- a/app/assets/images/emoji/timer.png +++ /dev/null diff --git a/app/assets/images/emoji/tired_face.png b/app/assets/images/emoji/tired_face.png Binary files differdeleted file mode 100644 index 4e01eff5b23..00000000000 --- a/app/assets/images/emoji/tired_face.png +++ /dev/null diff --git a/app/assets/images/emoji/tm.png b/app/assets/images/emoji/tm.png Binary files differdeleted file mode 100644 index 7a0c44a2c2b..00000000000 --- a/app/assets/images/emoji/tm.png +++ /dev/null diff --git a/app/assets/images/emoji/toilet.png b/app/assets/images/emoji/toilet.png Binary files differdeleted file mode 100644 index 1392f761835..00000000000 --- a/app/assets/images/emoji/toilet.png +++ /dev/null diff --git a/app/assets/images/emoji/tokyo_tower.png b/app/assets/images/emoji/tokyo_tower.png Binary files differdeleted file mode 100644 index 37df7fc65b1..00000000000 --- a/app/assets/images/emoji/tokyo_tower.png +++ /dev/null diff --git a/app/assets/images/emoji/tomato.png b/app/assets/images/emoji/tomato.png Binary files differdeleted file mode 100644 index 497da8f6b22..00000000000 --- a/app/assets/images/emoji/tomato.png +++ /dev/null diff --git a/app/assets/images/emoji/tone1.png b/app/assets/images/emoji/tone1.png Binary files differdeleted file mode 100644 index c395f3d0d68..00000000000 --- a/app/assets/images/emoji/tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/tone2.png b/app/assets/images/emoji/tone2.png Binary files differdeleted file mode 100644 index 080847431c1..00000000000 --- a/app/assets/images/emoji/tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/tone3.png b/app/assets/images/emoji/tone3.png Binary files differdeleted file mode 100644 index 482dd403475..00000000000 --- a/app/assets/images/emoji/tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/tone4.png b/app/assets/images/emoji/tone4.png Binary files differdeleted file mode 100644 index 5cae8bb20b0..00000000000 --- a/app/assets/images/emoji/tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/tone5.png b/app/assets/images/emoji/tone5.png Binary files differdeleted file mode 100644 index 49d1a8c3a64..00000000000 --- a/app/assets/images/emoji/tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/tongue.png b/app/assets/images/emoji/tongue.png Binary files differdeleted file mode 100644 index 70ce9c1225f..00000000000 --- a/app/assets/images/emoji/tongue.png +++ /dev/null diff --git a/app/assets/images/emoji/tools.png b/app/assets/images/emoji/tools.png Binary files differdeleted file mode 100644 index 3c6049273a9..00000000000 --- a/app/assets/images/emoji/tools.png +++ /dev/null diff --git a/app/assets/images/emoji/top.png b/app/assets/images/emoji/top.png Binary files differdeleted file mode 100644 index 49dea8c08b5..00000000000 --- a/app/assets/images/emoji/top.png +++ /dev/null diff --git a/app/assets/images/emoji/tophat.png b/app/assets/images/emoji/tophat.png Binary files differdeleted file mode 100644 index 131b657b109..00000000000 --- a/app/assets/images/emoji/tophat.png +++ /dev/null diff --git a/app/assets/images/emoji/track_next.png b/app/assets/images/emoji/track_next.png Binary files differdeleted file mode 100644 index f8880d33bab..00000000000 --- a/app/assets/images/emoji/track_next.png +++ /dev/null diff --git a/app/assets/images/emoji/track_previous.png b/app/assets/images/emoji/track_previous.png Binary files differdeleted file mode 100644 index 1ffd0566cfc..00000000000 --- a/app/assets/images/emoji/track_previous.png +++ /dev/null diff --git a/app/assets/images/emoji/trackball.png b/app/assets/images/emoji/trackball.png Binary files differdeleted file mode 100644 index 3bea84ad7ce..00000000000 --- a/app/assets/images/emoji/trackball.png +++ /dev/null diff --git a/app/assets/images/emoji/tractor.png b/app/assets/images/emoji/tractor.png Binary files differdeleted file mode 100644 index c1bf8cae44f..00000000000 --- a/app/assets/images/emoji/tractor.png +++ /dev/null diff --git a/app/assets/images/emoji/traffic_light.png b/app/assets/images/emoji/traffic_light.png Binary files differdeleted file mode 100644 index 6b312285b00..00000000000 --- a/app/assets/images/emoji/traffic_light.png +++ /dev/null diff --git a/app/assets/images/emoji/train.png b/app/assets/images/emoji/train.png Binary files differdeleted file mode 100644 index 3c80321f7e8..00000000000 --- a/app/assets/images/emoji/train.png +++ /dev/null diff --git a/app/assets/images/emoji/train2.png b/app/assets/images/emoji/train2.png Binary files differdeleted file mode 100644 index 367c7bc5d39..00000000000 --- a/app/assets/images/emoji/train2.png +++ /dev/null diff --git a/app/assets/images/emoji/tram.png b/app/assets/images/emoji/tram.png Binary files differdeleted file mode 100644 index b6f0e69038f..00000000000 --- a/app/assets/images/emoji/tram.png +++ /dev/null diff --git a/app/assets/images/emoji/triangular_flag_on_post.png b/app/assets/images/emoji/triangular_flag_on_post.png Binary files differdeleted file mode 100644 index c12d8b06886..00000000000 --- a/app/assets/images/emoji/triangular_flag_on_post.png +++ /dev/null diff --git a/app/assets/images/emoji/triangular_ruler.png b/app/assets/images/emoji/triangular_ruler.png Binary files differdeleted file mode 100644 index 77dee9ee843..00000000000 --- a/app/assets/images/emoji/triangular_ruler.png +++ /dev/null diff --git a/app/assets/images/emoji/trident.png b/app/assets/images/emoji/trident.png Binary files differdeleted file mode 100644 index 777a1dad121..00000000000 --- a/app/assets/images/emoji/trident.png +++ /dev/null diff --git a/app/assets/images/emoji/triumph.png b/app/assets/images/emoji/triumph.png Binary files differdeleted file mode 100644 index 0be7a501969..00000000000 --- a/app/assets/images/emoji/triumph.png +++ /dev/null diff --git a/app/assets/images/emoji/trolleybus.png b/app/assets/images/emoji/trolleybus.png Binary files differdeleted file mode 100644 index 139a9931b52..00000000000 --- a/app/assets/images/emoji/trolleybus.png +++ /dev/null diff --git a/app/assets/images/emoji/trophy.png b/app/assets/images/emoji/trophy.png Binary files differdeleted file mode 100644 index ac2895c1896..00000000000 --- a/app/assets/images/emoji/trophy.png +++ /dev/null diff --git a/app/assets/images/emoji/tropical_drink.png b/app/assets/images/emoji/tropical_drink.png Binary files differdeleted file mode 100644 index cd714f81b36..00000000000 --- a/app/assets/images/emoji/tropical_drink.png +++ /dev/null diff --git a/app/assets/images/emoji/tropical_fish.png b/app/assets/images/emoji/tropical_fish.png Binary files differdeleted file mode 100644 index 252105235a6..00000000000 --- a/app/assets/images/emoji/tropical_fish.png +++ /dev/null diff --git a/app/assets/images/emoji/truck.png b/app/assets/images/emoji/truck.png Binary files differdeleted file mode 100644 index 130de047f8b..00000000000 --- a/app/assets/images/emoji/truck.png +++ /dev/null diff --git a/app/assets/images/emoji/trumpet.png b/app/assets/images/emoji/trumpet.png Binary files differdeleted file mode 100644 index 864ccbcd04a..00000000000 --- a/app/assets/images/emoji/trumpet.png +++ /dev/null diff --git a/app/assets/images/emoji/tulip.png b/app/assets/images/emoji/tulip.png Binary files differdeleted file mode 100644 index f799d75c182..00000000000 --- a/app/assets/images/emoji/tulip.png +++ /dev/null diff --git a/app/assets/images/emoji/tumbler_glass.png b/app/assets/images/emoji/tumbler_glass.png Binary files differdeleted file mode 100644 index 7bf09229879..00000000000 --- a/app/assets/images/emoji/tumbler_glass.png +++ /dev/null diff --git a/app/assets/images/emoji/turkey.png b/app/assets/images/emoji/turkey.png Binary files differdeleted file mode 100644 index 344af94c9ec..00000000000 --- a/app/assets/images/emoji/turkey.png +++ /dev/null diff --git a/app/assets/images/emoji/turtle.png b/app/assets/images/emoji/turtle.png Binary files differdeleted file mode 100644 index c22f7519fe8..00000000000 --- a/app/assets/images/emoji/turtle.png +++ /dev/null diff --git a/app/assets/images/emoji/tv.png b/app/assets/images/emoji/tv.png Binary files differdeleted file mode 100644 index 999f1fb5c6d..00000000000 --- a/app/assets/images/emoji/tv.png +++ /dev/null diff --git a/app/assets/images/emoji/twisted_rightwards_arrows.png b/app/assets/images/emoji/twisted_rightwards_arrows.png Binary files differdeleted file mode 100644 index 5904badde65..00000000000 --- a/app/assets/images/emoji/twisted_rightwards_arrows.png +++ /dev/null diff --git a/app/assets/images/emoji/two.png b/app/assets/images/emoji/two.png Binary files differdeleted file mode 100644 index 927339c9bff..00000000000 --- a/app/assets/images/emoji/two.png +++ /dev/null diff --git a/app/assets/images/emoji/two_hearts.png b/app/assets/images/emoji/two_hearts.png Binary files differdeleted file mode 100644 index 4d8c3386042..00000000000 --- a/app/assets/images/emoji/two_hearts.png +++ /dev/null diff --git a/app/assets/images/emoji/two_men_holding_hands.png b/app/assets/images/emoji/two_men_holding_hands.png Binary files differdeleted file mode 100644 index a511fda822a..00000000000 --- a/app/assets/images/emoji/two_men_holding_hands.png +++ /dev/null diff --git a/app/assets/images/emoji/two_women_holding_hands.png b/app/assets/images/emoji/two_women_holding_hands.png Binary files differdeleted file mode 100644 index b077cd3e40f..00000000000 --- a/app/assets/images/emoji/two_women_holding_hands.png +++ /dev/null diff --git a/app/assets/images/emoji/u5272.png b/app/assets/images/emoji/u5272.png Binary files differdeleted file mode 100644 index c4f837fe684..00000000000 --- a/app/assets/images/emoji/u5272.png +++ /dev/null diff --git a/app/assets/images/emoji/u5408.png b/app/assets/images/emoji/u5408.png Binary files differdeleted file mode 100644 index 8375ad9d9af..00000000000 --- a/app/assets/images/emoji/u5408.png +++ /dev/null diff --git a/app/assets/images/emoji/u55b6.png b/app/assets/images/emoji/u55b6.png Binary files differdeleted file mode 100644 index d21cb30eaf3..00000000000 --- a/app/assets/images/emoji/u55b6.png +++ /dev/null diff --git a/app/assets/images/emoji/u6307.png b/app/assets/images/emoji/u6307.png Binary files differdeleted file mode 100644 index 078e23e4ff3..00000000000 --- a/app/assets/images/emoji/u6307.png +++ /dev/null diff --git a/app/assets/images/emoji/u6708.png b/app/assets/images/emoji/u6708.png Binary files differdeleted file mode 100644 index c41bd36a26a..00000000000 --- a/app/assets/images/emoji/u6708.png +++ /dev/null diff --git a/app/assets/images/emoji/u6709.png b/app/assets/images/emoji/u6709.png Binary files differdeleted file mode 100644 index a4510de41c0..00000000000 --- a/app/assets/images/emoji/u6709.png +++ /dev/null diff --git a/app/assets/images/emoji/u6e80.png b/app/assets/images/emoji/u6e80.png Binary files differdeleted file mode 100644 index f9dea8b8833..00000000000 --- a/app/assets/images/emoji/u6e80.png +++ /dev/null diff --git a/app/assets/images/emoji/u7121.png b/app/assets/images/emoji/u7121.png Binary files differdeleted file mode 100644 index d3a19b420de..00000000000 --- a/app/assets/images/emoji/u7121.png +++ /dev/null diff --git a/app/assets/images/emoji/u7533.png b/app/assets/images/emoji/u7533.png Binary files differdeleted file mode 100644 index 6b7af0ee222..00000000000 --- a/app/assets/images/emoji/u7533.png +++ /dev/null diff --git a/app/assets/images/emoji/u7981.png b/app/assets/images/emoji/u7981.png Binary files differdeleted file mode 100644 index 4c704e03433..00000000000 --- a/app/assets/images/emoji/u7981.png +++ /dev/null diff --git a/app/assets/images/emoji/u7a7a.png b/app/assets/images/emoji/u7a7a.png Binary files differdeleted file mode 100644 index 47966c1ea93..00000000000 --- a/app/assets/images/emoji/u7a7a.png +++ /dev/null diff --git a/app/assets/images/emoji/umbrella.png b/app/assets/images/emoji/umbrella.png Binary files differdeleted file mode 100644 index 5b35b7ff6a4..00000000000 --- a/app/assets/images/emoji/umbrella.png +++ /dev/null diff --git a/app/assets/images/emoji/umbrella2.png b/app/assets/images/emoji/umbrella2.png Binary files differdeleted file mode 100644 index 97fe859e74f..00000000000 --- a/app/assets/images/emoji/umbrella2.png +++ /dev/null diff --git a/app/assets/images/emoji/unamused.png b/app/assets/images/emoji/unamused.png Binary files differdeleted file mode 100644 index 25e3677f2eb..00000000000 --- a/app/assets/images/emoji/unamused.png +++ /dev/null diff --git a/app/assets/images/emoji/underage.png b/app/assets/images/emoji/underage.png Binary files differdeleted file mode 100644 index 6dfe6da51e2..00000000000 --- a/app/assets/images/emoji/underage.png +++ /dev/null diff --git a/app/assets/images/emoji/unicorn.png b/app/assets/images/emoji/unicorn.png Binary files differdeleted file mode 100644 index 05a97969f7e..00000000000 --- a/app/assets/images/emoji/unicorn.png +++ /dev/null diff --git a/app/assets/images/emoji/unlock.png b/app/assets/images/emoji/unlock.png Binary files differdeleted file mode 100644 index 4a74a693911..00000000000 --- a/app/assets/images/emoji/unlock.png +++ /dev/null diff --git a/app/assets/images/emoji/up.png b/app/assets/images/emoji/up.png Binary files differdeleted file mode 100644 index 0d42142ba04..00000000000 --- a/app/assets/images/emoji/up.png +++ /dev/null diff --git a/app/assets/images/emoji/upside_down.png b/app/assets/images/emoji/upside_down.png Binary files differdeleted file mode 100644 index 128f31c9828..00000000000 --- a/app/assets/images/emoji/upside_down.png +++ /dev/null diff --git a/app/assets/images/emoji/urn.png b/app/assets/images/emoji/urn.png Binary files differdeleted file mode 100644 index 6b5b3503438..00000000000 --- a/app/assets/images/emoji/urn.png +++ /dev/null diff --git a/app/assets/images/emoji/v.png b/app/assets/images/emoji/v.png Binary files differdeleted file mode 100644 index 70c5516ffee..00000000000 --- a/app/assets/images/emoji/v.png +++ /dev/null diff --git a/app/assets/images/emoji/v_tone1.png b/app/assets/images/emoji/v_tone1.png Binary files differdeleted file mode 100644 index 6ac54a745f4..00000000000 --- a/app/assets/images/emoji/v_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/v_tone2.png b/app/assets/images/emoji/v_tone2.png Binary files differdeleted file mode 100644 index 6dd9669866d..00000000000 --- a/app/assets/images/emoji/v_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/v_tone3.png b/app/assets/images/emoji/v_tone3.png Binary files differdeleted file mode 100644 index a615e53f02f..00000000000 --- a/app/assets/images/emoji/v_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/v_tone4.png b/app/assets/images/emoji/v_tone4.png Binary files differdeleted file mode 100644 index 33a34bd5a78..00000000000 --- a/app/assets/images/emoji/v_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/v_tone5.png b/app/assets/images/emoji/v_tone5.png Binary files differdeleted file mode 100644 index 45ad14b6c9c..00000000000 --- a/app/assets/images/emoji/v_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/vertical_traffic_light.png b/app/assets/images/emoji/vertical_traffic_light.png Binary files differdeleted file mode 100644 index 8085973eecf..00000000000 --- a/app/assets/images/emoji/vertical_traffic_light.png +++ /dev/null diff --git a/app/assets/images/emoji/vhs.png b/app/assets/images/emoji/vhs.png Binary files differdeleted file mode 100644 index b9eb78ecd92..00000000000 --- a/app/assets/images/emoji/vhs.png +++ /dev/null diff --git a/app/assets/images/emoji/vibration_mode.png b/app/assets/images/emoji/vibration_mode.png Binary files differdeleted file mode 100644 index cc46510e48e..00000000000 --- a/app/assets/images/emoji/vibration_mode.png +++ /dev/null diff --git a/app/assets/images/emoji/video_camera.png b/app/assets/images/emoji/video_camera.png Binary files differdeleted file mode 100644 index 85b300d425c..00000000000 --- a/app/assets/images/emoji/video_camera.png +++ /dev/null diff --git a/app/assets/images/emoji/video_game.png b/app/assets/images/emoji/video_game.png Binary files differdeleted file mode 100644 index 316a9106a55..00000000000 --- a/app/assets/images/emoji/video_game.png +++ /dev/null diff --git a/app/assets/images/emoji/violin.png b/app/assets/images/emoji/violin.png Binary files differdeleted file mode 100644 index e1e76cce242..00000000000 --- a/app/assets/images/emoji/violin.png +++ /dev/null diff --git a/app/assets/images/emoji/virgo.png b/app/assets/images/emoji/virgo.png Binary files differdeleted file mode 100644 index a6b56c2cb5e..00000000000 --- a/app/assets/images/emoji/virgo.png +++ /dev/null diff --git a/app/assets/images/emoji/volcano.png b/app/assets/images/emoji/volcano.png Binary files differdeleted file mode 100644 index 931d569294c..00000000000 --- a/app/assets/images/emoji/volcano.png +++ /dev/null diff --git a/app/assets/images/emoji/volleyball.png b/app/assets/images/emoji/volleyball.png Binary files differdeleted file mode 100644 index 7a0e49d4b07..00000000000 --- a/app/assets/images/emoji/volleyball.png +++ /dev/null diff --git a/app/assets/images/emoji/vs.png b/app/assets/images/emoji/vs.png Binary files differdeleted file mode 100644 index e1180f4a464..00000000000 --- a/app/assets/images/emoji/vs.png +++ /dev/null diff --git a/app/assets/images/emoji/vulcan.png b/app/assets/images/emoji/vulcan.png Binary files differdeleted file mode 100644 index 54728bcaf5c..00000000000 --- a/app/assets/images/emoji/vulcan.png +++ /dev/null diff --git a/app/assets/images/emoji/vulcan_tone1.png b/app/assets/images/emoji/vulcan_tone1.png Binary files differdeleted file mode 100644 index 8aff5d8fa16..00000000000 --- a/app/assets/images/emoji/vulcan_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/vulcan_tone2.png b/app/assets/images/emoji/vulcan_tone2.png Binary files differdeleted file mode 100644 index 82b7ad519b4..00000000000 --- a/app/assets/images/emoji/vulcan_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/vulcan_tone3.png b/app/assets/images/emoji/vulcan_tone3.png Binary files differdeleted file mode 100644 index d1400e1dd28..00000000000 --- a/app/assets/images/emoji/vulcan_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/vulcan_tone4.png b/app/assets/images/emoji/vulcan_tone4.png Binary files differdeleted file mode 100644 index 47e2b280148..00000000000 --- a/app/assets/images/emoji/vulcan_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/vulcan_tone5.png b/app/assets/images/emoji/vulcan_tone5.png Binary files differdeleted file mode 100644 index 60b5c6077be..00000000000 --- a/app/assets/images/emoji/vulcan_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/walking.png b/app/assets/images/emoji/walking.png Binary files differdeleted file mode 100644 index 06dc169a3fd..00000000000 --- a/app/assets/images/emoji/walking.png +++ /dev/null diff --git a/app/assets/images/emoji/walking_tone1.png b/app/assets/images/emoji/walking_tone1.png Binary files differdeleted file mode 100644 index 4e391b45a0b..00000000000 --- a/app/assets/images/emoji/walking_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/walking_tone2.png b/app/assets/images/emoji/walking_tone2.png Binary files differdeleted file mode 100644 index 31f94a1bce1..00000000000 --- a/app/assets/images/emoji/walking_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/walking_tone3.png b/app/assets/images/emoji/walking_tone3.png Binary files differdeleted file mode 100644 index f7ed8e39c2e..00000000000 --- a/app/assets/images/emoji/walking_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/walking_tone4.png b/app/assets/images/emoji/walking_tone4.png Binary files differdeleted file mode 100644 index e58dc04c7b2..00000000000 --- a/app/assets/images/emoji/walking_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/walking_tone5.png b/app/assets/images/emoji/walking_tone5.png Binary files differdeleted file mode 100644 index ba4e1b58fcb..00000000000 --- a/app/assets/images/emoji/walking_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/waning_crescent_moon.png b/app/assets/images/emoji/waning_crescent_moon.png Binary files differdeleted file mode 100644 index cf68706b871..00000000000 --- a/app/assets/images/emoji/waning_crescent_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/waning_gibbous_moon.png b/app/assets/images/emoji/waning_gibbous_moon.png Binary files differdeleted file mode 100644 index 24e16266119..00000000000 --- a/app/assets/images/emoji/waning_gibbous_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/warning.png b/app/assets/images/emoji/warning.png Binary files differdeleted file mode 100644 index 35691c2ed97..00000000000 --- a/app/assets/images/emoji/warning.png +++ /dev/null diff --git a/app/assets/images/emoji/wastebasket.png b/app/assets/images/emoji/wastebasket.png Binary files differdeleted file mode 100644 index 2b3c484b498..00000000000 --- a/app/assets/images/emoji/wastebasket.png +++ /dev/null diff --git a/app/assets/images/emoji/watch.png b/app/assets/images/emoji/watch.png Binary files differdeleted file mode 100644 index 64819bc6e21..00000000000 --- a/app/assets/images/emoji/watch.png +++ /dev/null diff --git a/app/assets/images/emoji/water_buffalo.png b/app/assets/images/emoji/water_buffalo.png Binary files differdeleted file mode 100644 index 80446615caf..00000000000 --- a/app/assets/images/emoji/water_buffalo.png +++ /dev/null diff --git a/app/assets/images/emoji/water_polo.png b/app/assets/images/emoji/water_polo.png Binary files differdeleted file mode 100644 index cb44576780d..00000000000 --- a/app/assets/images/emoji/water_polo.png +++ /dev/null diff --git a/app/assets/images/emoji/water_polo_tone1.png b/app/assets/images/emoji/water_polo_tone1.png Binary files differdeleted file mode 100644 index bed1a908d6a..00000000000 --- a/app/assets/images/emoji/water_polo_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/water_polo_tone2.png b/app/assets/images/emoji/water_polo_tone2.png Binary files differdeleted file mode 100644 index ec5a43b4d4a..00000000000 --- a/app/assets/images/emoji/water_polo_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/water_polo_tone3.png b/app/assets/images/emoji/water_polo_tone3.png Binary files differdeleted file mode 100644 index b081a4a5a96..00000000000 --- a/app/assets/images/emoji/water_polo_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/water_polo_tone4.png b/app/assets/images/emoji/water_polo_tone4.png Binary files differdeleted file mode 100644 index 82cfbc3b0c7..00000000000 --- a/app/assets/images/emoji/water_polo_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/water_polo_tone5.png b/app/assets/images/emoji/water_polo_tone5.png Binary files differdeleted file mode 100644 index bd3366eb06c..00000000000 --- a/app/assets/images/emoji/water_polo_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/watermelon.png b/app/assets/images/emoji/watermelon.png Binary files differdeleted file mode 100644 index 0761488b4c9..00000000000 --- a/app/assets/images/emoji/watermelon.png +++ /dev/null diff --git a/app/assets/images/emoji/wave.png b/app/assets/images/emoji/wave.png Binary files differdeleted file mode 100644 index e0cd79b45f5..00000000000 --- a/app/assets/images/emoji/wave.png +++ /dev/null diff --git a/app/assets/images/emoji/wave_tone1.png b/app/assets/images/emoji/wave_tone1.png Binary files differdeleted file mode 100644 index 6b2b34b106e..00000000000 --- a/app/assets/images/emoji/wave_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/wave_tone2.png b/app/assets/images/emoji/wave_tone2.png Binary files differdeleted file mode 100644 index b857119732e..00000000000 --- a/app/assets/images/emoji/wave_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/wave_tone3.png b/app/assets/images/emoji/wave_tone3.png Binary files differdeleted file mode 100644 index 6283b670f43..00000000000 --- a/app/assets/images/emoji/wave_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/wave_tone4.png b/app/assets/images/emoji/wave_tone4.png Binary files differdeleted file mode 100644 index fe6b2baa747..00000000000 --- a/app/assets/images/emoji/wave_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/wave_tone5.png b/app/assets/images/emoji/wave_tone5.png Binary files differdeleted file mode 100644 index 4bd168ebb78..00000000000 --- a/app/assets/images/emoji/wave_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/wavy_dash.png b/app/assets/images/emoji/wavy_dash.png Binary files differdeleted file mode 100644 index 001c8d6e47d..00000000000 --- a/app/assets/images/emoji/wavy_dash.png +++ /dev/null diff --git a/app/assets/images/emoji/waxing_crescent_moon.png b/app/assets/images/emoji/waxing_crescent_moon.png Binary files differdeleted file mode 100644 index 687125173d9..00000000000 --- a/app/assets/images/emoji/waxing_crescent_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/waxing_gibbous_moon.png b/app/assets/images/emoji/waxing_gibbous_moon.png Binary files differdeleted file mode 100644 index 3a808156318..00000000000 --- a/app/assets/images/emoji/waxing_gibbous_moon.png +++ /dev/null diff --git a/app/assets/images/emoji/wc.png b/app/assets/images/emoji/wc.png Binary files differdeleted file mode 100644 index aa433e84ba6..00000000000 --- a/app/assets/images/emoji/wc.png +++ /dev/null diff --git a/app/assets/images/emoji/weary.png b/app/assets/images/emoji/weary.png Binary files differdeleted file mode 100644 index 98bfbd24a16..00000000000 --- a/app/assets/images/emoji/weary.png +++ /dev/null diff --git a/app/assets/images/emoji/wedding.png b/app/assets/images/emoji/wedding.png Binary files differdeleted file mode 100644 index d0d8aa0bfae..00000000000 --- a/app/assets/images/emoji/wedding.png +++ /dev/null diff --git a/app/assets/images/emoji/whale.png b/app/assets/images/emoji/whale.png Binary files differdeleted file mode 100644 index 9f19b44257c..00000000000 --- a/app/assets/images/emoji/whale.png +++ /dev/null diff --git a/app/assets/images/emoji/whale2.png b/app/assets/images/emoji/whale2.png Binary files differdeleted file mode 100644 index 0df9d3c73a4..00000000000 --- a/app/assets/images/emoji/whale2.png +++ /dev/null diff --git a/app/assets/images/emoji/wheel_of_dharma.png b/app/assets/images/emoji/wheel_of_dharma.png Binary files differdeleted file mode 100644 index 3666db0016b..00000000000 --- a/app/assets/images/emoji/wheel_of_dharma.png +++ /dev/null diff --git a/app/assets/images/emoji/wheelchair.png b/app/assets/images/emoji/wheelchair.png Binary files differdeleted file mode 100644 index 4e5b2698eac..00000000000 --- a/app/assets/images/emoji/wheelchair.png +++ /dev/null diff --git a/app/assets/images/emoji/white_check_mark.png b/app/assets/images/emoji/white_check_mark.png Binary files differdeleted file mode 100644 index e55f087e544..00000000000 --- a/app/assets/images/emoji/white_check_mark.png +++ /dev/null diff --git a/app/assets/images/emoji/white_circle.png b/app/assets/images/emoji/white_circle.png Binary files differdeleted file mode 100644 index c19e15684dd..00000000000 --- a/app/assets/images/emoji/white_circle.png +++ /dev/null diff --git a/app/assets/images/emoji/white_flower.png b/app/assets/images/emoji/white_flower.png Binary files differdeleted file mode 100644 index d6af8b60077..00000000000 --- a/app/assets/images/emoji/white_flower.png +++ /dev/null diff --git a/app/assets/images/emoji/white_large_square.png b/app/assets/images/emoji/white_large_square.png Binary files differdeleted file mode 100644 index 6f06c1c79de..00000000000 --- a/app/assets/images/emoji/white_large_square.png +++ /dev/null diff --git a/app/assets/images/emoji/white_medium_small_square.png b/app/assets/images/emoji/white_medium_small_square.png Binary files differdeleted file mode 100644 index ae874126750..00000000000 --- a/app/assets/images/emoji/white_medium_small_square.png +++ /dev/null diff --git a/app/assets/images/emoji/white_medium_square.png b/app/assets/images/emoji/white_medium_square.png Binary files differdeleted file mode 100644 index 8daacf57059..00000000000 --- a/app/assets/images/emoji/white_medium_square.png +++ /dev/null diff --git a/app/assets/images/emoji/white_small_square.png b/app/assets/images/emoji/white_small_square.png Binary files differdeleted file mode 100644 index d7ebdb0c0ed..00000000000 --- a/app/assets/images/emoji/white_small_square.png +++ /dev/null diff --git a/app/assets/images/emoji/white_square_button.png b/app/assets/images/emoji/white_square_button.png Binary files differdeleted file mode 100644 index 934b1cedfd2..00000000000 --- a/app/assets/images/emoji/white_square_button.png +++ /dev/null diff --git a/app/assets/images/emoji/white_sun_cloud.png b/app/assets/images/emoji/white_sun_cloud.png Binary files differdeleted file mode 100644 index 0a4cc100269..00000000000 --- a/app/assets/images/emoji/white_sun_cloud.png +++ /dev/null diff --git a/app/assets/images/emoji/white_sun_rain_cloud.png b/app/assets/images/emoji/white_sun_rain_cloud.png Binary files differdeleted file mode 100644 index 491f9ca4839..00000000000 --- a/app/assets/images/emoji/white_sun_rain_cloud.png +++ /dev/null diff --git a/app/assets/images/emoji/white_sun_small_cloud.png b/app/assets/images/emoji/white_sun_small_cloud.png Binary files differdeleted file mode 100644 index cead0bfa521..00000000000 --- a/app/assets/images/emoji/white_sun_small_cloud.png +++ /dev/null diff --git a/app/assets/images/emoji/wilted_rose.png b/app/assets/images/emoji/wilted_rose.png Binary files differdeleted file mode 100644 index 62412b143ae..00000000000 --- a/app/assets/images/emoji/wilted_rose.png +++ /dev/null diff --git a/app/assets/images/emoji/wind_blowing_face.png b/app/assets/images/emoji/wind_blowing_face.png Binary files differdeleted file mode 100644 index df81b652eb6..00000000000 --- a/app/assets/images/emoji/wind_blowing_face.png +++ /dev/null diff --git a/app/assets/images/emoji/wind_chime.png b/app/assets/images/emoji/wind_chime.png Binary files differdeleted file mode 100644 index 3c9ef3a95f6..00000000000 --- a/app/assets/images/emoji/wind_chime.png +++ /dev/null diff --git a/app/assets/images/emoji/wine_glass.png b/app/assets/images/emoji/wine_glass.png Binary files differdeleted file mode 100644 index 3cc98689192..00000000000 --- a/app/assets/images/emoji/wine_glass.png +++ /dev/null diff --git a/app/assets/images/emoji/wink.png b/app/assets/images/emoji/wink.png Binary files differdeleted file mode 100644 index 7ea7810a37d..00000000000 --- a/app/assets/images/emoji/wink.png +++ /dev/null diff --git a/app/assets/images/emoji/wolf.png b/app/assets/images/emoji/wolf.png Binary files differdeleted file mode 100644 index ba7220f2de9..00000000000 --- a/app/assets/images/emoji/wolf.png +++ /dev/null diff --git a/app/assets/images/emoji/woman.png b/app/assets/images/emoji/woman.png Binary files differdeleted file mode 100644 index ece440e7a61..00000000000 --- a/app/assets/images/emoji/woman.png +++ /dev/null diff --git a/app/assets/images/emoji/woman_tone1.png b/app/assets/images/emoji/woman_tone1.png Binary files differdeleted file mode 100644 index ff089b8889b..00000000000 --- a/app/assets/images/emoji/woman_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/woman_tone2.png b/app/assets/images/emoji/woman_tone2.png Binary files differdeleted file mode 100644 index 0719c378016..00000000000 --- a/app/assets/images/emoji/woman_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/woman_tone3.png b/app/assets/images/emoji/woman_tone3.png Binary files differdeleted file mode 100644 index 5672e2fd52d..00000000000 --- a/app/assets/images/emoji/woman_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/woman_tone4.png b/app/assets/images/emoji/woman_tone4.png Binary files differdeleted file mode 100644 index 5754aab558b..00000000000 --- a/app/assets/images/emoji/woman_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/woman_tone5.png b/app/assets/images/emoji/woman_tone5.png Binary files differdeleted file mode 100644 index fc252af3a39..00000000000 --- a/app/assets/images/emoji/woman_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/womans_clothes.png b/app/assets/images/emoji/womans_clothes.png Binary files differdeleted file mode 100644 index 01410dc8107..00000000000 --- a/app/assets/images/emoji/womans_clothes.png +++ /dev/null diff --git a/app/assets/images/emoji/womans_hat.png b/app/assets/images/emoji/womans_hat.png Binary files differdeleted file mode 100644 index b837b6a2e47..00000000000 --- a/app/assets/images/emoji/womans_hat.png +++ /dev/null diff --git a/app/assets/images/emoji/womens.png b/app/assets/images/emoji/womens.png Binary files differdeleted file mode 100644 index d4ecc22e7b3..00000000000 --- a/app/assets/images/emoji/womens.png +++ /dev/null diff --git a/app/assets/images/emoji/worried.png b/app/assets/images/emoji/worried.png Binary files differdeleted file mode 100644 index 7074afcf5b7..00000000000 --- a/app/assets/images/emoji/worried.png +++ /dev/null diff --git a/app/assets/images/emoji/wrench.png b/app/assets/images/emoji/wrench.png Binary files differdeleted file mode 100644 index c16b7439697..00000000000 --- a/app/assets/images/emoji/wrench.png +++ /dev/null diff --git a/app/assets/images/emoji/wrestlers.png b/app/assets/images/emoji/wrestlers.png Binary files differdeleted file mode 100644 index 71e67cfad85..00000000000 --- a/app/assets/images/emoji/wrestlers.png +++ /dev/null diff --git a/app/assets/images/emoji/wrestlers_tone1.png b/app/assets/images/emoji/wrestlers_tone1.png Binary files differdeleted file mode 100644 index 379070fd03b..00000000000 --- a/app/assets/images/emoji/wrestlers_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/wrestlers_tone2.png b/app/assets/images/emoji/wrestlers_tone2.png Binary files differdeleted file mode 100644 index 6863ea9209d..00000000000 --- a/app/assets/images/emoji/wrestlers_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/wrestlers_tone3.png b/app/assets/images/emoji/wrestlers_tone3.png Binary files differdeleted file mode 100644 index b7e62910127..00000000000 --- a/app/assets/images/emoji/wrestlers_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/wrestlers_tone4.png b/app/assets/images/emoji/wrestlers_tone4.png Binary files differdeleted file mode 100644 index 750f9589233..00000000000 --- a/app/assets/images/emoji/wrestlers_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/wrestlers_tone5.png b/app/assets/images/emoji/wrestlers_tone5.png Binary files differdeleted file mode 100644 index 36ab9bb3f42..00000000000 --- a/app/assets/images/emoji/wrestlers_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/writing_hand.png b/app/assets/images/emoji/writing_hand.png Binary files differdeleted file mode 100644 index 85639f8ac40..00000000000 --- a/app/assets/images/emoji/writing_hand.png +++ /dev/null diff --git a/app/assets/images/emoji/writing_hand_tone1.png b/app/assets/images/emoji/writing_hand_tone1.png Binary files differdeleted file mode 100644 index 7923d8ebb17..00000000000 --- a/app/assets/images/emoji/writing_hand_tone1.png +++ /dev/null diff --git a/app/assets/images/emoji/writing_hand_tone2.png b/app/assets/images/emoji/writing_hand_tone2.png Binary files differdeleted file mode 100644 index bcb304e15d2..00000000000 --- a/app/assets/images/emoji/writing_hand_tone2.png +++ /dev/null diff --git a/app/assets/images/emoji/writing_hand_tone3.png b/app/assets/images/emoji/writing_hand_tone3.png Binary files differdeleted file mode 100644 index fd885fd2d90..00000000000 --- a/app/assets/images/emoji/writing_hand_tone3.png +++ /dev/null diff --git a/app/assets/images/emoji/writing_hand_tone4.png b/app/assets/images/emoji/writing_hand_tone4.png Binary files differdeleted file mode 100644 index d065b8c64ab..00000000000 --- a/app/assets/images/emoji/writing_hand_tone4.png +++ /dev/null diff --git a/app/assets/images/emoji/writing_hand_tone5.png b/app/assets/images/emoji/writing_hand_tone5.png Binary files differdeleted file mode 100644 index a44b3dd757c..00000000000 --- a/app/assets/images/emoji/writing_hand_tone5.png +++ /dev/null diff --git a/app/assets/images/emoji/x.png b/app/assets/images/emoji/x.png Binary files differdeleted file mode 100644 index 9f9ed0f7ad2..00000000000 --- a/app/assets/images/emoji/x.png +++ /dev/null diff --git a/app/assets/images/emoji/yellow_heart.png b/app/assets/images/emoji/yellow_heart.png Binary files differdeleted file mode 100644 index 7901a9d0103..00000000000 --- a/app/assets/images/emoji/yellow_heart.png +++ /dev/null diff --git a/app/assets/images/emoji/yen.png b/app/assets/images/emoji/yen.png Binary files differdeleted file mode 100644 index 63ee4799d66..00000000000 --- a/app/assets/images/emoji/yen.png +++ /dev/null diff --git a/app/assets/images/emoji/yin_yang.png b/app/assets/images/emoji/yin_yang.png Binary files differdeleted file mode 100644 index f2900f6338f..00000000000 --- a/app/assets/images/emoji/yin_yang.png +++ /dev/null diff --git a/app/assets/images/emoji/yum.png b/app/assets/images/emoji/yum.png Binary files differdeleted file mode 100644 index 2df15753ca1..00000000000 --- a/app/assets/images/emoji/yum.png +++ /dev/null diff --git a/app/assets/images/emoji/zap.png b/app/assets/images/emoji/zap.png Binary files differdeleted file mode 100644 index 47e68e48e49..00000000000 --- a/app/assets/images/emoji/zap.png +++ /dev/null diff --git a/app/assets/images/emoji/zero.png b/app/assets/images/emoji/zero.png Binary files differdeleted file mode 100644 index 13aca83e018..00000000000 --- a/app/assets/images/emoji/zero.png +++ /dev/null diff --git a/app/assets/images/emoji/zipper_mouth.png b/app/assets/images/emoji/zipper_mouth.png Binary files differdeleted file mode 100644 index f8ced2502a7..00000000000 --- a/app/assets/images/emoji/zipper_mouth.png +++ /dev/null diff --git a/app/assets/images/emoji/zzz.png b/app/assets/images/emoji/zzz.png Binary files differdeleted file mode 100644 index 9bc72b4469f..00000000000 --- a/app/assets/images/emoji/zzz.png +++ /dev/null diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 85eb08cc97d..8754c253881 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -12,6 +12,7 @@ const Api = { projectsPath: '/api/:version/projects.json', projectPath: '/api/:version/projects/:id', projectLabelsPath: '/:namespace_path/:project_path/labels', + projectMergeRequestsPath: '/api/:version/projects/:id/merge_requests', projectMergeRequestPath: '/api/:version/projects/:id/merge_requests/:mrid', projectMergeRequestChangesPath: '/api/:version/projects/:id/merge_requests/:mrid/changes', projectMergeRequestVersionsPath: '/api/:version/projects/:id/merge_requests/:mrid/versions', @@ -111,6 +112,22 @@ const Api = { return axios.get(url); }, + /** + * Get all Merge Requests for a project, eventually filtering based on + * supplied parameters + * @param projectPath + * @param params + * @returns {Promise} + */ + projectMergeRequests(projectPath, params = {}) { + const url = Api.buildUrl(Api.projectMergeRequestsPath).replace( + ':id', + encodeURIComponent(projectPath), + ); + + return axios.get(url, { params }); + }, + // Return Merge Request for project projectMergeRequest(projectPath, mergeRequestId, params = {}) { const url = Api.buildUrl(Api.projectMergeRequestPath) diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js index 73ce3e760ab..aeb88715c11 100644 --- a/app/assets/javascripts/awards_handler.js +++ b/app/assets/javascripts/awards_handler.js @@ -615,10 +615,18 @@ export class AwardsHandler { let awardsHandlerPromise = null; export default function loadAwardsHandler(reload = false) { if (!awardsHandlerPromise || reload) { - awardsHandlerPromise = import(/* webpackChunkName: 'emoji' */ './emoji').then(Emoji => { - const awardsHandler = new AwardsHandler(Emoji); - awardsHandler.bindEvents(); - return awardsHandler; + awardsHandlerPromise = new Promise((resolve, reject) => { + import(/* webpackChunkName: 'emoji' */ './emoji') + .then(Emoji => { + Emoji.initEmojiMap() + .then(() => { + const awardsHandler = new AwardsHandler(Emoji); + awardsHandler.bindEvents(); + resolve(awardsHandler); + }) + .catch(() => reject); + }) + .catch(() => reject); }); } return awardsHandlerPromise; diff --git a/app/assets/javascripts/behaviors/gl_emoji.js b/app/assets/javascripts/behaviors/gl_emoji.js index d1d75658181..9034563d9b3 100644 --- a/app/assets/javascripts/behaviors/gl_emoji.js +++ b/app/assets/javascripts/behaviors/gl_emoji.js @@ -1,47 +1,74 @@ import 'document-register-element'; import isEmojiUnicodeSupported from '../emoji/support'; +import { initEmojiMap, getEmojiInfo, emojiFallbackImageSrc, emojiImageTag } from '../emoji'; class GlEmoji extends HTMLElement { constructor() { super(); - 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 (emojiUnicode && isEmojiUnicode && !isEmojiUnicodeSupported(emojiUnicode, unicodeVersion)) { - // CSS sprite fallback takes precedence over image fallback - if (hasCssSpriteFalback) { - if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) { - const emojiSpriteLinkTag = document.createElement('link'); - emojiSpriteLinkTag.setAttribute('rel', 'stylesheet'); - emojiSpriteLinkTag.setAttribute('href', gon.emoji_sprites_css_path); - document.head.appendChild(emojiSpriteLinkTag); - gon.emoji_sprites_css_added = true; - } - // IE 11 doesn't like adding multiple at once :( - this.classList.add('emoji-icon'); - this.classList.add(fallbackSpriteClass); - } else { - import(/* webpackChunkName: 'emoji' */ '../emoji') - .then(({ emojiImageTag, emojiFallbackImageSrc }) => { - if (hasImageFallback) { - this.innerHTML = emojiImageTag(name, fallbackSrc); + let emojiUnicode = this.textContent.trim(); + const { fallbackSpriteClass, fallbackSrc, forceFallback } = this.dataset; + let { name, unicodeVersion } = this.dataset; + + initEmojiMap() + .then(() => { + if (!unicodeVersion) { + const emojiInfo = getEmojiInfo(name); + + if (emojiInfo) { + if (name !== emojiInfo.name) { + ({ name } = emojiInfo); + this.dataset.name = emojiInfo.name; + } + unicodeVersion = emojiInfo.u; + this.dataset.uni = unicodeVersion; + + if (forceFallback === 'true' && !fallbackSpriteClass) { + this.innerHTML = emojiImageTag(name, emojiFallbackImageSrc(name)); } else { - const src = emojiFallbackImageSrc(name); - this.innerHTML = emojiImageTag(name, src); + emojiUnicode = emojiInfo.e; + this.innerHTML = emojiInfo.e; } - }) - .catch(() => { - // do nothing - }); - } - } + + this.title = emojiInfo.d; + } + } + + 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 ( + emojiUnicode && + isEmojiUnicode && + !isEmojiUnicodeSupported(emojiUnicode, unicodeVersion) + ) { + // CSS sprite fallback takes precedence over image fallback + if (hasCssSpriteFalback) { + if (!gon.emoji_sprites_css_added && gon.emoji_sprites_css_path) { + const emojiSpriteLinkTag = document.createElement('link'); + emojiSpriteLinkTag.setAttribute('rel', 'stylesheet'); + emojiSpriteLinkTag.setAttribute('href', gon.emoji_sprites_css_path); + document.head.appendChild(emojiSpriteLinkTag); + gon.emoji_sprites_css_added = true; + } + // 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 = emojiFallbackImageSrc(name); + this.innerHTML = emojiImageTag(name, src); + } + } + }) + .catch(error => { + // Only reject is already handled in initEmojiMap + throw error; + }); } } diff --git a/app/assets/javascripts/behaviors/markdown/copy_as_gfm.js b/app/assets/javascripts/behaviors/markdown/copy_as_gfm.js index 9482a9f166d..58cf057b2c2 100644 --- a/app/assets/javascripts/behaviors/markdown/copy_as_gfm.js +++ b/app/assets/javascripts/behaviors/markdown/copy_as_gfm.js @@ -173,7 +173,9 @@ export class CopyAsGFM { wrapEl.appendChild(node.cloneNode(true)); const doc = DOMParser.fromSchema(schema.default).parse(wrapEl); - const res = markdownSerializer.default.serialize(doc); + const res = markdownSerializer.default.serialize(doc, { + tightLists: true, + }); return res; }) .catch(() => {}); diff --git a/app/assets/javascripts/behaviors/markdown/render_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_mermaid.js index 35380ca49fb..798114b4b0b 100644 --- a/app/assets/javascripts/behaviors/markdown/render_mermaid.js +++ b/app/assets/javascripts/behaviors/markdown/render_mermaid.js @@ -1,4 +1,5 @@ import flash from '~/flash'; +import { sprintf, __ } from '../../locale'; // Renders diagrams and flowcharts from text using Mermaid in any element with the // `js-render-mermaid` class. @@ -14,6 +15,9 @@ import flash from '~/flash'; // </pre> // +// This is an arbitary number; Can be iterated upon when suitable. +const MAX_CHAR_LIMIT = 5000; + export default function renderMermaid($els) { if (!$els.length) return; @@ -34,6 +38,21 @@ export default function renderMermaid($els) { $els.each((i, el) => { const source = el.textContent; + /** + * Restrict the rendering to a certain amount of character to + * prevent mermaidjs from hanging up the entire thread and + * causing a DoS. + */ + if (source && source.length > MAX_CHAR_LIMIT) { + el.textContent = sprintf( + __( + 'Cannot render the image. Maximum character count (%{charLimit}) has been exceeded.', + ), + { charLimit: MAX_CHAR_LIMIT }, + ); + return; + } + // Remove any extra spans added by the backend syntax highlighting. Object.assign(el, { textContent: source }); diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js index 5f64175362d..6aaf5bf7296 100644 --- a/app/assets/javascripts/blob_edit/blob_bundle.js +++ b/app/assets/javascripts/blob_edit/blob_bundle.js @@ -13,7 +13,7 @@ export default () => { if (editBlobForm.length) { const urlRoot = editBlobForm.data('relativeUrlRoot'); const assetsPath = editBlobForm.data('assetsPrefix'); - const filePath = editBlobForm.data('blobFilename'); + const filePath = `${editBlobForm.data('blobFilename')}`; const currentAction = $('.js-file-title').data('currentAction'); const projectId = editBlobForm.data('project-id'); const isMarkdown = editBlobForm.data('is-markdown'); diff --git a/app/assets/javascripts/boards/components/issue_due_date.vue b/app/assets/javascripts/boards/components/issue_due_date.vue index 9c4c6632976..9bc66978198 100644 --- a/app/assets/javascripts/boards/components/issue_due_date.vue +++ b/app/assets/javascripts/boards/components/issue_due_date.vue @@ -53,7 +53,7 @@ export default { } else if (timeDifference === -1) { return __('Yesterday'); } else if (timeDifference > 0 && timeDifference < 7) { - return dateFormat(issueDueDate, 'dddd', true); + return dateFormat(issueDueDate, 'dddd'); } return standardDateFormat; diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index f88e9b55988..c4c5fedc615 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -58,6 +58,7 @@ export default () => { state: boardsStore.state, loading: true, boardsEndpoint: $boardApp.dataset.boardsEndpoint, + recentBoardsEndpoint: $boardApp.dataset.recentBoardsEndpoint, listsEndpoint: $boardApp.dataset.listsEndpoint, boardId: $boardApp.dataset.boardId, disabled: parseBoolean($boardApp.dataset.disabled), @@ -75,6 +76,7 @@ export default () => { created() { gl.boardService = new BoardService({ boardsEndpoint: this.boardsEndpoint, + recentBoardsEndpoint: this.recentBoardsEndpoint, listsEndpoint: this.listsEndpoint, bulkUpdatePath: this.bulkUpdatePath, boardId: this.boardId, diff --git a/app/assets/javascripts/boards/services/board_service.js b/app/assets/javascripts/boards/services/board_service.js index 3de6eb056c2..7d463f17ab1 100644 --- a/app/assets/javascripts/boards/services/board_service.js +++ b/app/assets/javascripts/boards/services/board_service.js @@ -2,12 +2,13 @@ import axios from '../../lib/utils/axios_utils'; import { mergeUrlParams } from '../../lib/utils/url_utility'; export default class BoardService { - constructor({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId }) { + constructor({ boardsEndpoint, listsEndpoint, bulkUpdatePath, boardId, recentBoardsEndpoint }) { this.boardsEndpoint = boardsEndpoint; this.boardId = boardId; this.listsEndpoint = listsEndpoint; this.listsEndpointGenerate = `${listsEndpoint}/generate.json`; this.bulkUpdatePath = bulkUpdatePath; + this.recentBoardsEndpoint = `${recentBoardsEndpoint}.json`; } generateBoardsPath(id) { diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js index 6ebd1ad109e..388f674f643 100644 --- a/app/assets/javascripts/clusters/clusters_bundle.js +++ b/app/assets/javascripts/clusters/clusters_bundle.js @@ -36,6 +36,7 @@ export default class Clusters { installRunnerPath, installJupyterPath, installKnativePath, + updateKnativePath, installPrometheusPath, managePrometheusPath, hasRbac, @@ -62,6 +63,7 @@ export default class Clusters { installPrometheusEndpoint: installPrometheusPath, installJupyterEndpoint: installJupyterPath, installKnativeEndpoint: installKnativePath, + updateKnativeEndpoint: updateKnativePath, }); this.installApplication = this.installApplication.bind(this); @@ -119,8 +121,7 @@ export default class Clusters { static initDismissableCallout() { const callout = document.querySelector('.js-cluster-security-warning'); - - if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new + PersistentUserCallout.factory(callout); } addListeners() { @@ -129,6 +130,8 @@ export default class Clusters { eventHub.$on('upgradeApplication', data => this.upgradeApplication(data)); eventHub.$on('upgradeFailed', appId => this.upgradeFailed(appId)); eventHub.$on('dismissUpgradeSuccess', appId => this.dismissUpgradeSuccess(appId)); + eventHub.$on('saveKnativeDomain', data => this.saveKnativeDomain(data)); + eventHub.$on('setKnativeHostname', data => this.setKnativeHostname(data)); } removeListeners() { @@ -137,6 +140,8 @@ export default class Clusters { eventHub.$off('upgradeApplication', this.upgradeApplication); eventHub.$off('upgradeFailed', this.upgradeFailed); eventHub.$off('dismissUpgradeSuccess', this.dismissUpgradeSuccess); + eventHub.$off('saveKnativeDomain'); + eventHub.$off('setKnativeHostname'); } initPolling() { @@ -272,6 +277,18 @@ export default class Clusters { this.store.updateAppProperty(appId, 'requestStatus', null); } + saveKnativeDomain(data) { + const appId = data.id; + this.store.updateAppProperty(appId, 'status', APPLICATION_STATUS.UPDATING); + this.service.updateApplication(appId, data.params); + } + + setKnativeHostname(data) { + const appId = data.id; + this.store.updateAppProperty(appId, 'isEditingHostName', true); + this.store.updateAppProperty(appId, 'hostname', data.hostname); + } + destroy() { this.destroyed = true; diff --git a/app/assets/javascripts/clusters/components/application_row.vue b/app/assets/javascripts/clusters/components/application_row.vue index 5952e93b9a7..19e5ac1567d 100644 --- a/app/assets/javascripts/clusters/components/application_row.vue +++ b/app/assets/javascripts/clusters/components/application_row.vue @@ -191,14 +191,7 @@ export default { return this.status === APPLICATION_STATUS.UPDATE_ERRORED; }, upgradeFailureDescription() { - return sprintf( - s__( - 'ClusterIntegration|Something went wrong when upgrading %{title}. Please check the logs and try again.', - ), - { - title: this.title, - }, - ); + return s__('ClusterIntegration|Update failed. Please check the logs and try again.'); }, upgradeSuccessDescription() { return sprintf(s__('ClusterIntegration|%{title} upgraded successfully.'), { @@ -210,9 +203,9 @@ export default { if (this.upgradeAvailable && !this.upgradeFailed && !this.isUpgrading) { label = s__('ClusterIntegration|Upgrade'); } else if (this.isUpgrading) { - label = s__('ClusterIntegration|Upgrading'); + label = s__('ClusterIntegration|Updating'); } else if (this.upgradeFailed) { - label = s__('ClusterIntegration|Retry upgrade'); + label = s__('ClusterIntegration|Retry update'); } return label; @@ -224,6 +217,14 @@ export default { (this.upgradeRequested && !this.upgradeSuccessful) ); }, + shouldShowUpgradeDetails() { + // This method only returns true when; + // Upgrade was successful OR Upgrade failed + // AND new upgrade is unavailable AND version information is present. + return ( + (this.upgradeSuccessful || this.upgradeFailed) && !this.upgradeAvailable && this.version + ); + }, }, watch: { status() { @@ -303,7 +304,7 @@ export default { </div> <div - v-if="(upgradeSuccessful || upgradeFailed) && !upgradeAvailable" + v-if="shouldShowUpgradeDetails" class="form-text text-muted label p-0 js-cluster-application-upgrade-details" > {{ versionLabel }} diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index 0cf187d4189..f74cd71de04 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -15,11 +15,14 @@ import { s__, sprintf } from '../../locale'; import applicationRow from './application_row.vue'; import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import { CLUSTER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants'; +import LoadingButton from '~/vue_shared/components/loading_button.vue'; +import eventHub from '~/clusters/event_hub'; export default { components: { applicationRow, clipboardButton, + LoadingButton, }, props: { type: { @@ -173,16 +176,55 @@ export default { jupyterHostname() { return this.applications.jupyter.hostname; }, + knative() { + return this.applications.knative; + }, knativeInstalled() { - return this.applications.knative.status === APPLICATION_STATUS.INSTALLED; + return ( + this.knative.status === APPLICATION_STATUS.INSTALLED || + this.knativeUpgrading || + this.knativeUpgradeFailed || + this.knative.status === APPLICATION_STATUS.UPDATED + ); + }, + knativeUpgrading() { + return ( + this.knative.status === APPLICATION_STATUS.UPDATING || + this.knative.status === APPLICATION_STATUS.SCHEDULED + ); + }, + knativeUpgradeFailed() { + return this.knative.status === APPLICATION_STATUS.UPDATE_ERRORED; }, knativeExternalIp() { - return this.applications.knative.externalIp; + return this.knative.externalIp; + }, + canUpdateKnativeEndpoint() { + return this.knativeExternalIp && !this.knativeUpgradeFailed && !this.knativeUpgrading; + }, + knativeHostname: { + get() { + return this.knative.hostname; + }, + set(hostname) { + eventHub.$emit('setKnativeHostname', { + id: 'knative', + hostname, + }); + }, }, }, created() { this.helmInstallIllustration = helmInstallIllustration; }, + methods: { + saveKnativeDomain() { + eventHub.$emit('saveKnativeDomain', { + id: 'knative', + params: { hostname: this.knative.hostname }, + }); + }, + }, }; </script> @@ -471,76 +513,88 @@ export default { }} </p> - <template v-if="knativeInstalled"> - <div class="form-group"> - <label for="knative-domainname"> - {{ s__('ClusterIntegration|Knative Domain Name:') }} - </label> - <input - id="knative-domainname" - v-model="applications.knative.hostname" - type="text" - class="form-control js-domainname" - readonly - /> - </div> - </template> - <template v-else-if="helmInstalled && rbac"> - <div class="form-group"> - <label for="knative-domainname"> - {{ s__('ClusterIntegration|Knative Domain Name:') }} - </label> - <input - id="knative-domainname" - v-model="applications.knative.hostname" - type="text" - class="form-control js-domainname" - /> - </div> - </template> - <template v-if="knativeInstalled"> - <div class="form-group"> - <label for="knative-ip-address"> - {{ s__('ClusterIntegration|Knative IP Address:') }} - </label> - <div v-if="knativeExternalIp" class="input-group"> + <div class="row"> + <template v-if="knativeInstalled || (helmInstalled && rbac)"> + <div + :class="{ 'col-md-6': knativeInstalled, 'col-12': helmInstalled && rbac }" + class="form-group col-sm-12 mb-0" + > + <label for="knative-domainname"> + <strong> + {{ s__('ClusterIntegration|Knative Domain Name:') }} + </strong> + </label> <input - id="knative-ip-address" - :value="knativeExternalIp" + id="knative-domainname" + v-model="knativeHostname" type="text" - class="form-control js-ip-address" - readonly + class="form-control js-knative-domainname" /> - <span class="input-group-append"> - <clipboard-button - :text="knativeExternalIp" - :title="s__('ClusterIntegration|Copy Knative IP Address to clipboard')" - class="input-group-text js-clipboard-btn" + </div> + </template> + <template v-if="knativeInstalled"> + <div class="form-group col-sm-12 col-md-6 pl-md-0 mb-0 mt-3 mt-md-0"> + <label for="knative-ip-address"> + <strong> + {{ s__('ClusterIntegration|Knative Endpoint:') }} + </strong> + </label> + <div v-if="knativeExternalIp" class="input-group"> + <input + id="knative-ip-address" + :value="knativeExternalIp" + type="text" + class="form-control js-knative-ip-address" + readonly /> - </span> + <span class="input-group-append"> + <clipboard-button + :text="knativeExternalIp" + :title="s__('ClusterIntegration|Copy Knative Endpoint to clipboard')" + class="input-group-text js-knative-ip-clipboard-btn" + /> + </span> + </div> + <input + v-else + type="text" + class="form-control js-knative-ip-address" + readonly + value="?" + /> </div> - <input v-else type="text" class="form-control js-ip-address" readonly value="?" /> - </div> - <p v-if="!knativeExternalIp" class="settings-message js-no-ip-message"> - {{ - s__(`ClusterIntegration|The IP address is in - the process of being assigned. Please check your Kubernetes - cluster or Quotas on Google Kubernetes Engine if it takes a long time.`) - }} - </p> + <p class="form-text text-muted col-12"> + {{ + s__( + `ClusterIntegration|To access your application after deployment, point a wildcard DNS to the Knative Endpoint.`, + ) + }} + <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer"> + {{ __('More information') }} + </a> + </p> - <p> - {{ - s__(`ClusterIntegration|Point a wildcard DNS to this - generated IP address in order to access - your application after it has been deployed.`) - }} - <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer"> - {{ __('More information') }} - </a> - </p> - </template> + <p + v-if="!knativeExternalIp" + class="settings-message js-no-knative-ip-message mt-2 mr-3 mb-0 ml-3 " + > + {{ + s__(`ClusterIntegration|The IP address is in + the process of being assigned. Please check your Kubernetes + cluster or Quotas on Google Kubernetes Engine if it takes a long time.`) + }} + </p> + + <button + v-if="canUpdateKnativeEndpoint" + class="btn btn-success js-knative-save-domain-button mt-3 ml-3" + @click="saveKnativeDomain" + > + {{ s__('ClusterIntegration|Save changes') }} + </button> + </template> + </div> </div> </application-row> </div> diff --git a/app/assets/javascripts/clusters/services/clusters_service.js b/app/assets/javascripts/clusters/services/clusters_service.js index 89dda4b7902..dea33ac44c5 100644 --- a/app/assets/javascripts/clusters/services/clusters_service.js +++ b/app/assets/javascripts/clusters/services/clusters_service.js @@ -12,6 +12,9 @@ export default class ClusterService { jupyter: this.options.installJupyterEndpoint, knative: this.options.installKnativeEndpoint, }; + this.appUpdateEndpointMap = { + knative: this.options.updateKnativeEndpoint, + }; } fetchData() { @@ -22,6 +25,10 @@ export default class ClusterService { return axios.post(this.appInstallEndpointMap[appId], params); } + updateApplication(appId, params) { + return axios.patch(this.appUpdateEndpointMap[appId], params); + } + static updateCluster(endpoint, data) { return axios.put(endpoint, data); } diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js index d309678be27..3f03a8512fc 100644 --- a/app/assets/javascripts/clusters/stores/clusters_store.js +++ b/app/assets/javascripts/clusters/stores/clusters_store.js @@ -66,6 +66,7 @@ export default class ClusterStore { requestStatus: null, requestReason: null, hostname: null, + isEditingHostName: false, externalIp: null, }, }, @@ -129,8 +130,10 @@ export default class ClusterStore { ? `jupyter.${this.state.applications.ingress.externalIp}.nip.io` : ''); } else if (appId === KNATIVE) { - this.state.applications.knative.hostname = - serverAppEntry.hostname || this.state.applications.knative.hostname; + if (!this.state.applications.knative.isEditingHostName) { + this.state.applications.knative.hostname = + serverAppEntry.hostname || this.state.applications.knative.hostname; + } this.state.applications.knative.externalIp = serverAppEntry.external_ip || this.state.applications.knative.externalIp; } else if (appId === RUNNER) { diff --git a/app/assets/javascripts/contextual_sidebar.js b/app/assets/javascripts/contextual_sidebar.js index 50efecb3475..67fcdd082a2 100644 --- a/app/assets/javascripts/contextual_sidebar.js +++ b/app/assets/javascripts/contextual_sidebar.js @@ -4,6 +4,10 @@ import _ from 'underscore'; import bp from './breakpoints'; import { parseBoolean } from '~/lib/utils/common_utils'; +// NOTE: at 1200px nav sidebar should not overlap the content +// https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/24555#note_134136110 +const NAV_SIDEBAR_BREAKPOINT = 1200; + export default class ContextualSidebar { constructor() { this.initDomElements(); @@ -26,44 +30,54 @@ export default class ContextualSidebar { bindEvents() { if (!this.$sidebar.length) return; - document.addEventListener('click', e => { - if ( - !e.target.closest('.nav-sidebar') && - (bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md') - ) { - this.toggleCollapsedSidebar(true, true); - } - }); this.$openSidebar.on('click', () => this.toggleSidebarNav(true)); this.$closeSidebar.on('click', () => this.toggleSidebarNav(false)); this.$overlay.on('click', () => this.toggleSidebarNav(false)); this.$sidebarToggle.on('click', () => { - const value = !this.$sidebar.hasClass('sidebar-collapsed-desktop'); - this.toggleCollapsedSidebar(value, true); + if (!ContextualSidebar.isDesktopBreakpoint()) { + this.toggleSidebarNav(!this.$sidebar.hasClass('sidebar-expanded-mobile')); + } else { + const value = !this.$sidebar.hasClass('sidebar-collapsed-desktop'); + this.toggleCollapsedSidebar(value, true); + } }); $(window).on('resize', () => _.debounce(this.render(), 100)); } + // TODO: use the breakpoints from breakpoints.js once they have been updated for bootstrap 4 + // See documentation: https://design.gitlab.com/regions/navigation#contextual-navigation + static isDesktopBreakpoint = () => bp.windowWidth() >= NAV_SIDEBAR_BREAKPOINT; static setCollapsedCookie(value) { - if (bp.getBreakpointSize() !== 'lg') { + if (!ContextualSidebar.isDesktopBreakpoint()) { return; } Cookies.set('sidebar_collapsed', value, { expires: 365 * 10 }); } toggleSidebarNav(show) { - this.$sidebar.toggleClass('sidebar-expanded-mobile', show); - this.$overlay.toggleClass('mobile-nav-open', show); + const breakpoint = bp.getBreakpointSize(); + const dbp = ContextualSidebar.isDesktopBreakpoint(); + + this.$sidebar.toggleClass('sidebar-expanded-mobile', !dbp ? show : false); + this.$overlay.toggleClass( + 'mobile-nav-open', + breakpoint === 'xs' || breakpoint === 'sm' ? show : false, + ); this.$sidebar.removeClass('sidebar-collapsed-desktop'); } toggleCollapsedSidebar(collapsed, saveCookie) { const breakpoint = bp.getBreakpointSize(); + const dbp = ContextualSidebar.isDesktopBreakpoint(); if (this.$sidebar.length) { this.$sidebar.toggleClass('sidebar-collapsed-desktop', collapsed); - this.$page.toggleClass('page-with-icon-sidebar', breakpoint === 'sm' ? true : collapsed); + this.$sidebar.toggleClass('sidebar-expanded-mobile', !dbp ? !collapsed : false); + this.$page.toggleClass( + 'page-with-icon-sidebar', + breakpoint === 'xs' || breakpoint === 'sm' ? true : collapsed, + ); } if (saveCookie) { @@ -84,13 +98,11 @@ export default class ContextualSidebar { render() { if (!this.$sidebar.length) return; - const breakpoint = bp.getBreakpointSize(); - - if (breakpoint === 'sm' || breakpoint === 'md') { - this.toggleCollapsedSidebar(true, false); - } else if (breakpoint === 'lg') { + if (!ContextualSidebar.isDesktopBreakpoint()) { + this.toggleSidebarNav(false); + } else { const collapse = parseBoolean(Cookies.get('sidebar_collapsed')); - this.toggleCollapsedSidebar(collapse, false); + this.toggleCollapsedSidebar(collapse, true); } } } diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue index 2b801898345..a5125c3d077 100644 --- a/app/assets/javascripts/diffs/components/diff_file_header.vue +++ b/app/assets/javascripts/diffs/components/diff_file_header.vue @@ -5,7 +5,7 @@ import { polyfillSticky } from '~/lib/utils/sticky'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import Icon from '~/vue_shared/components/icon.vue'; import FileIcon from '~/vue_shared/components/file_icon.vue'; -import { GlTooltipDirective } from '@gitlab/ui'; +import { GlButton, GlTooltipDirective, GlTooltip, GlLoadingIcon } from '@gitlab/ui'; import { truncateSha } from '~/lib/utils/text_utility'; import { __, s__, sprintf } from '~/locale'; import { diffViewerModes } from '~/ide/constants'; @@ -14,6 +14,9 @@ import DiffStats from './diff_stats.vue'; export default { components: { + GlTooltip, + GlLoadingIcon, + GlButton, ClipboardButton, EditButton, Icon, @@ -125,12 +128,15 @@ export default { isModeChanged() { return this.diffFile.viewer.name === diffViewerModes.mode_changed; }, + showExpandDiffToFullFileEnabled() { + return gon.features.expandDiffFullFile && !this.diffFile.is_fully_expanded; + }, }, mounted() { polyfillSticky(this.$refs.header); }, methods: { - ...mapActions('diffs', ['toggleFileDiscussions']), + ...mapActions('diffs', ['toggleFileDiscussions', 'toggleFullDiff']), handleToggleFile(e, checkTarget) { if ( !checkTarget || @@ -236,12 +242,34 @@ export default { <a v-if="diffFile.replaced_view_path" :href="diffFile.replaced_view_path" - class="btn view-file js-view-file" + class="btn view-file js-view-replaced-file" v-html="viewReplacedFileButtonText" > </a> - <a :href="diffFile.view_path" class="btn view-file js-view-file" v-html="viewFileButtonText"> - </a> + <gl-tooltip :target="() => $refs.viewButton" placement="bottom"> + <span v-html="viewFileButtonText"></span> + </gl-tooltip> + <gl-button + ref="viewButton" + :href="diffFile.view_path" + target="blank" + class="view-file js-view-file-button" + > + <icon name="external-link" /> + </gl-button> + <gl-button + v-if="showExpandDiffToFullFileEnabled" + class="expand-file js-expand-file" + @click="toggleFullDiff(diffFile.file_path)" + > + <template v-if="diffFile.isShowingFullFile"> + {{ s__('MRDiff|Show changes only') }} + </template> + <template v-else> + {{ s__('MRDiff|Show full file') }} + </template> + <gl-loading-icon v-if="diffFile.isLoadingFullFile" inline /> + </gl-button> <a v-if="diffFile.external_url" @@ -250,7 +278,7 @@ export default { :title="`View on ${diffFile.formatted_external_url}`" target="_blank" rel="noopener noreferrer" - class="btn btn-file-option" + class="btn btn-file-option js-external-url" > <icon name="external-link" /> </a> diff --git a/app/assets/javascripts/diffs/components/diff_line_note_form.vue b/app/assets/javascripts/diffs/components/diff_line_note_form.vue index 18edbe286ba..bb66ab36283 100644 --- a/app/assets/javascripts/diffs/components/diff_line_note_form.vue +++ b/app/assets/javascripts/diffs/components/diff_line_note_form.vue @@ -1,6 +1,7 @@ <script> import { mapState, mapGetters, mapActions } from 'vuex'; import { s__ } from '~/locale'; +import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form'; import noteForm from '../../notes/components/note_form.vue'; import autosave from '../../notes/mixins/autosave'; import { DIFF_NOTE_TYPE } from '../constants'; @@ -9,7 +10,7 @@ export default { components: { noteForm, }, - mixins: [autosave], + mixins: [autosave, diffLineNoteFormMixin], props: { diffFileHash: { type: String, @@ -103,6 +104,7 @@ export default { :help-page-path="helpPagePath" save-button-title="Comment" class="diff-comment-form" + @handleFormUpdateAddToReview="addToReview" @cancelForm="handleCancelCommentForm" @handleFormUpdate="handleSaveNote" /> diff --git a/app/assets/javascripts/diffs/components/edit_button.vue b/app/assets/javascripts/diffs/components/edit_button.vue index 5d38d545ce8..f0cc5de4b33 100644 --- a/app/assets/javascripts/diffs/components/edit_button.vue +++ b/app/assets/javascripts/diffs/components/edit_button.vue @@ -1,5 +1,15 @@ <script> +import { GlTooltipDirective, GlButton } from '@gitlab/ui'; +import Icon from '~/vue_shared/components/icon.vue'; + export default { + components: { + GlButton, + Icon, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, props: { editPath: { type: String, @@ -17,12 +27,7 @@ export default { }, methods: { handleEditClick(evt) { - if (!this.canCurrentUserFork || this.canModifyBlob) { - // if we can Edit, do default Edit button behavior - return; - } - - if (this.canCurrentUserFork) { + if (this.canCurrentUserFork && !this.canModifyBlob) { evt.preventDefault(); this.$emit('showForkMessage'); } @@ -32,5 +37,13 @@ export default { </script> <template> - <a :href="editPath" class="btn btn-default js-edit-blob" @click="handleEditClick"> Edit </a> + <gl-button + v-gl-tooltip.bottom + :href="editPath" + :title="__('Edit file')" + class="js-edit-blob" + @click.native="handleEditClick" + > + <icon name="pencil" /> + </gl-button> </template> diff --git a/app/assets/javascripts/diffs/components/inline_diff_view.vue b/app/assets/javascripts/diffs/components/inline_diff_view.vue index e781397214d..8c76a555b62 100644 --- a/app/assets/javascripts/diffs/components/inline_diff_view.vue +++ b/app/assets/javascripts/diffs/components/inline_diff_view.vue @@ -1,5 +1,6 @@ <script> import { mapGetters } from 'vuex'; +import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments'; import inlineDiffTableRow from './inline_diff_table_row.vue'; import inlineDiffCommentRow from './inline_diff_comment_row.vue'; @@ -7,7 +8,10 @@ export default { components: { inlineDiffCommentRow, inlineDiffTableRow, + InlineDraftCommentRow: () => + import('ee_component/batch_comments/components/inline_draft_comment_row.vue'), }, + mixins: [draftCommentsMixin], props: { diffFile: { type: Object, @@ -54,6 +58,11 @@ export default { :line="line" :help-page-path="helpPagePath" /> + <inline-draft-comment-row + v-if="shouldRenderDraftRow(diffFile.file_hash, line)" + :key="`draft_${index}`" + :draft="draftForLine(diffFile.file_hash, line)" + /> </template> </tbody> </table> diff --git a/app/assets/javascripts/diffs/components/parallel_diff_view.vue b/app/assets/javascripts/diffs/components/parallel_diff_view.vue index 1bf693380db..93e754fa896 100644 --- a/app/assets/javascripts/diffs/components/parallel_diff_view.vue +++ b/app/assets/javascripts/diffs/components/parallel_diff_view.vue @@ -1,5 +1,6 @@ <script> import { mapGetters } from 'vuex'; +import draftCommentsMixin from 'ee_else_ce/diffs/mixins/draft_comments'; import parallelDiffTableRow from './parallel_diff_table_row.vue'; import parallelDiffCommentRow from './parallel_diff_comment_row.vue'; @@ -7,7 +8,10 @@ export default { components: { parallelDiffTableRow, parallelDiffCommentRow, + ParallelDraftCommentRow: () => + import('ee_component/batch_comments/components/parallel_draft_comment_row.vue'), }, + mixins: [draftCommentsMixin], props: { diffFile: { type: Object, @@ -56,6 +60,12 @@ export default { :line-index="index" :help-page-path="helpPagePath" /> + <parallel-draft-comment-row + v-if="shouldRenderParallelDraftRow(diffFile.file_hash, line)" + :key="`drafts-${index}`" + :line="line" + :diff-file-content-sha="diffFile.file_hash" + /> </template> </tbody> </table> diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js index 7002655ea49..6f380fe6ece 100644 --- a/app/assets/javascripts/diffs/constants.js +++ b/app/assets/javascripts/diffs/constants.js @@ -42,3 +42,8 @@ export const INITIAL_TREE_WIDTH = 320; export const MIN_TREE_WIDTH = 240; export const MAX_TREE_WIDTH = 400; export const TREE_HIDE_STATS_WIDTH = 260; + +export const OLD_LINE_KEY = 'old_line'; +export const NEW_LINE_KEY = 'new_line'; +export const TYPE_KEY = 'type'; +export const LEFT_LINE_KEY = 'left'; diff --git a/app/assets/javascripts/diffs/mixins/draft_comments.js b/app/assets/javascripts/diffs/mixins/draft_comments.js new file mode 100644 index 00000000000..cfa722b27f1 --- /dev/null +++ b/app/assets/javascripts/diffs/mixins/draft_comments.js @@ -0,0 +1,7 @@ +export default { + computed: { + shouldRenderDraftRow: () => () => false, + shouldRenderParallelDraftRow: () => () => false, + draftForLine: () => () => ({}), + }, +}; diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index c40775c3259..57ddc923a3e 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -309,5 +309,40 @@ export const cacheTreeListWidth = (_, size) => { localStorage.setItem(TREE_LIST_WIDTH_STORAGE_KEY, size); }; +export const requestFullDiff = ({ commit }, filePath) => commit(types.REQUEST_FULL_DIFF, filePath); +export const receiveFullDiffSucess = ({ commit }, { filePath, data }) => + commit(types.RECEIVE_FULL_DIFF_SUCCESS, { filePath, data }); +export const receiveFullDiffError = ({ commit }, filePath) => { + commit(types.RECEIVE_FULL_DIFF_ERROR, filePath); + createFlash(s__('MergeRequest|Error loading full diff. Please try again.')); +}; + +export const fetchFullDiff = ({ dispatch }, file) => + axios + .get(file.context_lines_path, { + params: { + full: true, + from_merge_request: true, + }, + }) + .then(({ data }) => dispatch('receiveFullDiffSucess', { filePath: file.file_path, data })) + .then(() => scrollToElement(`#${file.file_hash}`)) + .catch(() => dispatch('receiveFullDiffError', file.file_path)); + +export const toggleFullDiff = ({ dispatch, getters, state }, filePath) => { + const file = state.diffFiles.find(f => f.file_path === filePath); + + dispatch('requestFullDiff', filePath); + + if (file.isShowingFullFile) { + dispatch('loadCollapsedDiff', file) + .then(() => dispatch('assignDiscussionsToDiff', getters.getDiffFileDiscussions(file))) + .then(() => scrollToElement(`#${file.file_hash}`)) + .catch(() => dispatch('receiveFullDiffError', filePath)); + } else { + dispatch('fetchFullDiff', file); + } +}; + // prevent babel-plugin-rewire from generating an invalid default during karma tests export default () => {}; diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js index 71ad108ce88..b441b1de451 100644 --- a/app/assets/javascripts/diffs/store/mutation_types.js +++ b/app/assets/javascripts/diffs/store/mutation_types.js @@ -23,3 +23,7 @@ export const SET_TREE_DATA = 'SET_TREE_DATA'; export const SET_RENDER_TREE_LIST = 'SET_RENDER_TREE_LIST'; export const SET_SHOW_WHITESPACE = 'SET_SHOW_WHITESPACE'; export const TOGGLE_FILE_FINDER_VISIBLE = 'TOGGLE_FILE_FINDER_VISIBLE'; + +export const REQUEST_FULL_DIFF = 'REQUEST_FULL_DIFF'; +export const RECEIVE_FULL_DIFF_SUCCESS = 'RECEIVE_FULL_DIFF_SUCCESS'; +export const RECEIVE_FULL_DIFF_ERROR = 'RECEIVE_FULL_DIFF_ERROR'; diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js index 5a27388863c..45187d93fef 100644 --- a/app/assets/javascripts/diffs/store/mutations.js +++ b/app/assets/javascripts/diffs/store/mutations.js @@ -6,8 +6,10 @@ import { addContextLines, prepareDiffData, isDiscussionApplicableToLine, + convertExpandLines, } from './utils'; import * as types from './mutation_types'; +import { OLD_LINE_KEY, NEW_LINE_KEY, TYPE_KEY, LEFT_LINE_KEY } from '../constants'; export default { [types.SET_BASE_CONFIG](state, options) { @@ -248,4 +250,54 @@ export default { [types.TOGGLE_FILE_FINDER_VISIBLE](state, visible) { state.fileFinderVisible = visible; }, + [types.REQUEST_FULL_DIFF](state, filePath) { + const file = findDiffFile(state.diffFiles, filePath, 'file_path'); + + file.isLoadingFullFile = true; + }, + [types.RECEIVE_FULL_DIFF_ERROR](state, filePath) { + const file = findDiffFile(state.diffFiles, filePath, 'file_path'); + + file.isLoadingFullFile = false; + }, + [types.RECEIVE_FULL_DIFF_SUCCESS](state, { filePath, data }) { + const file = findDiffFile(state.diffFiles, filePath, 'file_path'); + + file.isShowingFullFile = true; + file.isLoadingFullFile = false; + + file.highlighted_diff_lines = convertExpandLines({ + diffLines: file.highlighted_diff_lines, + typeKey: [TYPE_KEY], + oldLineKey: [OLD_LINE_KEY], + newLineKey: [NEW_LINE_KEY], + data, + mapLine: ({ line, oldLine, newLine }) => ({ + ...line, + old_line: oldLine, + new_line: newLine, + line_code: `${file.file_hash}_${oldLine}_${newLine}`, + }), + }); + + file.parallel_diff_lines = convertExpandLines({ + diffLines: file.parallel_diff_lines, + typeKey: [LEFT_LINE_KEY, TYPE_KEY], + oldLineKey: [LEFT_LINE_KEY, OLD_LINE_KEY], + newLineKey: [LEFT_LINE_KEY, NEW_LINE_KEY], + data, + mapLine: ({ line, oldLine, newLine }) => ({ + left: { + ...line, + old_line: oldLine, + line_code: `${file.file_hash}_${oldLine}_${newLine}`, + }, + right: { + ...line, + new_line: newLine, + line_code: `${file.file_hash}_${newLine}_${oldLine}`, + }, + }), + }); + }, }; diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js index 247d1e65fea..27a79369a24 100644 --- a/app/assets/javascripts/diffs/store/utils.js +++ b/app/assets/javascripts/diffs/store/utils.js @@ -15,8 +15,8 @@ import { TREE_TYPE, } from '../constants'; -export function findDiffFile(files, hash) { - return files.filter(file => file.file_hash === hash)[0]; +export function findDiffFile(files, match, matchKey = 'file_hash') { + return files.find(file => file[matchKey] === match); } export const getReversePosition = linePosition => { @@ -250,6 +250,8 @@ export function prepareDiffData(diffData) { renderIt: showingLines < LINES_TO_BE_RENDERED_DIRECTLY, collapsed: file.viewer.name === diffViewerModes.text && showingLines > MAX_LINES_TO_BE_RENDERED, + isShowingFullFile: false, + isLoadingFullFile: false, discussions: [], }); } @@ -411,3 +413,37 @@ export const getDiffMode = diffFile => { diffModes.replaced ); }; + +export const convertExpandLines = ({ + diffLines, + data, + typeKey, + oldLineKey, + newLineKey, + mapLine, +}) => { + const dataLength = data.length; + + return diffLines.reduce((acc, line, i) => { + if (_.property(typeKey)(line) === 'match') { + const beforeLine = diffLines[i - 1]; + const afterLine = diffLines[i + 1]; + const beforeLineIndex = _.property(newLineKey)(beforeLine) || 0; + const afterLineIndex = _.property(newLineKey)(afterLine) - 1 || dataLength; + + acc.push( + ...data.slice(beforeLineIndex, afterLineIndex).map((l, index) => ({ + ...mapLine({ + line: { ...l, hasForm: false, discussions: [] }, + oldLine: (_.property(oldLineKey)(beforeLine) || 0) + index + 1, + newLine: (_.property(newLineKey)(beforeLine) || 0) + index + 1, + }), + })), + ); + } else { + acc.push(line); + } + + return acc; + }, []); +}; diff --git a/app/assets/javascripts/emoji/index.js b/app/assets/javascripts/emoji/index.js index cd8dff40b88..36542315c4c 100644 --- a/app/assets/javascripts/emoji/index.js +++ b/app/assets/javascripts/emoji/index.js @@ -1,13 +1,58 @@ import _ from 'underscore'; -import emojiMap from 'emojis/digests.json'; +import createFlash from '~/flash'; +import { s__ } from '~/locale'; import emojiAliases from 'emojis/aliases.json'; +import axios from '../lib/utils/axios_utils'; -export const validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; +import AccessorUtilities from '../lib/utils/accessor'; + +let emojiMap = null; +let validEmojiNames = null; + +export const EMOJI_VERSION = '1'; +const EMOJI_VERSION_LOCALSTORAGE = `EMOJIS_${EMOJI_VERSION}`; + +const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe(); + +export function initEmojiMap() { + return new Promise((resolve, reject) => { + if (emojiMap) { + resolve(emojiMap); + } else if (isLocalStorageAvailable && window.localStorage.getItem(EMOJI_VERSION_LOCALSTORAGE)) { + emojiMap = JSON.parse(window.localStorage.getItem(EMOJI_VERSION_LOCALSTORAGE)); + validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; + resolve(emojiMap); + } else { + // We load the JSON from server + axios + .get( + `${gon.asset_host || ''}${gon.relative_url_root || + ''}/-/emojis/${EMOJI_VERSION}/emojis.json`, + ) + .then(({ data }) => { + emojiMap = data; + validEmojiNames = [...Object.keys(emojiMap), ...Object.keys(emojiAliases)]; + resolve(emojiMap); + if (isLocalStorageAvailable) { + window.localStorage.setItem(EMOJI_VERSION_LOCALSTORAGE, JSON.stringify(emojiMap)); + } + }) + .catch(err => { + createFlash(s__('Emojis|Something went wrong while loading emojis.')); + reject(err); + }); + } + }); +} export function normalizeEmojiName(name) { return Object.prototype.hasOwnProperty.call(emojiAliases, name) ? emojiAliases[name] : name; } +export function getValidEmojiNames() { + return validEmojiNames; +} + export function isEmojiNameValid(name) { return validEmojiNames.indexOf(name) >= 0; } @@ -36,8 +81,8 @@ export function getEmojiCategoryMap() { }; Object.keys(emojiMap).forEach(name => { const emoji = emojiMap[name]; - if (emojiCategoryMap[emoji.category]) { - emojiCategoryMap[emoji.category].push(name); + if (emojiCategoryMap[emoji.c]) { + emojiCategoryMap[emoji.c].push(name); } }); } @@ -58,8 +103,9 @@ export function getEmojiInfo(query) { } export function emojiFallbackImageSrc(inputName) { - const { name, digest } = getEmojiInfo(inputName); - return `${gon.asset_host || ''}${gon.relative_url_root || ''}/assets/emoji/${name}-${digest}.png`; + const { name } = getEmojiInfo(inputName); + return `${gon.asset_host || ''}${gon.relative_url_root || + ''}/-/emojis/${EMOJI_VERSION}/${name}.png`; } export function emojiImageTag(name, src) { @@ -68,9 +114,8 @@ export function emojiImageTag(name, src) { export function glEmojiTag(inputName, options) { const opts = { sprite: false, forceFallback: false, ...options }; - const { name, ...emojiInfo } = getEmojiInfo(inputName); + const name = normalizeEmojiName(inputName); - const fallbackImageSrc = emojiFallbackImageSrc(name); const fallbackSpriteClass = `emoji-${name}`; const classList = []; @@ -79,24 +124,19 @@ export function glEmojiTag(inputName, options) { 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); - } + const forceFallbackAttribute = opts.forceFallback ? 'data-force-fallback="true"' : ''; return ` <gl-emoji ${classAttribute} data-name="${name}" - data-fallback-src="${fallbackImageSrc}" ${fallbackSpriteAttribute} - data-unicode-version="${emojiInfo.unicodeVersion}" - title="${emojiInfo.description}" + ${forceFallbackAttribute} > - ${contents} </gl-emoji> `; } diff --git a/app/assets/javascripts/emoji/support/index.js b/app/assets/javascripts/emoji/support/index.js index 1f7852dd487..ed9bfb8bc78 100644 --- a/app/assets/javascripts/emoji/support/index.js +++ b/app/assets/javascripts/emoji/support/index.js @@ -5,6 +5,9 @@ import getUnicodeSupportMap from './unicode_support_map'; let browserUnicodeSupportMap; export default function isEmojiUnicodeSupportedByBrowser(emojiUnicode, unicodeVersion) { + // Our Spec browser would fail producing emoji maps + if (/\bHeadlessChrome\//.test(navigator.userAgent)) return true; + browserUnicodeSupportMap = browserUnicodeSupportMap || getUnicodeSupportMap(); return isEmojiUnicodeSupported(browserUnicodeSupportMap, emojiUnicode, unicodeVersion); } diff --git a/app/assets/javascripts/environments/components/confirm_rollback_modal.vue b/app/assets/javascripts/environments/components/confirm_rollback_modal.vue new file mode 100644 index 00000000000..a8ee3f4ac10 --- /dev/null +++ b/app/assets/javascripts/environments/components/confirm_rollback_modal.vue @@ -0,0 +1,108 @@ +<script> +/** + * Render modal to confirm rollback/redeploy. + */ + +import _ from 'underscore'; +import { GlModal } from '@gitlab/ui'; +import { s__, sprintf } from '~/locale'; + +import eventHub from '../event_hub'; + +export default { + name: 'ConfirmRollbackModal', + + components: { + GlModal, + }, + + props: { + environment: { + type: Object, + required: true, + }, + }, + + computed: { + modalTitle() { + const title = this.environment.isLastDeployment + ? s__('Environments|Re-deploy environment %{name}?') + : s__('Environments|Rollback environment %{name}?'); + + return sprintf(title, { + name: _.escape(this.environment.name), + }); + }, + + commitShortSha() { + const { last_deployment } = this.environment; + return this.commitData(last_deployment, 'short_id'); + }, + + commitUrl() { + const { last_deployment } = this.environment; + return this.commitData(last_deployment, 'commit_path'); + }, + + commitTitle() { + const { last_deployment } = this.environment; + return this.commitData(last_deployment, 'title'); + }, + + modalText() { + const linkStart = `<a class="commit-sha" href="${_.escape(this.commitUrl)}">`; + const commitId = _.escape(this.commitShortSha); + const linkEnd = '</a>'; + const name = _.escape(this.name); + const body = this.environment.isLastDeployment + ? s__( + 'Environments|This action will relaunch the job for commit %{linkStart}%{commitId}%{linkEnd}, putting the environment in a previous version. Are you sure you want to continue?', + ) + : s__( + 'Environments|This action will run the job defined by %{name} for commit %{linkStart}%{commitId}%{linkEnd} putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?', + ); + return sprintf( + body, + { + commitId, + linkStart, + linkEnd, + name, + }, + false, + ); + }, + + modalActionText() { + return this.environment.isLastDeployment + ? s__('Environments|Re-deploy') + : s__('Environments|Rollback'); + }, + }, + + methods: { + onOk() { + eventHub.$emit('rollbackEnvironment', this.environment); + }, + + commitData(lastDeployment, key) { + if (lastDeployment && lastDeployment.commit) { + return lastDeployment.commit[key]; + } + + return ''; + }, + }, +}; +</script> +<template> + <gl-modal + :title="modalTitle" + modal-id="confirm-rollback-modal" + :ok-title="modalActionText" + ok-variant="danger" + @ok="onOk" + > + <p v-html="modalText"></p> + </gl-modal> +</template> diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue index 503c1b38f71..1e89dce69cb 100644 --- a/app/assets/javascripts/environments/components/environment_item.vue +++ b/app/assets/javascripts/environments/components/environment_item.vue @@ -3,7 +3,6 @@ import Timeago from 'timeago.js'; import _ from 'underscore'; import { GlTooltipDirective } from '@gitlab/ui'; import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; -import { humanize } from '~/lib/utils/text_utility'; import Icon from '~/vue_shared/components/icon.vue'; import ActionsComponent from './environment_actions.vue'; import ExternalUrlComponent from './environment_external_url.vue'; @@ -156,7 +155,7 @@ export default { const combinedActions = (manualActions || []).concat(scheduledActions || []); return combinedActions.map(action => ({ ...action, - name: humanize(action.name), + name: action.name, })); }, @@ -556,6 +555,7 @@ export default { <rollback-component v-if="canRetry" + :environment="model" :is-last-deployment="isLastDeployment" :retry-url="retryUrl" /> diff --git a/app/assets/javascripts/environments/components/environment_rollback.vue b/app/assets/javascripts/environments/components/environment_rollback.vue index 50c86af057c..266cdc42518 100644 --- a/app/assets/javascripts/environments/components/environment_rollback.vue +++ b/app/assets/javascripts/environments/components/environment_rollback.vue @@ -5,29 +5,38 @@ * * Makes a post request when the button is clicked. */ +import { GlTooltipDirective, GlLoadingIcon, GlModalDirective, GlButton } from '@gitlab/ui'; import { s__ } from '~/locale'; -import { GlTooltipDirective, GlLoadingIcon } from '@gitlab/ui'; import Icon from '~/vue_shared/components/icon.vue'; +import ConfirmRollbackModal from './confirm_rollback_modal.vue'; import eventHub from '../event_hub'; export default { components: { Icon, GlLoadingIcon, + GlButton, + ConfirmRollbackModal, }, directives: { GlTooltip: GlTooltipDirective, + GlModal: GlModalDirective, }, props: { - retryUrl: { - type: String, - default: '', - }, - isLastDeployment: { type: Boolean, default: true, }, + + environment: { + type: Object, + required: true, + }, + + retryUrl: { + type: String, + required: true, + }, }, data() { return { @@ -45,23 +54,31 @@ export default { methods: { onClick() { - this.isLoading = true; - - eventHub.$emit('postAction', { endpoint: this.retryUrl }); + eventHub.$emit('requestRollbackEnvironment', { + ...this.environment, + retryUrl: this.retryUrl, + isLastDeployment: this.isLastDeployment, + }); + eventHub.$on('rollbackEnvironment', environment => { + if (environment.id === this.environment.id) { + this.isLoading = true; + } + }); }, }, }; </script> <template> - <button + <gl-button v-gl-tooltip + v-gl-modal.confirm-rollback-modal + variant="secondary" :disabled="isLoading" :title="title" - type="button" - class="btn d-none d-sm-none d-md-block" + class="d-none d-md-block" @click="onClick" > <icon v-if="isLastDeployment" name="repeat" /> <icon v-else name="redo" /> <gl-loading-icon v-if="isLoading" /> - </button> + </gl-button> </template> diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue index aa2417d3194..6e55c3f901a 100644 --- a/app/assets/javascripts/environments/components/environments_app.vue +++ b/app/assets/javascripts/environments/components/environments_app.vue @@ -6,11 +6,13 @@ import eventHub from '../event_hub'; import environmentsMixin from '../mixins/environments_mixin'; import CIPaginationMixin from '../../vue_shared/mixins/ci_pagination_api_mixin'; import StopEnvironmentModal from './stop_environment_modal.vue'; +import ConfirmRollbackModal from './confirm_rollback_modal.vue'; export default { components: { emptyState, StopEnvironmentModal, + ConfirmRollbackModal, }, mixins: [CIPaginationMixin, environmentsMixin], @@ -87,6 +89,7 @@ export default { <template> <div :class="cssContainerClass"> <stop-environment-modal :environment="environmentInStopModal" /> + <confirm-rollback-modal :environment="environmentInRollbackModal" /> <div class="top-area"> <tabs :tabs="tabs" scope="environments" @onChangeTab="onChangeTab" /> diff --git a/app/assets/javascripts/environments/mixins/environments_mixin.js b/app/assets/javascripts/environments/mixins/environments_mixin.js index 9d83840c87c..71b6b578196 100644 --- a/app/assets/javascripts/environments/mixins/environments_mixin.js +++ b/app/assets/javascripts/environments/mixins/environments_mixin.js @@ -36,6 +36,7 @@ export default { page: getParameterByName('page') || '1', requestData: {}, environmentInStopModal: {}, + environmentInRollbackModal: {}, }; }, @@ -116,6 +117,10 @@ export default { this.environmentInStopModal = environment; }, + updateRollbackModal(environment) { + this.environmentInRollbackModal = environment; + }, + stopEnvironment(environment) { const endpoint = environment.stop_path; const errorMessage = s__( @@ -123,6 +128,16 @@ export default { ); this.postAction({ endpoint, errorMessage }); }, + + rollbackEnvironment(environment) { + const { retryUrl, isLastDeployment } = environment; + const errorMessage = isLastDeployment + ? s__('Environments|An error occurred while re-deploying the environment, please try again') + : s__( + 'Environments|An error occurred while rolling back the environment, please try again', + ); + this.postAction({ endpoint: retryUrl, errorMessage }); + }, }, computed: { @@ -181,11 +196,17 @@ export default { eventHub.$on('postAction', this.postAction); eventHub.$on('requestStopEnvironment', this.updateStopModal); eventHub.$on('stopEnvironment', this.stopEnvironment); + + eventHub.$on('requestRollbackEnvironment', this.updateRollbackModal); + eventHub.$on('rollbackEnvironment', this.rollbackEnvironment); }, beforeDestroy() { eventHub.$off('postAction', this.postAction); eventHub.$off('requestStopEnvironment', this.updateStopModal); eventHub.$off('stopEnvironment', this.stopEnvironment); + + eventHub.$off('requestRollbackEnvironment', this.updateRollbackModal); + eventHub.$off('rollbackEnvironment', this.rollbackEnvironment); }, }; diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue index 6981afe1ead..43ae54133af 100644 --- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue +++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue @@ -48,7 +48,7 @@ export default { } }, methods: { - ...mapActions(['startPolling']), + ...mapActions(['startPolling', 'restartPolling']), }, }; </script> @@ -56,19 +56,17 @@ export default { <template> <div> <div v-if="errorTrackingEnabled"> - <div v-if="loading" class="py-3"><gl-loading-icon :size="3" /></div> + <div v-if="loading" class="py-3"> + <gl-loading-icon :size="3" /> + </div> <div v-else> <div class="d-flex justify-content-end"> - <gl-button class="my-3 ml-auto" variant="primary" :href="externalUrl" target="_blank" - >View in Sentry <icon name="external-link" /> + <gl-button class="my-3 ml-auto" variant="primary" :href="externalUrl" target="_blank"> + {{ __('View in Sentry') }} + <icon name="external-link" /> </gl-button> </div> - <gl-table - :items="errors" - :fields="$options.fields" - :show-empty="true" - :empty-text="__('No errors to display')" - > + <gl-table :items="errors" :fields="$options.fields" :show-empty="true"> <template slot="HEAD_events" slot-scope="data"> <div class="text-right">{{ data.label }}</div> </template> @@ -102,6 +100,14 @@ export default { <time-ago :time="errors.item.lastSeen" class="text-secondary" /> </div> </template> + <template slot="empty"> + <div ref="empty"> + {{ __('No errors to display.') }} + <gl-link class="js-try-again" @click="restartPolling"> + {{ __('Check again') }} + </gl-link> + </div> + </template> </gl-table> </div> </div> diff --git a/app/assets/javascripts/error_tracking/store/actions.js b/app/assets/javascripts/error_tracking/store/actions.js index 11aec312368..d42e4f145dc 100644 --- a/app/assets/javascripts/error_tracking/store/actions.js +++ b/app/assets/javascripts/error_tracking/store/actions.js @@ -6,7 +6,7 @@ import { __, sprintf } from '~/locale'; let eTagPoll; -export function startPolling({ commit }, endpoint) { +export function startPolling({ commit, dispatch }, endpoint) { eTagPoll = new Poll({ resource: Service, method: 'getErrorList', @@ -18,6 +18,7 @@ export function startPolling({ commit }, endpoint) { commit(types.SET_ERRORS, data.errors); commit(types.SET_EXTERNAL_URL, data.external_url); commit(types.SET_LOADING, false); + dispatch('stopPolling'); }, errorCallback: response => { let errorMessage = ''; @@ -36,4 +37,16 @@ export function startPolling({ commit }, endpoint) { eTagPoll.makeRequest(); } +export const stopPolling = () => { + if (eTagPoll) eTagPoll.stop(); +}; + +export function restartPolling({ commit }) { + commit(types.SET_ERRORS, []); + commit(types.SET_EXTERNAL_URL, ''); + commit(types.SET_LOADING, true); + + if (eTagPoll) eTagPoll.restart(); +} + export default () => {}; diff --git a/app/assets/javascripts/error_tracking_settings/components/app.vue b/app/assets/javascripts/error_tracking_settings/components/app.vue new file mode 100644 index 00000000000..50eb3e63b7c --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/components/app.vue @@ -0,0 +1,129 @@ +<script> +import { mapActions, mapGetters, mapState } from 'vuex'; +import { GlButton } from '@gitlab/ui'; +import ProjectDropdown from './project_dropdown.vue'; +import ErrorTrackingForm from './error_tracking_form.vue'; + +export default { + components: { ProjectDropdown, ErrorTrackingForm, GlButton }, + props: { + initialApiHost: { + type: String, + required: false, + default: '', + }, + initialEnabled: { + type: String, + required: true, + }, + initialProject: { + type: String, + required: false, + default: null, + }, + initialToken: { + type: String, + required: false, + default: '', + }, + listProjectsEndpoint: { + type: String, + required: true, + }, + operationsSettingsEndpoint: { + type: String, + required: true, + }, + }, + computed: { + ...mapGetters([ + 'dropdownLabel', + 'hasProjects', + 'invalidProjectLabel', + 'isProjectInvalid', + 'projectSelectionLabel', + ]), + ...mapState([ + 'apiHost', + 'connectError', + 'connectSuccessful', + 'enabled', + 'projects', + 'selectedProject', + 'settingsLoading', + 'token', + ]), + }, + created() { + this.setInitialState({ + apiHost: this.initialApiHost, + enabled: this.initialEnabled, + project: this.initialProject, + token: this.initialToken, + listProjectsEndpoint: this.listProjectsEndpoint, + operationsSettingsEndpoint: this.operationsSettingsEndpoint, + }); + }, + methods: { + ...mapActions([ + 'fetchProjects', + 'setInitialState', + 'updateApiHost', + 'updateEnabled', + 'updateSelectedProject', + 'updateSettings', + 'updateToken', + ]), + handleSubmit() { + this.updateSettings(); + }, + }, +}; +</script> + +<template> + <div> + <div class="form-check form-group"> + <input + id="error-tracking-enabled" + :checked="enabled" + class="form-check-input" + type="checkbox" + @change="updateEnabled($event.target.checked)" + /> + <label class="form-check-label" for="error-tracking-enabled">{{ + s__('ErrorTracking|Active') + }}</label> + </div> + <error-tracking-form + :api-host="apiHost" + :connect-error="connectError" + :connect-successful="connectSuccessful" + :token="token" + @handle-connect="fetchProjects" + @update-api-host="updateApiHost" + @update-token="updateToken" + /> + <div class="form-group"> + <project-dropdown + :has-projects="hasProjects" + :invalid-project-label="invalidProjectLabel" + :is-project-invalid="isProjectInvalid" + :dropdown-label="dropdownLabel" + :project-selection-label="projectSelectionLabel" + :projects="projects" + :selected-project="selectedProject" + :token="token" + @select-project="updateSelectedProject" + /> + </div> + <gl-button + :disabled="settingsLoading" + class="js-error-tracking-button" + variant="success" + @click="handleSubmit" + > + {{ __('Save changes') }} + </gl-button> + </div> +</template> diff --git a/app/assets/javascripts/error_tracking_settings/components/error_tracking_form.vue b/app/assets/javascripts/error_tracking_settings/components/error_tracking_form.vue new file mode 100644 index 00000000000..060d8e25227 --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/components/error_tracking_form.vue @@ -0,0 +1,91 @@ +<script> +import { GlButton, GlFormInput } from '@gitlab/ui'; +import Icon from '~/vue_shared/components/icon.vue'; + +export default { + components: { GlButton, GlFormInput, Icon }, + props: { + apiHost: { + type: String, + required: true, + }, + connectError: { + type: Boolean, + required: true, + }, + connectSuccessful: { + type: Boolean, + required: true, + }, + token: { + type: String, + required: true, + }, + }, + computed: { + tokenInputState() { + return this.connectError ? false : null; + }, + }, +}; +</script> + +<template> + <div> + <div class="form-group"> + <label class="label-bold" for="error-tracking-api-host">{{ __('Sentry API URL') }}</label> + <div class="row"> + <div class="col-8 col-md-9 gl-pr-0"> + <gl-form-input + id="error-tracking-api-host" + :value="apiHost" + placeholder="https://mysentryserver.com" + @input="$emit('update-api-host', $event)" + /> + </div> + </div> + <p class="form-text text-muted"> + {{ s__('ErrorTracking|Find your hostname in your Sentry account settings page') }} + </p> + </div> + <div class="form-group" :class="{ 'gl-show-field-errors': connectError }"> + <label class="label-bold" for="error-tracking-token">{{ + s__('ErrorTracking|Auth Token') + }}</label> + <div class="row"> + <div class="col-8 col-md-9 gl-pr-0"> + <gl-form-input + id="error-tracking-token" + :value="token" + :state="tokenInputState" + @input="$emit('update-token', $event)" + /> + </div> + <div class="col-4 col-md-3 gl-pl-0"> + <gl-button + class="js-error-tracking-connect prepend-left-5" + @click="$emit('handle-connect')" + > + {{ __('Connect') }} + </gl-button> + <icon + v-show="connectSuccessful" + class="js-error-tracking-connect-success prepend-left-5 text-success align-middle" + :aria-label="__('Projects Successfully Retrieved')" + name="check-circle" + /> + </div> + </div> + <p v-if="connectError" class="gl-field-error"> + {{ s__('ErrorTracking|Connection has failed. Re-check Auth Token and try again.') }} + </p> + <p v-else class="form-text text-muted"> + {{ + s__( + "ErrorTracking|After adding your Auth Token, use the 'Connect' button to load projects", + ) + }} + </p> + </div> + </div> +</template> diff --git a/app/assets/javascripts/error_tracking_settings/components/project_dropdown.vue b/app/assets/javascripts/error_tracking_settings/components/project_dropdown.vue new file mode 100644 index 00000000000..82df02afafd --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/components/project_dropdown.vue @@ -0,0 +1,82 @@ +<script> +import { GlDropdown, GlDropdownHeader, GlDropdownItem } from '@gitlab/ui'; +import Icon from '~/vue_shared/components/icon.vue'; +import { getDisplayName } from '../utils'; + +export default { + components: { + GlDropdown, + GlDropdownHeader, + GlDropdownItem, + Icon, + }, + props: { + dropdownLabel: { + type: String, + required: true, + }, + hasProjects: { + type: Boolean, + required: true, + }, + invalidProjectLabel: { + type: String, + required: true, + }, + isProjectInvalid: { + type: Boolean, + required: true, + }, + projects: { + type: Array, + required: true, + }, + selectedProject: { + type: Object, + required: false, + default: null, + }, + projectSelectionLabel: { + type: String, + required: true, + }, + token: { + type: String, + required: true, + }, + }, + methods: { + getDisplayName, + }, +}; +</script> + +<template> + <div :class="{ 'gl-show-field-errors': isProjectInvalid }"> + <label class="label-bold" for="project-dropdown">{{ __('Project') }}</label> + <div class="row"> + <gl-dropdown + id="project-dropdown" + class="col-8 col-md-9 gl-pr-0" + :disabled="!hasProjects" + menu-class="w-100 mw-100" + toggle-class="dropdown-menu-toggle w-100 gl-field-error-outline" + :text="dropdownLabel" + > + <gl-dropdown-item + v-for="project in projects" + :key="`${project.organizationSlug}.${project.slug}`" + class="w-100" + @click="$emit('select-project', project)" + >{{ getDisplayName(project) }}</gl-dropdown-item + > + </gl-dropdown> + </div> + <p v-if="isProjectInvalid" class="js-project-dropdown-error gl-field-error"> + {{ invalidProjectLabel }} + </p> + <p v-else-if="!hasProjects" class="js-project-dropdown-label form-text text-muted"> + {{ projectSelectionLabel }} + </p> + </div> +</template> diff --git a/app/assets/javascripts/error_tracking_settings/index.js b/app/assets/javascripts/error_tracking_settings/index.js new file mode 100644 index 00000000000..ce315963723 --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/index.js @@ -0,0 +1,27 @@ +import Vue from 'vue'; +import ErrorTrackingSettings from './components/app.vue'; +import createStore from './store'; + +export default () => { + const formContainerEl = document.querySelector('.js-error-tracking-form'); + const { + dataset: { apiHost, enabled, project, token, listProjectsEndpoint, operationsSettingsEndpoint }, + } = formContainerEl; + + return new Vue({ + el: formContainerEl, + store: createStore(), + render(createElement) { + return createElement(ErrorTrackingSettings, { + props: { + initialApiHost: apiHost, + initialEnabled: enabled, + initialProject: project, + initialToken: token, + listProjectsEndpoint, + operationsSettingsEndpoint, + }, + }); + }, + }); +}; diff --git a/app/assets/javascripts/error_tracking_settings/store/actions.js b/app/assets/javascripts/error_tracking_settings/store/actions.js new file mode 100644 index 00000000000..95105797807 --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/store/actions.js @@ -0,0 +1,91 @@ +import { __ } from '~/locale'; +import axios from '~/lib/utils/axios_utils'; +import { refreshCurrentPage } from '~/lib/utils/url_utility'; +import createFlash from '~/flash'; +import { transformFrontendSettings } from '../utils'; +import * as types from './mutation_types'; + +export const requestProjects = ({ commit }) => { + commit(types.RESET_CONNECT); +}; + +export const receiveProjectsSuccess = ({ commit }, projects) => { + commit(types.UPDATE_CONNECT_SUCCESS); + commit(types.RECEIVE_PROJECTS, projects); +}; + +export const receiveProjectsError = ({ commit }) => { + commit(types.UPDATE_CONNECT_ERROR); + commit(types.CLEAR_PROJECTS); +}; + +export const fetchProjects = ({ dispatch, state }) => { + dispatch('requestProjects'); + return axios + .post(state.listProjectsEndpoint, { + error_tracking_setting: { + api_host: state.apiHost, + token: state.token, + }, + }) + .then(({ data: { projects } }) => { + dispatch('receiveProjectsSuccess', projects); + }) + .catch(() => { + dispatch('receiveProjectsError'); + }); +}; + +export const requestSettings = ({ commit }) => { + commit(types.UPDATE_SETTINGS_LOADING, true); +}; + +export const receiveSettingsError = ({ commit }, { response = {} }) => { + const message = response.data && response.data.message ? response.data.message : ''; + + createFlash(`${__('There was an error saving your changes.')} ${message}`, 'alert'); + commit(types.UPDATE_SETTINGS_LOADING, false); +}; + +export const updateSettings = ({ dispatch, state }) => { + dispatch('requestSettings'); + return axios + .patch(state.operationsSettingsEndpoint, { + project: { + error_tracking_setting_attributes: { + ...transformFrontendSettings(state), + }, + }, + }) + .then(() => { + refreshCurrentPage(); + }) + .catch(err => { + dispatch('receiveSettingsError', err); + }); +}; + +export const updateApiHost = ({ commit }, apiHost) => { + commit(types.UPDATE_API_HOST, apiHost); + commit(types.RESET_CONNECT); +}; + +export const updateEnabled = ({ commit }, enabled) => { + commit(types.UPDATE_ENABLED, enabled); +}; + +export const updateToken = ({ commit }, token) => { + commit(types.UPDATE_TOKEN, token); + commit(types.RESET_CONNECT); +}; + +export const updateSelectedProject = ({ commit }, selectedProject) => { + commit(types.UPDATE_SELECTED_PROJECT, selectedProject); +}; + +export const setInitialState = ({ commit }, data) => { + commit(types.SET_INITIAL_STATE, data); +}; + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/error_tracking_settings/store/getters.js b/app/assets/javascripts/error_tracking_settings/store/getters.js new file mode 100644 index 00000000000..a008b181907 --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/store/getters.js @@ -0,0 +1,44 @@ +import _ from 'underscore'; +import { __, s__, sprintf } from '~/locale'; +import { getDisplayName } from '../utils'; + +export const hasProjects = state => !!state.projects && state.projects.length > 0; + +export const isProjectInvalid = (state, getters) => + !!state.selectedProject && + getters.hasProjects && + !state.projects.some(project => _.isMatch(state.selectedProject, project)); + +export const dropdownLabel = (state, getters) => { + if (state.selectedProject !== null) { + return getDisplayName(state.selectedProject); + } + if (!getters.hasProjects) { + return s__('ErrorTracking|No projects available'); + } + return s__('ErrorTracking|Select project'); +}; + +export const invalidProjectLabel = state => { + if (state.selectedProject) { + return sprintf( + __('Project "%{name}" is no longer available. Select another project to continue.'), + { + name: state.selectedProject.name, + }, + ); + } + return ''; +}; + +export const projectSelectionLabel = state => { + if (state.token) { + return s__( + "ErrorTracking|Click 'Connect' to re-establish the connection to Sentry and activate the dropdown.", + ); + } + return s__('ErrorTracking|To enable project selection, enter a valid Auth Token'); +}; + +// prevent babel-plugin-rewire from generating an invalid default during karma tests +export default () => {}; diff --git a/app/assets/javascripts/error_tracking_settings/store/index.js b/app/assets/javascripts/error_tracking_settings/store/index.js new file mode 100644 index 00000000000..560f265a2ea --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/store/index.js @@ -0,0 +1,16 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import createState from './state'; +import * as actions from './actions'; +import * as getters from './getters'; +import mutations from './mutations'; + +Vue.use(Vuex); + +export default () => + new Vuex.Store({ + state: createState(), + actions, + getters, + mutations, + }); diff --git a/app/assets/javascripts/error_tracking_settings/store/mutation_types.js b/app/assets/javascripts/error_tracking_settings/store/mutation_types.js new file mode 100644 index 00000000000..b4f8a237947 --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/store/mutation_types.js @@ -0,0 +1,11 @@ +export const CLEAR_PROJECTS = 'CLEAR_PROJECTS'; +export const SET_INITIAL_STATE = 'SET_INITIAL_STATE'; +export const RECEIVE_PROJECTS = 'RECEIVE_PROJECTS'; +export const RESET_CONNECT = 'RESET_CONNECT'; +export const UPDATE_API_HOST = 'UPDATE_API_HOST'; +export const UPDATE_CONNECT_ERROR = 'UPDATE_CONNECT_ERROR'; +export const UPDATE_CONNECT_SUCCESS = 'UPDATE_CONNECT_SUCCESS'; +export const UPDATE_ENABLED = 'UPDATE_ENABLED'; +export const UPDATE_SELECTED_PROJECT = 'UPDATE_SELECTED_PROJECT'; +export const UPDATE_SETTINGS_LOADING = 'UPDATE_SETTINGS_LOADING'; +export const UPDATE_TOKEN = 'UPDATE_TOKEN'; diff --git a/app/assets/javascripts/error_tracking_settings/store/mutations.js b/app/assets/javascripts/error_tracking_settings/store/mutations.js new file mode 100644 index 00000000000..4089d1ee94e --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/store/mutations.js @@ -0,0 +1,61 @@ +import _ from 'underscore'; +import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils'; +import * as types from './mutation_types'; +import { projectKeys } from '../utils'; + +export default { + [types.CLEAR_PROJECTS](state) { + state.projects = []; + }, + [types.RECEIVE_PROJECTS](state, projects) { + state.projects = projects + .map(convertObjectPropsToCamelCase) + // The `pick` strips out extra properties returned from Sentry. + // Such properties could be problematic later, e.g. when checking whether `projects` contains `selectedProject` + .map(project => _.pick(project, projectKeys)); + }, + [types.RESET_CONNECT](state) { + state.connectSuccessful = false; + state.connectError = false; + }, + [types.SET_INITIAL_STATE]( + state, + { apiHost, enabled, project, token, listProjectsEndpoint, operationsSettingsEndpoint }, + ) { + state.enabled = parseBoolean(enabled); + state.apiHost = apiHost; + state.token = token; + state.listProjectsEndpoint = listProjectsEndpoint; + state.operationsSettingsEndpoint = operationsSettingsEndpoint; + + if (project) { + state.selectedProject = _.pick( + convertObjectPropsToCamelCase(JSON.parse(project)), + projectKeys, + ); + } + }, + [types.UPDATE_API_HOST](state, apiHost) { + state.apiHost = apiHost; + }, + [types.UPDATE_ENABLED](state, enabled) { + state.enabled = enabled; + }, + [types.UPDATE_TOKEN](state, token) { + state.token = token; + }, + [types.UPDATE_SELECTED_PROJECT](state, selectedProject) { + state.selectedProject = selectedProject; + }, + [types.UPDATE_SETTINGS_LOADING](state, settingsLoading) { + state.settingsLoading = settingsLoading; + }, + [types.UPDATE_CONNECT_SUCCESS](state) { + state.connectSuccessful = true; + state.connectError = false; + }, + [types.UPDATE_CONNECT_ERROR](state) { + state.connectSuccessful = false; + state.connectError = true; + }, +}; diff --git a/app/assets/javascripts/error_tracking_settings/store/state.js b/app/assets/javascripts/error_tracking_settings/store/state.js new file mode 100644 index 00000000000..98219d33f4d --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/store/state.js @@ -0,0 +1,12 @@ +export default () => ({ + apiHost: '', + enabled: false, + token: '', + projects: [], + selectedProject: null, + settingsLoading: false, + connectSuccessful: false, + connectError: false, + listProjectsEndpoint: '', + operationsSettingsEndpoint: '', +}); diff --git a/app/assets/javascripts/error_tracking_settings/utils.js b/app/assets/javascripts/error_tracking_settings/utils.js new file mode 100644 index 00000000000..6613e04ee0e --- /dev/null +++ b/app/assets/javascripts/error_tracking_settings/utils.js @@ -0,0 +1,18 @@ +export const projectKeys = ['name', 'organizationName', 'organizationSlug', 'slug']; + +export const transformFrontendSettings = ({ apiHost, enabled, token, selectedProject }) => { + const project = selectedProject + ? { + slug: selectedProject.slug, + name: selectedProject.name, + organization_name: selectedProject.organizationName, + organization_slug: selectedProject.organizationSlug, + } + : null; + + return { api_host: apiHost || null, enabled, token: token || null, project }; +}; + +export const getDisplayName = project => `${project.organizationName} | ${project.name}`; + +export default () => {}; diff --git a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js index 934375023ba..691d165c585 100644 --- a/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js +++ b/app/assets/javascripts/filtered_search/admin_runners_filtered_search_token_keys.js @@ -17,6 +17,14 @@ const tokenKeys = [ icon: 'cube', tag: 'type', }, + { + key: 'tag', + type: 'array', + param: 'name[]', + symbol: '~', + icon: 'tag', + tag: '~tag', + }, ]; const AdminRunnersFilteredSearchTokenKeys = new FilteredSearchTokenKeys(tokenKeys); diff --git a/app/assets/javascripts/filtered_search/dropdown_ajax_filter.js b/app/assets/javascripts/filtered_search/dropdown_ajax_filter.js new file mode 100644 index 00000000000..b27bb63c220 --- /dev/null +++ b/app/assets/javascripts/filtered_search/dropdown_ajax_filter.js @@ -0,0 +1,68 @@ +import createFlash from '../flash'; +import AjaxFilter from '../droplab/plugins/ajax_filter'; +import FilteredSearchDropdown from './filtered_search_dropdown'; +import DropdownUtils from './dropdown_utils'; +import FilteredSearchTokenizer from './filtered_search_tokenizer'; +import { __ } from '~/locale'; + +export default class DropdownAjaxFilter extends FilteredSearchDropdown { + constructor(options = {}) { + const { tokenKeys, endpoint, symbol } = options; + + super(options); + + this.tokenKeys = tokenKeys; + this.endpoint = endpoint; + this.symbol = symbol; + + this.config = { + AjaxFilter: this.ajaxFilterConfig(), + }; + } + + ajaxFilterConfig() { + return { + endpoint: `${gon.relative_url_root || ''}${this.endpoint}`, + searchKey: 'search', + searchValueFunction: this.getSearchInput.bind(this), + loadingTemplate: this.loadingTemplate, + onError() { + createFlash(__('An error occurred fetching the dropdown data.')); + }, + }; + } + + itemClicked(e) { + super.itemClicked(e, selected => + selected.querySelector('.dropdown-light-content').innerText.trim(), + ); + } + + renderContent(forceShowList = false) { + this.droplab.changeHookList(this.hookId, this.dropdown, [AjaxFilter], this.config); + super.renderContent(forceShowList); + } + + getSearchInput() { + const query = DropdownUtils.getSearchInput(this.input); + const { lastToken } = FilteredSearchTokenizer.processTokens(query, this.tokenKeys.get()); + + let value = lastToken || ''; + + if (value[0] === this.symbol) { + value = value.slice(1); + } + + // Removes the first character if it is a quotation so that we can search + // with multiple words + if (value[0] === '"' || value[0] === "'") { + value = value.slice(1); + } + + return value; + } + + init() { + this.droplab.addHook(this.input, this.dropdown, [AjaxFilter], this.config).init(); + } +} diff --git a/app/assets/javascripts/filtered_search/dropdown_user.js b/app/assets/javascripts/filtered_search/dropdown_user.js index d5027590bb7..f1e7be6bde1 100644 --- a/app/assets/javascripts/filtered_search/dropdown_user.js +++ b/app/assets/javascripts/filtered_search/dropdown_user.js @@ -1,54 +1,34 @@ -import Flash from '../flash'; -import AjaxFilter from '../droplab/plugins/ajax_filter'; -import FilteredSearchDropdown from './filtered_search_dropdown'; import { addClassIfElementExists } from '../lib/utils/dom_utils'; -import DropdownUtils from './dropdown_utils'; -import FilteredSearchTokenizer from './filtered_search_tokenizer'; +import DropdownAjaxFilter from './dropdown_ajax_filter'; -export default class DropdownUser extends FilteredSearchDropdown { +export default class DropdownUser extends DropdownAjaxFilter { constructor(options = {}) { - const { tokenKeys } = options; - super(options); - this.config = { - AjaxFilter: { - endpoint: `${gon.relative_url_root || ''}/autocomplete/users.json`, - searchKey: 'search', - params: { - active: true, - group_id: this.getGroupId(), - project_id: this.getProjectId(), - current_user: true, - }, - searchValueFunction: this.getSearchInput.bind(this), - loadingTemplate: this.loadingTemplate, - onLoadingFinished: () => { - this.hideCurrentUser(); - }, - onError() { - /* eslint-disable no-new */ - new Flash('An error occurred fetching the dropdown data.'); - /* eslint-enable no-new */ - }, + super({ + ...options, + endpoint: '/autocomplete/users.json', + symbol: '@', + }); + } + + ajaxFilterConfig() { + return { + ...super.ajaxFilterConfig(), + params: { + active: true, + group_id: this.getGroupId(), + project_id: this.getProjectId(), + current_user: true, + }, + onLoadingFinished: () => { + this.hideCurrentUser(); }, }; - this.tokenKeys = tokenKeys; } hideCurrentUser() { addClassIfElementExists(this.dropdown.querySelector('.js-current-user'), 'hidden'); } - itemClicked(e) { - super.itemClicked(e, selected => - selected.querySelector('.dropdown-light-content').innerText.trim(), - ); - } - - renderContent(forceShowList = false) { - this.droplab.changeHookList(this.hookId, this.dropdown, [AjaxFilter], this.config); - super.renderContent(forceShowList); - } - getGroupId() { return this.input.getAttribute('data-group-id'); } @@ -56,27 +36,4 @@ export default class DropdownUser extends FilteredSearchDropdown { getProjectId() { return this.input.getAttribute('data-project-id'); } - - getSearchInput() { - const query = DropdownUtils.getSearchInput(this.input); - const { lastToken } = FilteredSearchTokenizer.processTokens(query, this.tokenKeys.get()); - - let value = lastToken || ''; - - if (value[0] === '@') { - value = value.slice(1); - } - - // Removes the first character if it is a quotation so that we can search - // with multiple words - if (value[0] === '"' || value[0] === "'") { - value = value.slice(1); - } - - return value; - } - - init() { - this.droplab.addHook(this.input, this.dropdown, [AjaxFilter], this.config).init(); - } } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js index 4d05f46ed17..57847d4ad9f 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js @@ -7,6 +7,7 @@ import DropdownHint from './dropdown_hint'; import DropdownEmoji from './dropdown_emoji'; import DropdownNonUser from './dropdown_non_user'; import DropdownUser from './dropdown_user'; +import DropdownAjaxFilter from './dropdown_ajax_filter'; import NullDropdown from './null_dropdown'; import FilteredSearchVisualTokens from './filtered_search_visual_tokens'; @@ -111,6 +112,15 @@ export default class FilteredSearchDropdownManager { gl: NullDropdown, element: this.container.querySelector('#js-dropdown-admin-runner-type'), }, + tag: { + reference: null, + gl: DropdownAjaxFilter, + extraArguments: { + endpoint: this.getRunnerTagsEndpoint(), + symbol: '~', + }, + element: this.container.querySelector('#js-dropdown-runner-tag'), + }, }; supportedTokens.forEach(type => { @@ -146,6 +156,10 @@ export default class FilteredSearchDropdownManager { return endpoint; } + getRunnerTagsEndpoint() { + return `${this.baseEndpoint}/admin/runners/tag_list.json`; + } + static addWordToInput(tokenName, tokenValue = '', clicked = false, options = {}) { const { uppercaseTokenName = false, capitalizeTokenValue = false } = options; const input = FilteredSearchContainer.container.querySelector('.filtered-search'); diff --git a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js index 5090b0bdc3c..addf1ad94df 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js +++ b/app/assets/javascripts/filtered_search/filtered_search_visual_tokens.js @@ -142,19 +142,29 @@ export default class FilteredSearchVisualTokens { static updateEmojiTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) { const container = tokenValueContainer; const element = tokenValueElement; + const value = tokenValue; return ( import(/* webpackChunkName: 'emoji' */ '../emoji') .then(Emoji => { - if (!Emoji.isEmojiNameValid(tokenValue)) { - return; - } - - container.dataset.originalValue = tokenValue; - element.innerHTML = Emoji.glEmojiTag(tokenValue); + Emoji.initEmojiMap() + .then(() => { + if (!Emoji.isEmojiNameValid(value)) { + return; + } + + container.dataset.originalValue = value; + element.innerHTML = Emoji.glEmojiTag(value); + }) + // ignore error and leave emoji name in the search bar + .catch(err => { + throw err; + }); }) // ignore error and leave emoji name in the search bar - .catch(() => {}) + .catch(importError => { + throw importError; + }) ); } diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index c81e754df4c..50ea13edf63 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -487,9 +487,15 @@ class GfmAutoComplete { this.loadData($input, at, this.cachedData[at]); } else if (GfmAutoComplete.atTypeMap[at] === 'emojis') { import(/* webpackChunkName: 'emoji' */ './emoji') - .then(({ validEmojiNames, glEmojiTag }) => { - this.loadData($input, at, validEmojiNames); - GfmAutoComplete.glEmojiTag = glEmojiTag; + .then(({ initEmojiMap, getValidEmojiNames, glEmojiTag }) => { + initEmojiMap() + .then(() => { + this.loadData($input, at, getValidEmojiNames()); + GfmAutoComplete.glEmojiTag = glEmojiTag; + }) + .catch(() => { + this.isLoadingData[at] = false; + }); }) .catch(() => { this.isLoadingData[at] = false; diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js index a8ac2f510a4..27d8669b256 100644 --- a/app/assets/javascripts/gl_dropdown.js +++ b/app/assets/javascripts/gl_dropdown.js @@ -656,23 +656,7 @@ GitLabDropdown = (function() { if (this.options.renderMenu) { return this.options.renderMenu(html); } else { - var ul = document.createElement('ul'); - - for (var i = 0; i < html.length; i += 1) { - var el = html[i]; - - if (el instanceof $) { - el = el.get(0); - } - - if (typeof el === 'string') { - ul.innerHTML += el; - } else { - ul.appendChild(el); - } - } - - return ul; + return $('<ul>').append(html); } }; diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue index d7a7b1b4d78..593a9162a06 100644 --- a/app/assets/javascripts/ide/components/new_dropdown/index.vue +++ b/app/assets/javascripts/ide/components/new_dropdown/index.vue @@ -1,7 +1,6 @@ <script> import { mapActions } from 'vuex'; import icon from '~/vue_shared/components/icon.vue'; -import newModal from './modal.vue'; import upload from './upload.vue'; import ItemButton from './button.vue'; import { modalTypes } from '../../constants'; @@ -9,7 +8,6 @@ import { modalTypes } from '../../constants'; export default { components: { icon, - newModal, upload, ItemButton, }, diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue index c9c4e9e86f8..ba6bbdfef4b 100644 --- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue +++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue @@ -1,6 +1,7 @@ <script> import $ from 'jquery'; -import { __ } from '~/locale'; +import flash from '~/flash'; +import { __, sprintf, s__ } from '~/locale'; import { mapActions, mapState, mapGetters } from 'vuex'; import GlModal from '~/vue_shared/components/gl_modal.vue'; import { modalTypes } from '../../constants'; @@ -15,15 +16,17 @@ export default { }; }, computed: { - ...mapState(['entryModal']), + ...mapState(['entries', 'entryModal']), ...mapGetters('fileTemplates', ['templateTypes']), entryName: { get() { + const entryPath = this.entryModal.entry.path; + if (this.entryModal.type === modalTypes.rename) { - return this.name || this.entryModal.entry.name; + return this.name || entryPath; } - return this.name || (this.entryModal.path !== '' ? `${this.entryModal.path}/` : ''); + return this.name || (entryPath ? `${entryPath}/` : ''); }, set(val) { this.name = val; @@ -62,10 +65,40 @@ export default { ...mapActions(['createTempEntry', 'renameEntry']), submitForm() { if (this.entryModal.type === modalTypes.rename) { - this.renameEntry({ - path: this.entryModal.entry.path, - name: this.entryName, - }); + if (this.entries[this.entryName] && !this.entries[this.entryName].deleted) { + flash( + sprintf(s__('The name %{entryName} is already taken in this directory.'), { + entryName: this.entryName, + }), + 'alert', + document, + null, + false, + true, + ); + } else { + let parentPath = this.entryName.split('/'); + const entryName = parentPath.pop(); + parentPath = parentPath.join('/'); + + const createPromise = + parentPath && !this.entries[parentPath] + ? this.createTempEntry({ name: parentPath, type: 'tree' }) + : Promise.resolve(); + + createPromise + .then(() => + this.renameEntry({ + path: this.entryModal.entry.path, + name: entryName, + entryPath: null, + parentPath, + }), + ) + .catch(() => + flash(__('Error creating a new path'), 'alert', document, null, false, true), + ); + } } else { this.createTempEntry({ name: this.name, @@ -82,7 +115,14 @@ export default { $('#ide-new-entry').modal('toggle'); }, focusInput() { + const name = this.entries[this.entryName] ? this.entries[this.entryName].name : null; + const inputValue = this.$refs.fieldName.value; + this.$refs.fieldName.focus(); + + if (name) { + this.$refs.fieldName.setSelectionRange(inputValue.indexOf(name), inputValue.length); + } }, closedModal() { this.name = ''; diff --git a/app/assets/javascripts/ide/lib/files.js b/app/assets/javascripts/ide/lib/files.js new file mode 100644 index 00000000000..5dfba8fe531 --- /dev/null +++ b/app/assets/javascripts/ide/lib/files.js @@ -0,0 +1,113 @@ +import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils'; +import { decorateData, sortTree } from '../stores/utils'; + +export const splitParent = path => { + const idx = path.lastIndexOf('/'); + + return { + parent: idx >= 0 ? path.substring(0, idx) : null, + name: idx >= 0 ? path.substring(idx + 1) : path, + }; +}; + +/** + * Create file objects from a list of file paths. + */ +export const decorateFiles = ({ + data, + projectId, + branchId, + tempFile = false, + content = '', + base64 = false, +}) => { + const treeList = []; + const entries = {}; + + // These mutable variable references end up being exported and used by `createTempEntry` + let file; + let parentPath; + + const insertParent = path => { + if (!path) { + return null; + } else if (entries[path]) { + return entries[path]; + } + + const { parent, name } = splitParent(path); + const parentFolder = parent && insertParent(parent); + parentPath = parentFolder && parentFolder.path; + + const tree = decorateData({ + projectId, + branchId, + id: path, + name, + path, + url: `/${projectId}/tree/${branchId}/-/${path}/`, + type: 'tree', + parentTreeUrl: parentFolder ? parentFolder.url : `/${projectId}/tree/${branchId}/`, + tempFile, + changed: tempFile, + opened: tempFile, + parentPath, + }); + + Object.assign(entries, { + [path]: tree, + }); + + if (parentFolder) { + parentFolder.tree.push(tree); + } else { + treeList.push(tree); + } + + return tree; + }; + + data.forEach(path => { + const { parent, name } = splitParent(path); + + const fileFolder = parent && insertParent(parent); + + if (name) { + parentPath = fileFolder && fileFolder.path; + + file = decorateData({ + projectId, + branchId, + id: path, + name, + path, + url: `/${projectId}/blob/${branchId}/-/${path}`, + type: 'blob', + parentTreeUrl: fileFolder ? fileFolder.url : `/${projectId}/blob/${branchId}`, + tempFile, + changed: tempFile, + content, + base64, + previewMode: viewerInformationForPath(name), + parentPath, + }); + + Object.assign(entries, { + [path]: file, + }); + + if (fileFolder) { + fileFolder.tree.push(file); + } else { + treeList.push(file); + } + } + }); + + return { + entries, + treeList: sortTree(treeList), + file, + parentPath, + }; +}; diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js index 13449592e62..ba33b6826d6 100644 --- a/app/assets/javascripts/ide/services/index.js +++ b/app/assets/javascripts/ide/services/index.js @@ -40,6 +40,9 @@ export default { getProjectData(namespace, project) { return Api.project(`${namespace}/${project}`); }, + getProjectMergeRequests(projectId, params = {}) { + return Api.projectMergeRequests(projectId, params); + }, getProjectMergeRequestData(projectId, mergeRequestId, params = {}) { return Api.projectMergeRequest(projectId, mergeRequestId, params); }, diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js index e10a132ab4b..7b660bda081 100644 --- a/app/assets/javascripts/ide/stores/actions.js +++ b/app/assets/javascripts/ide/stores/actions.js @@ -3,7 +3,7 @@ import Vue from 'vue'; import { visitUrl } from '~/lib/utils/url_utility'; import flash from '~/flash'; import * as types from './mutation_types'; -import FilesDecoratorWorker from './workers/files_decorator_worker'; +import { decorateFiles } from '../lib/files'; import { stageKeys } from '../constants'; export const redirectToUrl = (_, url) => visitUrl(url); @@ -56,7 +56,6 @@ export const createTempEntry = ( { name, type, content = '', base64 = false }, ) => new Promise(resolve => { - const worker = new FilesDecoratorWorker(); const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name; if (state.entries[name]) { @@ -74,31 +73,7 @@ export const createTempEntry = ( return null; } - worker.addEventListener('message', ({ data }) => { - const { file, parentPath } = data; - - worker.terminate(); - - commit(types.CREATE_TMP_ENTRY, { - data, - projectId: state.currentProjectId, - branchId: state.currentBranchId, - }); - - if (type === 'blob') { - commit(types.TOGGLE_FILE_OPEN, file.path); - commit(types.ADD_FILE_TO_CHANGED, file.path); - dispatch('setFileActive', file.path); - } - - if (parentPath && !state.entries[parentPath].opened) { - commit(types.TOGGLE_TREE_OPEN, parentPath); - } - - resolve(file); - }); - - worker.postMessage({ + const data = decorateFiles({ data: [fullName], projectId: state.currentProjectId, branchId: state.currentBranchId, @@ -107,6 +82,25 @@ export const createTempEntry = ( base64, content, }); + const { file, parentPath } = data; + + commit(types.CREATE_TMP_ENTRY, { + data, + projectId: state.currentProjectId, + branchId: state.currentBranchId, + }); + + if (type === 'blob') { + commit(types.TOGGLE_FILE_OPEN, file.path); + commit(types.ADD_FILE_TO_CHANGED, file.path); + dispatch('setFileActive', file.path); + } + + if (parentPath && !state.entries[parentPath].opened) { + commit(types.TOGGLE_TREE_OPEN, parentPath); + } + + resolve(file); return null; }); @@ -215,15 +209,27 @@ export const deleteEntry = ({ commit, dispatch, state }, path) => { export const resetOpenFiles = ({ commit }) => commit(types.RESET_OPEN_FILES); -export const renameEntry = ({ dispatch, commit, state }, { path, name, entryPath = null }) => { +export const renameEntry = ( + { dispatch, commit, state }, + { path, name, entryPath = null, parentPath }, +) => { const entry = state.entries[entryPath || path]; - commit(types.RENAME_ENTRY, { path, name, entryPath }); + commit(types.RENAME_ENTRY, { path, name, entryPath, parentPath }); if (entry.type === 'tree') { - state.entries[entryPath || path].tree.forEach(f => - dispatch('renameEntry', { path, name, entryPath: f.path }), - ); + const slashedParentPath = parentPath ? `${parentPath}/` : ''; + const targetEntry = entryPath ? entryPath.split('/').pop() : name; + const newParentPath = `${slashedParentPath}${targetEntry}`; + + state.entries[entryPath || path].tree.forEach(f => { + dispatch('renameEntry', { + path, + name, + entryPath: f.path, + parentPath: newParentPath, + }); + }); } if (!entryPath && !entry.tempFile) { diff --git a/app/assets/javascripts/ide/stores/actions/merge_request.js b/app/assets/javascripts/ide/stores/actions/merge_request.js index 18c24369996..362ced248a1 100644 --- a/app/assets/javascripts/ide/stores/actions/merge_request.js +++ b/app/assets/javascripts/ide/stores/actions/merge_request.js @@ -4,6 +4,38 @@ import service from '../../services'; import * as types from '../mutation_types'; import { activityBarViews } from '../../constants'; +export const getMergeRequestsForBranch = ({ commit }, { projectId, branchId } = {}) => + service + .getProjectMergeRequests(`${projectId}`, { + source_branch: branchId, + order_by: 'created_at', + per_page: 1, + }) + .then(({ data }) => { + if (data.length > 0) { + const currentMR = data[0]; + + commit(types.SET_MERGE_REQUEST, { + projectPath: projectId, + mergeRequestId: currentMR.iid, + mergeRequest: currentMR, + }); + + commit(types.SET_CURRENT_MERGE_REQUEST, `${currentMR.iid}`); + } + }) + .catch(e => { + flash( + __(`Error fetching merge requests for ${branchId}`), + 'alert', + document, + null, + false, + true, + ); + throw e; + }); + export const getMergeRequestData = ( { commit, dispatch, state }, { projectId, mergeRequestId, targetProjectId = null, force = false } = {}, diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js index b65f631c99c..06ed5c0b572 100644 --- a/app/assets/javascripts/ide/stores/actions/project.js +++ b/app/assets/javascripts/ide/stores/actions/project.js @@ -136,17 +136,24 @@ export const openBranch = ({ dispatch, state }, { projectId, branchId, basePath return dispatch('getFiles', { projectId, branchId, - }).then(() => { - if (basePath) { - const path = basePath.slice(-1) === '/' ? basePath.slice(0, -1) : basePath; - const treeEntryKey = Object.keys(state.entries).find( - key => key === path && !state.entries[key].pending, - ); - const treeEntry = state.entries[treeEntryKey]; + }) + .then(() => { + if (basePath) { + const path = basePath.slice(-1) === '/' ? basePath.slice(0, -1) : basePath; + const treeEntryKey = Object.keys(state.entries).find( + key => key === path && !state.entries[key].pending, + ); + const treeEntry = state.entries[treeEntryKey]; - if (treeEntry) { - dispatch('handleTreeEntryAction', treeEntry); + if (treeEntry) { + dispatch('handleTreeEntryAction', treeEntry); + } } - } - }); + }) + .then(() => { + dispatch('getMergeRequestsForBranch', { + projectId, + branchId, + }); + }); }; diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js index de5f6050074..3d83e4a9ba5 100644 --- a/app/assets/javascripts/ide/stores/actions/tree.js +++ b/app/assets/javascripts/ide/stores/actions/tree.js @@ -1,7 +1,8 @@ +import _ from 'underscore'; import { __ } from '../../../locale'; import service from '../../services'; import * as types from '../mutation_types'; -import FilesDecoratorWorker from '../workers/files_decorator_worker'; +import { decorateFiles } from '../../lib/files'; export const toggleTreeOpen = ({ commit }, path) => { commit(types.TOGGLE_TREE_OPEN, path); @@ -32,6 +33,19 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => { dispatch('showTreeEntry', row.path); }; +export const setDirectoryData = ({ state, commit }, { projectId, branchId, treeList }) => { + const selectedTree = state.trees[`${projectId}/${branchId}`]; + + commit(types.SET_DIRECTORY_DATA, { + treePath: `${projectId}/${branchId}`, + data: treeList, + }); + commit(types.TOGGLE_LOADING, { + entry: selectedTree, + forceValue: false, + }); +}; + export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = {}) => new Promise((resolve, reject) => { if ( @@ -45,31 +59,19 @@ export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = service .getFiles(selectedProject.web_url, branchId) .then(({ data }) => { - const worker = new FilesDecoratorWorker(); - worker.addEventListener('message', e => { - const { entries, treeList } = e.data; - const selectedTree = state.trees[`${projectId}/${branchId}`]; - - commit(types.SET_ENTRIES, entries); - commit(types.SET_DIRECTORY_DATA, { - treePath: `${projectId}/${branchId}`, - data: treeList, - }); - commit(types.TOGGLE_LOADING, { - entry: selectedTree, - forceValue: false, - }); - - worker.terminate(); - - resolve(); - }); - - worker.postMessage({ + const { entries, treeList } = decorateFiles({ data, projectId, branchId, }); + + commit(types.SET_ENTRIES, entries); + + // Defer setting the directory data because this triggers some intense rendering. + // The entries is all we need to load the file editor. + _.defer(() => dispatch('setDirectoryData', { projectId, branchId, treeList })); + + resolve(); }) .catch(e => { if (e.response.status === 404) { diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js index 78cdfda74f0..9b9f4b21f1c 100644 --- a/app/assets/javascripts/ide/stores/mutations.js +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -206,19 +206,17 @@ export default { } } }, - [types.RENAME_ENTRY](state, { path, name, entryPath = null }) { + [types.RENAME_ENTRY](state, { path, name, entryPath = null, parentPath }) { const oldEntry = state.entries[entryPath || path]; - const nameRegex = - !entryPath && oldEntry.type === 'blob' - ? new RegExp(`${oldEntry.name}$`) - : new RegExp(`^${path}`); - const newPath = oldEntry.path.replace(nameRegex, name); - const parentPath = oldEntry.parentPath ? oldEntry.parentPath.replace(nameRegex, name) : ''; + const slashedParentPath = parentPath ? `${parentPath}/` : ''; + const newPath = entryPath + ? `${slashedParentPath}${oldEntry.name}` + : `${slashedParentPath}${name}`; state.entries[newPath] = { ...oldEntry, id: newPath, - key: `${name}-${oldEntry.type}-${oldEntry.id}`, + key: `${newPath}-${oldEntry.type}-${oldEntry.id}`, path: newPath, name: entryPath ? oldEntry.name : name, tempFile: true, @@ -228,6 +226,7 @@ export default { parentPath, raw: '', }; + oldEntry.moved = true; oldEntry.movedPath = newPath; @@ -256,6 +255,7 @@ export default { Vue.delete(state.entries, oldEntry.path); } }, + ...projectMutations, ...mergeRequestMutation, ...fileMutations, diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js index 0ede76fd1e0..0b2a18e9c8a 100644 --- a/app/assets/javascripts/ide/stores/utils.js +++ b/app/assets/javascripts/ide/stores/utils.js @@ -75,8 +75,7 @@ export const decorateData = entity => { parentPath = '', } = entity; - return { - ...dataStructure(), + return Object.assign(dataStructure(), { id, projectId, branchId, @@ -97,7 +96,7 @@ export const decorateData = entity => { file_lock, html, parentPath, - }; + }); }; export const findEntry = (tree, type, name, prop = 'name') => diff --git a/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js b/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js deleted file mode 100644 index fa35c215880..00000000000 --- a/app/assets/javascripts/ide/stores/workers/files_decorator_worker.js +++ /dev/null @@ -1,100 +0,0 @@ -import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils'; -import { decorateData, sortTree } from '../utils'; - -// eslint-disable-next-line no-restricted-globals -self.addEventListener('message', e => { - const { data, projectId, branchId, tempFile = false, content = '', base64 = false } = e.data; - - const treeList = []; - let file; - let parentPath; - const entries = data.reduce((acc, path) => { - const pathSplit = path.split('/'); - const blobName = pathSplit.pop().trim(); - - if (pathSplit.length > 0) { - pathSplit.reduce((pathAcc, folderName) => { - const parentFolder = acc[pathAcc[pathAcc.length - 1]]; - const folderPath = `${parentFolder ? `${parentFolder.path}/` : ''}${folderName}`; - const foundEntry = acc[folderPath]; - - if (!foundEntry) { - parentPath = parentFolder ? parentFolder.path : null; - - const tree = decorateData({ - projectId, - branchId, - id: folderPath, - name: folderName, - path: folderPath, - url: `/${projectId}/tree/${branchId}/-/${folderPath}/`, - type: 'tree', - parentTreeUrl: parentFolder ? parentFolder.url : `/${projectId}/tree/${branchId}/`, - tempFile, - changed: tempFile, - opened: tempFile, - parentPath, - }); - - Object.assign(acc, { - [folderPath]: tree, - }); - - if (parentFolder) { - parentFolder.tree.push(tree); - } else { - treeList.push(tree); - } - - pathAcc.push(tree.path); - } else { - pathAcc.push(foundEntry.path); - } - - return pathAcc; - }, []); - } - - if (blobName !== '') { - const fileFolder = acc[pathSplit.join('/')]; - parentPath = fileFolder ? fileFolder.path : null; - - file = decorateData({ - projectId, - branchId, - id: path, - name: blobName, - path, - url: `/${projectId}/blob/${branchId}/-/${path}`, - type: 'blob', - parentTreeUrl: fileFolder ? fileFolder.url : `/${projectId}/blob/${branchId}`, - tempFile, - changed: tempFile, - content, - base64, - previewMode: viewerInformationForPath(blobName), - parentPath, - }); - - Object.assign(acc, { - [path]: file, - }); - - if (fileFolder) { - fileFolder.tree.push(file); - } else { - treeList.push(file); - } - } - - return acc; - }, {}); - - // eslint-disable-next-line no-restricted-globals - self.postMessage({ - entries, - treeList: sortTree(treeList), - file, - parentPath, - }); -}); diff --git a/app/assets/javascripts/import_projects/index.js b/app/assets/javascripts/import_projects/index.js index 5c77484aee1..2d99d716609 100644 --- a/app/assets/javascripts/import_projects/index.js +++ b/app/assets/javascripts/import_projects/index.js @@ -3,7 +3,7 @@ import { mapActions } from 'vuex'; import Translate from '../vue_shared/translate'; import ImportProjectsTable from './components/import_projects_table.vue'; import { parseBoolean } from '../lib/utils/common_utils'; -import store from './store'; +import createStore from './store'; Vue.use(Translate); @@ -20,6 +20,7 @@ export default function mountImportProjectsTable(mountElement) { ciCdOnly, } = mountElement.dataset; + const store = createStore(); return new Vue({ el: mountElement, store, diff --git a/app/assets/javascripts/import_projects/store/index.js b/app/assets/javascripts/import_projects/store/index.js index 6ac9bfd8189..f666e2ebf33 100644 --- a/app/assets/javascripts/import_projects/store/index.js +++ b/app/assets/javascripts/import_projects/store/index.js @@ -7,9 +7,10 @@ import mutations from './mutations'; Vue.use(Vuex); -export default new Vuex.Store({ - state: state(), - actions, - mutations, - getters, -}); +export default () => + new Vuex.Store({ + state: state(), + actions, + mutations, + getters, + }); diff --git a/app/assets/javascripts/jobs/components/job_app.vue b/app/assets/javascripts/jobs/components/job_app.vue index d473d6a482d..dbadd224251 100644 --- a/app/assets/javascripts/jobs/components/job_app.vue +++ b/app/assets/javascripts/jobs/components/job_app.vue @@ -34,6 +34,7 @@ export default { StuckBlock, Sidebar, GlLoadingIcon, + SharedRunner: () => import('ee_component/jobs/components/shared_runner_limit_block.vue'), }, mixins: [delayedJobMixin], props: { @@ -84,6 +85,7 @@ export default { 'shouldRenderCalloutMessage', 'shouldRenderTriggeredLabel', 'hasEnvironment', + 'shouldRenderSharedRunnerLimitWarning', 'hasTrace', 'emptyStateIllustration', 'isScrollingDown', @@ -221,6 +223,14 @@ export default { :runners-path="runnerSettingsUrl" /> + <shared-runner + v-if="shouldRenderSharedRunnerLimitWarning" + class="js-shared-runner-limit" + :quota-used="job.runners.quota.used" + :quota-limit="job.runners.quota.limit" + :runners-path="runnerHelpUrl" + /> + <environments-block v-if="hasEnvironment" class="js-job-environment" diff --git a/app/assets/javascripts/jobs/store/getters.js b/app/assets/javascripts/jobs/store/getters.js index 98911717381..73c1cbc3a99 100644 --- a/app/assets/javascripts/jobs/store/getters.js +++ b/app/assets/javascripts/jobs/store/getters.js @@ -28,6 +28,17 @@ export const emptyStateIllustration = state => export const emptyStateAction = state => (state.job && state.job.status && state.job.status.action) || null; +/** + * Shared runners limit is only rendered when + * used quota is bigger or equal than the limit + * + * @returns {Boolean} + */ +export const shouldRenderSharedRunnerLimitWarning = state => + !_.isEmpty(state.job.runners) && + !_.isEmpty(state.job.runners.quota) && + state.job.runners.quota.used >= state.job.runners.quota.limit; + export const isScrollingDown = state => isScrolledToBottom() && !state.isTraceComplete; export const hasRunnersForProject = state => diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index f7a611fbca0..cca4927c115 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -199,8 +199,8 @@ export default class LabelsSelect { .catch(() => flash(__('Error fetching labels.'))); }, renderRow: function(label, instance) { - var $a, - $li, + var linkEl, + listItemEl, color, colorEl, indeterminate, @@ -209,12 +209,11 @@ export default class LabelsSelect { spacing, i, marked, - dropdownName, dropdownValue; - $li = $('<li>'); - $a = $('<a href="#">'); + selectedClass = []; removesAll = label.id <= 0 || label.id == null; + if ($dropdown.hasClass('js-filter-bulk-update')) { indeterminate = $dropdown.data('indeterminate') || []; marked = $dropdown.data('marked') || []; @@ -233,7 +232,6 @@ export default class LabelsSelect { } } else { if (this.id(label)) { - dropdownName = $dropdown.data('fieldName'); dropdownValue = this.id(label) .toString() .replace(/'/g, "\\'"); @@ -241,7 +239,7 @@ export default class LabelsSelect { if ( $form.find( "input[type='hidden'][name='" + - dropdownName + + this.fieldName + "'][value='" + dropdownValue + "']", @@ -251,24 +249,34 @@ export default class LabelsSelect { } } - if ($dropdown.hasClass('js-multiselect') && removesAll) { + if (this.multiSelect && removesAll) { selectedClass.push('dropdown-clear-active'); } } + if (label.color) { colorEl = "<span class='dropdown-label-box' style='background: " + label.color + "'></span>"; } else { colorEl = ''; } + + linkEl = document.createElement('a'); + linkEl.href = '#'; + // We need to identify which items are actually labels if (label.id) { selectedClass.push('label-item'); - $a.attr('data-label-id', label.id); + linkEl.dataset.labelId = label.id; } - $a.addClass(selectedClass.join(' ')).html(`${colorEl} ${_.escape(label.title)}`); - // Return generated html - return $li.html($a).prop('outerHTML'); + + linkEl.className = selectedClass.join(' '); + linkEl.innerHTML = `${colorEl} ${_.escape(label.title)}`; + + listItemEl = document.createElement('li'); + listItemEl.appendChild(linkEl); + + return listItemEl; }, search: { fields: ['title'], diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index a73cdb73690..1af6b63efc9 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -708,6 +708,14 @@ export const NavigationType = { TYPE_RESERVED: 255, }; +/** + * Returns the value of `gon.ee` + * Used to check if it's the EE codebase or the CE one. + * + * @returns Boolean + */ +export const isEE = () => window.gon && window.gon.ee; + window.gl = window.gl || {}; window.gl.utils = { ...(window.gl.utils || {}), diff --git a/app/assets/javascripts/lib/utils/http_status.js b/app/assets/javascripts/lib/utils/http_status.js index 14c02218990..37ad1676f7a 100644 --- a/app/assets/javascripts/lib/utils/http_status.js +++ b/app/assets/javascripts/lib/utils/http_status.js @@ -16,6 +16,7 @@ const httpStatusCodes = { IM_USED: 226, MULTIPLE_CHOICES: 300, BAD_REQUEST: 400, + UNAUTHORIZED: 401, FORBIDDEN: 403, NOT_FOUND: 404, UNPROCESSABLE_ENTITY: 422, diff --git a/app/assets/javascripts/lib/utils/number_utils.js b/app/assets/javascripts/lib/utils/number_utils.js index 2ccc51c35f7..19c4de6083d 100644 --- a/app/assets/javascripts/lib/utils/number_utils.js +++ b/app/assets/javascripts/lib/utils/number_utils.js @@ -80,3 +80,22 @@ export function numberToHumanSize(size) { } return `${bytesToGiB(size).toFixed(2)} GiB`; } + +/** + * A simple method that returns the value of a + b + * It seems unessesary, but when combined with a reducer it + * adds up all the values in an array. + * + * e.g. `[1, 2, 3, 4, 5].reduce(sum) // => 15` + * + * @param {Float} a + * @param {Float} b + * @example + * // return 15 + * [1, 2, 3, 4, 5].reduce(sum); + * + * // returns 6 + * Object.values([{a: 1, b: 2, c: 3].reduce(sum); + * @returns {Float} The summed value + */ +export const sum = (a = 0, b = 0) => a + b; diff --git a/app/assets/javascripts/members.js b/app/assets/javascripts/members.js index bd263c75a3d..af2697444f2 100644 --- a/app/assets/javascripts/members.js +++ b/app/assets/javascripts/members.js @@ -16,25 +16,33 @@ export default class Members { gl.utils.disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change'); } + dropdownClicked(options) { + this.formSubmit(null, options.$el); + } + + // eslint-disable-next-line class-methods-use-this + dropdownToggleLabel(selected, $el) { + return $el.text(); + } + + // eslint-disable-next-line class-methods-use-this + dropdownIsSelectable(selected, $el) { + return !$el.hasClass('is-active'); + } + initGLDropdown() { $('.js-member-permissions-dropdown').each((i, btn) => { const $btn = $(btn); $btn.glDropdown({ selectable: true, - isSelectable(selected, $el) { - return !$el.hasClass('is-active'); - }, + isSelectable: (selected, $el) => this.dropdownIsSelectable(selected, $el), fieldName: $btn.data('fieldName'), id(selected, $el) { return $el.data('id'); }, - toggleLabel(selected, $el) { - return $el.text(); - }, - clicked: options => { - this.formSubmit(null, options.$el); - }, + toggleLabel: (selected, $el) => this.dropdownToggleLabel(selected, $el, $btn), + clicked: options => this.dropdownClicked(options), }); }); } @@ -55,6 +63,7 @@ export default class Members { $toggle.enable(); $dateInput.enable(); } + // eslint-disable-next-line class-methods-use-this getMemberListItems($el) { const $memberListItem = $el.is('.member') ? $el : $(`#${$el.data('elId')}`); diff --git a/app/assets/javascripts/monitoring/components/charts/area.vue b/app/assets/javascripts/monitoring/components/charts/area.vue index 9e031b03579..41783d311ef 100644 --- a/app/assets/javascripts/monitoring/components/charts/area.vue +++ b/app/assets/javascripts/monitoring/components/charts/area.vue @@ -4,6 +4,7 @@ import dateFormat from 'dateformat'; import { debounceByAnimationFrame } from '~/lib/utils/common_utils'; import { getSvgIconPathContent } from '~/lib/utils/icon_utils'; import Icon from '~/vue_shared/components/icon.vue'; +import { chartHeight, graphTypes, lineTypes } from '../../constants'; let debouncedResize; @@ -19,7 +20,6 @@ export default { required: true, validator(data) { return ( - data.queries && Array.isArray(data.queries) && data.queries.filter(query => { if (Array.isArray(query.result)) { @@ -51,21 +51,44 @@ export default { return { tooltip: { title: '', - content: '', + content: [], isDeployment: false, sha: '', }, width: 0, - height: 0, - scatterSymbol: undefined, + height: chartHeight, + svgs: {}, + primaryColor: null, }; }, computed: { chartData() { - return this.graphData.queries.reduce((accumulator, query) => { - accumulator[query.unit] = query.result.reduce((acc, res) => acc.concat(res.values), []); - return accumulator; - }, {}); + return this.graphData.queries.map(query => { + const { appearance } = query; + const lineType = + appearance && appearance.line && appearance.line.type + ? appearance.line.type + : lineTypes.default; + const lineColor = lineType === lineTypes.threshold ? this.primaryColor : undefined; + + return { + name: this.formatLegendLabel(query), + data: this.concatenateResults(query.result), + lineStyle: { + type: lineType, + color: lineColor, + }, + itemStyle: { + color: lineColor, + }, + areaStyle: { + opacity: + appearance && appearance.area && typeof appearance.area.opacity === 'number' + ? appearance.area.opacity + : undefined, + }, + }; + }); }, chartOptions() { return { @@ -78,28 +101,25 @@ export default { axisPointer: { snap: true, }, - nameTextStyle: { - padding: [18, 0, 0, 0], - }, }, yAxis: { name: this.yAxisLabel, axisLabel: { formatter: value => value.toFixed(3), }, - nameTextStyle: { - padding: [0, 0, 36, 0], - }, - }, - legend: { - formatter: this.xAxisLabel, }, series: this.scatterSeries, + dataZoom: this.dataZoomConfig, }; }, + dataZoomConfig() { + const handleIcon = this.svgs['scroll-handle']; + + return handleIcon ? { handleIcon } : {}; + }, earliestDatapoint() { - return Object.values(this.chartData).reduce((acc, data) => { - const [[timestamp]] = data.sort(([a], [b]) => { + return this.chartData.reduce((acc, series) => { + const [[timestamp]] = series.data.sort(([a], [b]) => { if (a < b) { return -1; } @@ -129,15 +149,15 @@ export default { }, scatterSeries() { return { - type: 'scatter', + type: graphTypes.deploymentData, data: this.recentDeployments.map(deployment => [deployment.createdAt, 0]), - symbol: this.scatterSymbol, + symbol: this.svgs.rocket, symbolSize: 14, + itemStyle: { + color: this.primaryColor, + }, }; }, - xAxisLabel() { - return this.graphData.queries.map(query => query.label).join(', '); - }, yAxisLabel() { return `${this.graphData.y_label}`; }, @@ -151,35 +171,54 @@ export default { created() { debouncedResize = debounceByAnimationFrame(this.onResize); window.addEventListener('resize', debouncedResize); - this.getScatterSymbol(); + this.setSvg('rocket'); + this.setSvg('scroll-handle'); }, methods: { + concatenateResults(results) { + return results.reduce((acc, result) => acc.concat(result.values), []); + }, + formatLegendLabel(query) { + return `${query.label}`; + }, formatTooltipText(params) { - const [seriesData] = params.seriesData; - this.tooltip.isDeployment = seriesData.componentSubType === 'scatter'; this.tooltip.title = dateFormat(params.value, 'dd mmm yyyy, h:MMTT'); - if (this.tooltip.isDeployment) { - const [deploy] = this.recentDeployments.filter( - deployment => deployment.createdAt === seriesData.value[0], - ); - this.tooltip.sha = deploy.sha.substring(0, 8); - } else { - this.tooltip.content = `${this.yAxisLabel} ${seriesData.value[1].toFixed(3)}`; - } + this.tooltip.content = []; + params.seriesData.forEach(seriesData => { + if (seriesData.componentSubType === graphTypes.deploymentData) { + this.tooltip.isDeployment = true; + const [deploy] = this.recentDeployments.filter( + deployment => deployment.createdAt === seriesData.value[0], + ); + this.tooltip.sha = deploy.sha.substring(0, 8); + } else { + const { seriesName } = seriesData; + // seriesData.value contains the chart's [x, y] value pair + // seriesData.value[1] is threfore the chart y value + const value = seriesData.value[1].toFixed(3); + + this.tooltip.content.push({ + name: seriesName, + value, + }); + } + }); }, - getScatterSymbol() { - getSvgIconPathContent('rocket') + setSvg(name) { + getSvgIconPathContent(name) .then(path => { if (path) { - this.scatterSymbol = `path://${path}`; + this.$set(this.svgs, name, `path://${path}`); } }) .catch(() => {}); }, + onChartUpdated(chart) { + [this.primaryColor] = chart.getOption().color; + }, onResize() { - const { width, height } = this.$refs.areaChart.$el.getBoundingClientRect(); + const { width } = this.$refs.areaChart.$el.getBoundingClientRect(); this.width = width; - this.height = height; }, }, }; @@ -200,6 +239,7 @@ export default { :thresholds="alertData" :width="width" :height="height" + @updated="onChartUpdated" > <template slot="tooltipTitle"> <div v-if="tooltip.isDeployment"> @@ -213,7 +253,13 @@ export default { {{ tooltip.sha }} </div> <template v-else> - {{ tooltip.content }} + <div + v-for="(content, key) in tooltip.content" + :key="key" + class="d-flex justify-content-between" + > + {{ content.name }} {{ content.value }} + </div> </template> </template> </gl-area-chart> diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js new file mode 100644 index 00000000000..869173b6572 --- /dev/null +++ b/app/assets/javascripts/monitoring/constants.js @@ -0,0 +1,10 @@ +export const chartHeight = 300; + +export const graphTypes = { + deploymentData: 'scatter', +}; + +export const lineTypes = { + default: 'solid', + threshold: 'dashed', +}; diff --git a/app/assets/javascripts/mr_notes/index.js b/app/assets/javascripts/mr_notes/index.js index 9e99aa4f724..8eccba07c38 100644 --- a/app/assets/javascripts/mr_notes/index.js +++ b/app/assets/javascripts/mr_notes/index.js @@ -1,11 +1,9 @@ -import $ from 'jquery'; import Vue from 'vue'; -import { mapActions, mapState, mapGetters } from 'vuex'; +import store from 'ee_else_ce/mr_notes/stores'; +import initNotesApp from './init_notes'; import initDiffsApp from '../diffs'; -import notesApp from '../notes/components/notes_app.vue'; import discussionCounter from '../notes/components/discussion_counter.vue'; import initDiscussionFilters from '../notes/discussion_filters'; -import store from './stores'; import MergeRequest from '../merge_request'; import { resetServiceWorkersPublicPath } from '../lib/utils/webpack'; @@ -18,68 +16,7 @@ export default function initMrNotes() { action: mrShowNode.dataset.mrAction, }); - // eslint-disable-next-line no-new - new Vue({ - el: '#js-vue-mr-discussions', - name: 'MergeRequestDiscussions', - components: { - notesApp, - }, - store, - data() { - const notesDataset = document.getElementById('js-vue-mr-discussions').dataset; - const noteableData = JSON.parse(notesDataset.noteableData); - noteableData.noteableType = notesDataset.noteableType; - noteableData.targetType = notesDataset.targetType; - - return { - noteableData, - currentUserData: JSON.parse(notesDataset.currentUserData), - notesData: JSON.parse(notesDataset.notesData), - helpPagePath: notesDataset.helpPagePath, - }; - }, - computed: { - ...mapGetters(['discussionTabCounter']), - ...mapState({ - activeTab: state => state.page.activeTab, - }), - }, - watch: { - discussionTabCounter() { - this.updateDiscussionTabCounter(); - }, - }, - created() { - this.setActiveTab(window.mrTabs.getCurrentAction()); - }, - mounted() { - this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge'); - $(document).on('visibilitychange', this.updateDiscussionTabCounter); - window.mrTabs.eventHub.$on('MergeRequestTabChange', this.setActiveTab); - }, - beforeDestroy() { - $(document).off('visibilitychange', this.updateDiscussionTabCounter); - window.mrTabs.eventHub.$off('MergeRequestTabChange', this.setActiveTab); - }, - methods: { - ...mapActions(['setActiveTab']), - updateDiscussionTabCounter() { - this.notesCountBadge.text(this.discussionTabCounter); - }, - }, - render(createElement) { - return createElement('notes-app', { - props: { - noteableData: this.noteableData, - notesData: this.notesData, - userData: this.currentUserData, - shouldShow: this.activeTab === 'show', - helpPagePath: this.helpPagePath, - }, - }); - }, - }); + initNotesApp(); // eslint-disable-next-line no-new new Vue({ diff --git a/app/assets/javascripts/mr_notes/init_notes.js b/app/assets/javascripts/mr_notes/init_notes.js new file mode 100644 index 00000000000..842a209a545 --- /dev/null +++ b/app/assets/javascripts/mr_notes/init_notes.js @@ -0,0 +1,70 @@ +import $ from 'jquery'; +import Vue from 'vue'; +import { mapActions, mapState, mapGetters } from 'vuex'; +import store from 'ee_else_ce/mr_notes/stores'; +import notesApp from '../notes/components/notes_app.vue'; + +export default () => { + // eslint-disable-next-line no-new + new Vue({ + el: '#js-vue-mr-discussions', + name: 'MergeRequestDiscussions', + components: { + notesApp, + }, + store, + data() { + const notesDataset = document.getElementById('js-vue-mr-discussions').dataset; + const noteableData = JSON.parse(notesDataset.noteableData); + noteableData.noteableType = notesDataset.noteableType; + noteableData.targetType = notesDataset.targetType; + + return { + noteableData, + currentUserData: JSON.parse(notesDataset.currentUserData), + notesData: JSON.parse(notesDataset.notesData), + helpPagePath: notesDataset.helpPagePath, + }; + }, + computed: { + ...mapGetters(['discussionTabCounter']), + ...mapState({ + activeTab: state => state.page.activeTab, + }), + }, + watch: { + discussionTabCounter() { + this.updateDiscussionTabCounter(); + }, + }, + created() { + this.setActiveTab(window.mrTabs.getCurrentAction()); + }, + mounted() { + this.notesCountBadge = $('.issuable-details').find('.notes-tab .badge'); + $(document).on('visibilitychange', this.updateDiscussionTabCounter); + window.mrTabs.eventHub.$on('MergeRequestTabChange', this.setActiveTab); + }, + beforeDestroy() { + $(document).off('visibilitychange', this.updateDiscussionTabCounter); + window.mrTabs.eventHub.$off('MergeRequestTabChange', this.setActiveTab); + }, + methods: { + ...mapActions(['setActiveTab']), + updateDiscussionTabCounter() { + this.notesCountBadge.text(this.discussionTabCounter); + }, + }, + render(createElement) { + return createElement('notes-app', { + props: { + noteableData: this.noteableData, + notesData: this.notesData, + userData: this.currentUserData, + shouldShow: this.activeTab === 'show', + helpPagePath: this.helpPagePath, + }, + }); + }, + }); +}; diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index 7b39901024d..68b753a4abf 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -69,7 +69,7 @@ export default { type="button" @click="handleToggle" > - <i :class="toggleChevronClass" class="fa" aria-hidden="true"> </i> + <i :class="toggleChevronClass" class="fa" aria-hidden="true"></i> {{ __('Toggle discussion') }} </button> </div> @@ -81,19 +81,18 @@ export default { :data-user-id="author.id" :data-username="author.username" > + <slot name="note-header-info"></slot> <span class="note-header-author-name">{{ author.name }}</span> <span v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span> - <span class="note-headline-light"> @{{ author.username }} </span> + <span class="note-headline-light">@{{ author.username }}</span> </a> - <span v-else> {{ __('A deleted user') }} </span> + <span v-else>{{ __('A deleted user') }}</span> <span class="note-headline-light"> <span class="note-headline-meta"> <span class="system-note-message"> <slot></slot> </span> <template v-if="createdAt"> <span class="system-note-separator"> - <template v-if="actionText"> - {{ actionText }} - </template> + <template v-if="actionText">{{ actionText }}</template> </span> <a :href="noteTimestampLink" @@ -107,8 +106,7 @@ export default { class="fa fa-spinner fa-spin editing-spinner" aria-label="Comment is being updated" aria-hidden="true" - > - </i> + ></i> </span> </span> </div> diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index 3894dc8c677..fc51998935d 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -6,6 +6,7 @@ import { truncateSha } from '~/lib/utils/text_utility'; import { s__, __, sprintf } from '~/locale'; import systemNote from '~/vue_shared/components/notes/system_note.vue'; import icon from '~/vue_shared/components/icon.vue'; +import diffLineNoteFormMixin from 'ee_else_ce/notes/mixins/diff_line_note_form'; import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue'; import Flash from '../../flash'; import { SYSTEM_NOTE } from '../constants'; @@ -47,12 +48,13 @@ export default { placeholderSystemNote, ResolveWithIssueButton, systemNote, + DraftNote: () => import('ee_component/batch_comments/components/draft_note.vue'), TimelineEntryItem, }, directives: { GlTooltip: GlTooltipDirective, }, - mixins: [autosave, noteable, resolvable, discussionNavigation], + mixins: [autosave, noteable, resolvable, discussionNavigation, diffLineNoteFormMixin], props: { discussion: { type: Object, @@ -510,6 +512,7 @@ Please check your network connection and try again.`; :is-editing="false" :line="diffLine" save-button-title="Comment" + @handleFormUpdateAddToReview="addReplyToReview" @handleFormUpdate="saveReply" @cancelForm="cancelReplyForm" /> diff --git a/app/assets/javascripts/notes/mixins/diff_line_note_form.js b/app/assets/javascripts/notes/mixins/diff_line_note_form.js new file mode 100644 index 00000000000..188556e8921 --- /dev/null +++ b/app/assets/javascripts/notes/mixins/diff_line_note_form.js @@ -0,0 +1,10 @@ +export default { + computed: { + draftForDiscussion: () => () => ({}), + }, + methods: { + showDraft: () => false, + addReplyToReview: () => {}, + addToReview: () => {}, + }, +}; diff --git a/app/assets/javascripts/notes/mixins/resolvable.js b/app/assets/javascripts/notes/mixins/resolvable.js index 8edf3d088bb..2329727bca2 100644 --- a/app/assets/javascripts/notes/mixins/resolvable.js +++ b/app/assets/javascripts/notes/mixins/resolvable.js @@ -31,6 +31,10 @@ export default { }, methods: { resolveHandler(resolvedState = false) { + if (this.note && this.note.isDraft) { + return this.$emit('toggleResolveStatus'); + } + this.isResolving = true; const isResolved = this.discussionResolved || resolvedState; const discussion = this.resolveAsThread; diff --git a/app/assets/javascripts/notes/stores/getters.js b/app/assets/javascripts/notes/stores/getters.js index 5026c13dab5..fcc8889b0c7 100644 --- a/app/assets/javascripts/notes/stores/getters.js +++ b/app/assets/javascripts/notes/stores/getters.js @@ -191,6 +191,9 @@ export const firstUnresolvedDiscussionId = (state, getters) => diffOrder => { return getters.unresolvedDiscussionsIdsByDate[0]; }; +export const getDiscussion = state => discussionId => + state.discussions.find(discussion => discussion.id === discussionId); + export const commentsDisabled = state => state.commentsDisabled; // prevent babel-plugin-rewire from generating an invalid default during karma tests diff --git a/app/assets/javascripts/notes/stores/mutations.js b/app/assets/javascripts/notes/stores/mutations.js index ae6f8b7790a..fa44ef2d057 100644 --- a/app/assets/javascripts/notes/stores/mutations.js +++ b/app/assets/javascripts/notes/stores/mutations.js @@ -193,6 +193,10 @@ export default { const noteObj = utils.findNoteObjectById(state.discussions, note.discussion_id); if (noteObj.individual_note) { + if (note.type === constants.DISCUSSION_NOTE) { + noteObj.individual_note = false; + } + noteObj.notes.splice(0, 1, note); } else { const comment = utils.findNoteObjectById(noteObj.notes, note.id); diff --git a/app/assets/javascripts/pages/groups/clusters/index/index.js b/app/assets/javascripts/pages/groups/clusters/index/index.js index 21efc4f6d00..30d519d0e37 100644 --- a/app/assets/javascripts/pages/groups/clusters/index/index.js +++ b/app/assets/javascripts/pages/groups/clusters/index/index.js @@ -2,6 +2,5 @@ import PersistentUserCallout from '~/persistent_user_callout'; document.addEventListener('DOMContentLoaded', () => { const callout = document.querySelector('.gcp-signup-offer'); - - if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new + PersistentUserCallout.factory(callout); }); diff --git a/app/assets/javascripts/pages/groups/group_members/index/index.js b/app/assets/javascripts/pages/groups/group_members/index/index.js index c22a164cd4e..e4f4c3b574e 100644 --- a/app/assets/javascripts/pages/groups/group_members/index/index.js +++ b/app/assets/javascripts/pages/groups/group_members/index/index.js @@ -1,7 +1,7 @@ /* eslint-disable no-new */ import memberExpirationDate from '~/member_expiration_date'; -import Members from '~/members'; +import Members from 'ee_else_ce/members'; import UsersSelect from '~/users_select'; document.addEventListener('DOMContentLoaded', () => { diff --git a/app/assets/javascripts/pages/groups/index.js b/app/assets/javascripts/pages/groups/index.js index a63a0dbc6b1..451be6497de 100644 --- a/app/assets/javascripts/pages/groups/index.js +++ b/app/assets/javascripts/pages/groups/index.js @@ -3,8 +3,7 @@ import initGkeDropdowns from '~/projects/gke_cluster_dropdowns'; function initGcpSignupCallout() { const callout = document.querySelector('.gcp-signup-offer'); - - if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new + PersistentUserCallout.factory(callout); } document.addEventListener('DOMContentLoaded', () => { diff --git a/app/assets/javascripts/pages/profiles/show/index.js b/app/assets/javascripts/pages/profiles/show/index.js index 0dd0d5336fc..c9d3bbc8c39 100644 --- a/app/assets/javascripts/pages/profiles/show/index.js +++ b/app/assets/javascripts/pages/profiles/show/index.js @@ -56,30 +56,34 @@ document.addEventListener('DOMContentLoaded', () => { import(/* webpackChunkName: 'emoji' */ '~/emoji') .then(Emoji => { - const emojiMenu = new EmojiMenu( - Emoji, - toggleEmojiMenuButtonSelector, - 'js-status-emoji-menu', - selectEmojiCallback, - ); - emojiMenu.bindEvents(); + Emoji.initEmojiMap() + .then(() => { + const emojiMenu = new EmojiMenu( + Emoji, + toggleEmojiMenuButtonSelector, + 'js-status-emoji-menu', + selectEmojiCallback, + ); + emojiMenu.bindEvents(); - const defaultEmojiTag = Emoji.glEmojiTag(defaultStatusEmoji); - statusMessageField.addEventListener('input', () => { - const hasStatusMessage = statusMessageField.value.trim() !== ''; - const statusEmoji = findStatusEmoji(); - if (hasStatusMessage && statusEmoji) { - return; - } + const defaultEmojiTag = Emoji.glEmojiTag(defaultStatusEmoji); + statusMessageField.addEventListener('input', () => { + const hasStatusMessage = statusMessageField.value.trim() !== ''; + const statusEmoji = findStatusEmoji(); + if (hasStatusMessage && statusEmoji) { + return; + } - if (hasStatusMessage) { - toggleNoEmojiPlaceholder(false); - toggleEmojiMenuButton.innerHTML += defaultEmojiTag; - } else if (statusEmoji.dataset.name === defaultStatusEmoji) { - toggleNoEmojiPlaceholder(true); - removeStatusEmoji(); - } - }); + if (hasStatusMessage) { + toggleNoEmojiPlaceholder(false); + toggleEmojiMenuButton.innerHTML += defaultEmojiTag; + } else if (statusEmoji.dataset.name === defaultStatusEmoji) { + toggleNoEmojiPlaceholder(true); + removeStatusEmoji(); + } + }); + }) + .catch(() => createFlash('Failed to load emoji list.')); }) .catch(() => createFlash('Failed to load emoji list.')); }); diff --git a/app/assets/javascripts/pages/projects/clusters/index/index.js b/app/assets/javascripts/pages/projects/clusters/index/index.js index 21efc4f6d00..30d519d0e37 100644 --- a/app/assets/javascripts/pages/projects/clusters/index/index.js +++ b/app/assets/javascripts/pages/projects/clusters/index/index.js @@ -2,6 +2,5 @@ import PersistentUserCallout from '~/persistent_user_callout'; document.addEventListener('DOMContentLoaded', () => { const callout = document.querySelector('.gcp-signup-offer'); - - if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new + PersistentUserCallout.factory(callout); }); diff --git a/app/assets/javascripts/pages/projects/index.js b/app/assets/javascripts/pages/projects/index.js index b0345b4e50d..d4bd02c14e9 100644 --- a/app/assets/javascripts/pages/projects/index.js +++ b/app/assets/javascripts/pages/projects/index.js @@ -13,7 +13,7 @@ document.addEventListener('DOMContentLoaded', () => { if (newClusterViews.indexOf(page) > -1) { const callout = document.querySelector('.gcp-signup-offer'); - if (callout) new PersistentUserCallout(callout); // eslint-disable-line no-new + PersistentUserCallout.factory(callout); initGkeDropdowns(); } diff --git a/app/assets/javascripts/pages/projects/issues/edit/index.js b/app/assets/javascripts/pages/projects/issues/edit/index.js index ffc84dc106b..aecc6484b26 100644 --- a/app/assets/javascripts/pages/projects/issues/edit/index.js +++ b/app/assets/javascripts/pages/projects/issues/edit/index.js @@ -1,3 +1,3 @@ -import initForm from '../form'; +import initForm from 'ee_else_ce/pages/projects/issues/form'; document.addEventListener('DOMContentLoaded', initForm); diff --git a/app/assets/javascripts/pages/projects/issues/form.js b/app/assets/javascripts/pages/projects/issues/form.js index f99023ad8e7..941c4552579 100644 --- a/app/assets/javascripts/pages/projects/issues/form.js +++ b/app/assets/javascripts/pages/projects/issues/form.js @@ -2,7 +2,7 @@ import $ from 'jquery'; import GLForm from '~/gl_form'; -import IssuableForm from '~/issuable_form'; +import IssuableForm from 'ee_else_ce/issuable_form'; import LabelsSelect from '~/labels_select'; import MilestoneSelect from '~/milestone_select'; import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; diff --git a/app/assets/javascripts/pages/projects/issues/new/index.js b/app/assets/javascripts/pages/projects/issues/new/index.js index ffc84dc106b..aecc6484b26 100644 --- a/app/assets/javascripts/pages/projects/issues/new/index.js +++ b/app/assets/javascripts/pages/projects/issues/new/index.js @@ -1,3 +1,3 @@ -import initForm from '../form'; +import initForm from 'ee_else_ce/pages/projects/issues/form'; document.addEventListener('DOMContentLoaded', initForm); diff --git a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js index e3971618da5..8f0dc8554e2 100644 --- a/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js +++ b/app/assets/javascripts/pages/projects/merge_requests/init_merge_request.js @@ -4,7 +4,7 @@ import $ from 'jquery'; import Diff from '~/diff'; import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation'; import GLForm from '~/gl_form'; -import IssuableForm from '~/issuable_form'; +import IssuableForm from 'ee_else_ce/issuable_form'; import LabelsSelect from '~/labels_select'; import MilestoneSelect from '~/milestone_select'; import IssuableTemplateSelectors from '~/templates/issuable_template_selectors'; diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js index adbe744290a..f39765818e7 100644 --- a/app/assets/javascripts/pages/projects/project_members/index.js +++ b/app/assets/javascripts/pages/projects/project_members/index.js @@ -1,7 +1,7 @@ +import Members from 'ee_else_ce/members'; import memberExpirationDate from '../../../member_expiration_date'; import UsersSelect from '../../../users_select'; import groupsSelect from '../../../groups_select'; -import Members from '../../../members'; document.addEventListener('DOMContentLoaded', () => { memberExpirationDate('.js-access-expiration-date-groups'); diff --git a/app/assets/javascripts/pages/projects/settings/operations/show/index.js b/app/assets/javascripts/pages/projects/settings/operations/show/index.js new file mode 100644 index 00000000000..73c745179be --- /dev/null +++ b/app/assets/javascripts/pages/projects/settings/operations/show/index.js @@ -0,0 +1,5 @@ +import mountErrorTrackingForm from '~/error_tracking_settings'; + +document.addEventListener('DOMContentLoaded', () => { + mountErrorTrackingForm(); +}); diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js index afa099d0e0b..61204c37307 100644 --- a/app/assets/javascripts/pages/users/activity_calendar.js +++ b/app/assets/javascripts/pages/users/activity_calendar.js @@ -10,6 +10,12 @@ import { __ } from '~/locale'; const d3 = { select, scaleLinear, scaleThreshold }; +const firstDayOfWeekChoices = Object.freeze({ + sunday: 0, + monday: 1, + saturday: 6, +}); + const LOADING_HTML = ` <div class="text-center"> <i class="fa fa-spinner fa-spin user-calendar-activities-loading"></i> @@ -49,7 +55,7 @@ export default class ActivityCalendar { timestamps, calendarActivitiesPath, utcOffset = 0, - firstDayOfWeek = 0, + firstDayOfWeek = firstDayOfWeekChoices.sunday, monthsAgo = 12, ) { this.calendarActivitiesPath = calendarActivitiesPath; @@ -206,11 +212,16 @@ export default class ActivityCalendar { }, ]; - if (this.firstDayOfWeek === 1) { + if (this.firstDayOfWeek === firstDayOfWeekChoices.monday) { days.push({ text: 'S', y: 29 + this.dayYPos(7), }); + } else if (this.firstDayOfWeek === firstDayOfWeekChoices.saturday) { + days.push({ + text: 'S', + y: 29 + this.dayYPos(6), + }); } this.svg diff --git a/app/assets/javascripts/persistent_user_callout.js b/app/assets/javascripts/persistent_user_callout.js index 1e34e74a152..4a08e158f6b 100644 --- a/app/assets/javascripts/persistent_user_callout.js +++ b/app/assets/javascripts/persistent_user_callout.js @@ -31,4 +31,12 @@ export default class PersistentUserCallout { Flash(__('An error occurred while dismissing the alert. Refresh the page and try again.')); }); } + + static factory(container) { + if (!container) { + return undefined; + } + + return new PersistentUserCallout(container); + } } diff --git a/app/assets/javascripts/pipelines/mixins/pipelines.js b/app/assets/javascripts/pipelines/mixins/pipelines.js index 74ca3071364..3cc9d0a3a4e 100644 --- a/app/assets/javascripts/pipelines/mixins/pipelines.js +++ b/app/assets/javascripts/pipelines/mixins/pipelines.js @@ -27,11 +27,7 @@ export default { }, computed: { shouldRenderPagination() { - return ( - !this.isLoading && - this.state.pipelines.length && - this.state.pageInfo.total > this.state.pageInfo.perPage - ); + return !this.isLoading; }, }, beforeMount() { diff --git a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue index 5f8a4946f4a..fd5d5f86401 100644 --- a/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue +++ b/app/assets/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown.vue @@ -34,7 +34,7 @@ export default { }, errorMessage() { return sprintf( - s__('ClusterIntegration|An error occured while trying to fetch project zones: %{error}'), + s__('ClusterIntegration|An error occurred while trying to fetch project zones: %{error}'), { error: this.gapiError }, ); }, diff --git a/app/assets/javascripts/releases/store/actions.js b/app/assets/javascripts/releases/store/actions.js index b5c4d54ac33..e0a922d5ef6 100644 --- a/app/assets/javascripts/releases/store/actions.js +++ b/app/assets/javascripts/releases/store/actions.js @@ -30,7 +30,7 @@ export const receiveReleasesSuccess = ({ commit }, data) => export const receiveReleasesError = ({ commit }) => { commit(types.RECEIVE_RELEASES_ERROR); - createFlash(__('An error occured while fetching the releases. Please try again.')); + createFlash(__('An error occurred while fetching the releases. Please try again.')); }; // prevent babel-plugin-rewire from generating an invalid default during karma tests diff --git a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue index 7f86741ed29..e9ed05e30cd 100644 --- a/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue +++ b/app/assets/javascripts/set_status_modal/set_status_modal_wrapper.vue @@ -66,19 +66,23 @@ export default { import(/* webpackChunkName: 'emoji' */ '~/emoji') .then(Emoji => { - if (this.emoji) { - this.emojiTag = Emoji.glEmojiTag(this.emoji); - } - this.noEmoji = this.emoji === ''; - this.defaultEmojiTag = Emoji.glEmojiTag('speech_balloon'); + Emoji.initEmojiMap() + .then(() => { + if (this.emoji) { + this.emojiTag = Emoji.glEmojiTag(this.emoji); + } + this.noEmoji = this.emoji === ''; + this.defaultEmojiTag = Emoji.glEmojiTag('speech_balloon'); - this.emojiMenu = new EmojiMenuInModal( - Emoji, - toggleEmojiMenuButtonSelector, - emojiMenuClass, - this.setEmoji, - this.$refs.userStatusForm, - ); + this.emojiMenu = new EmojiMenuInModal( + Emoji, + toggleEmojiMenuButtonSelector, + emojiMenuClass, + this.setEmoji, + this.$refs.userStatusForm, + ); + }) + .catch(() => createFlash(__('Failed to load emoji list.'))); }) .catch(() => createFlash(__('Failed to load emoji list.'))); }, diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index 4017630d6ef..8c71615dff2 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -93,23 +93,22 @@ function UsersSelect(currentUser, els, options = {}) { } // Save current selected user to the DOM - const input = document.createElement('input'); - input.type = 'hidden'; - input.name = $dropdown.data('fieldName'); - - const currentUserInfo = $dropdown.data('currentUserInfo'); - - if (currentUserInfo) { - input.value = currentUserInfo.id; - input.dataset.meta = _.escape(currentUserInfo.name); - } else if (_this.currentUser) { - input.value = _this.currentUser.id; - } + const currentUserInfo = $dropdown.data('currentUserInfo') || {}; + const currentUser = _this.currentUser || {}; + const fieldName = $dropdown.data('fieldName'); + const userName = currentUserInfo.name; + const userId = currentUserInfo.id || currentUser.id; + + const inputHtmlString = _.template(` + <input type="hidden" name="<%- fieldName %>" + data-meta="<%- userName %>" + value="<%- userId %>" /> + `)({ fieldName, userName, userId }); if ($selectbox) { - $dropdown.parent().before(input); + $dropdown.parent().before(inputHtmlString); } else { - $dropdown.after(input); + $dropdown.after(inputHtmlString); } }; diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue index 3b9fc2661ef..50ab7ead582 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue @@ -135,7 +135,7 @@ export default { <span class="dropdown"> <button type="button" - class="btn dropdown-toggle" + class="btn dropdown-toggle qa-dropdown-toggle" data-toggle="dropdown" aria-label="Download as" aria-haspopup="true" @@ -145,12 +145,20 @@ export default { </button> <ul class="dropdown-menu dropdown-menu-right"> <li> - <a :href="mr.emailPatchesPath" class="js-download-email-patches" download> + <a + :href="mr.emailPatchesPath" + class="js-download-email-patches qa-download-email-patches" + download + > {{ s__('mrWidget|Email patches') }} </a> </li> <li> - <a :href="mr.plainDiffPath" class="js-download-plain-diff" download> + <a + :href="mr.plainDiffPath" + class="js-download-plain-diff qa-download-plain-diff" + download + > {{ s__('mrWidget|Plain diff') }} </a> </li> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue index f11cf21b0ca..9e63aa00341 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue @@ -5,6 +5,7 @@ import PipelineStage from '~/pipelines/components/stage.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; import Icon from '~/vue_shared/components/icon.vue'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; +import mrWidgetPipelineMixin from 'ee_else_ce/vue_merge_request_widget/mixins/mr_widget_pipeline'; export default { name: 'MRWidgetPipeline', @@ -13,7 +14,10 @@ export default { CiIcon, Icon, TooltipOnTruncate, + LinkedPipelinesMiniList: () => + import('ee_component/vue_shared/components/linked_pipelines_mini_list.vue'), }, + mixins: [mrWidgetPipelineMixin], props: { pipeline: { type: Object, @@ -82,8 +86,7 @@ export default { <div v-if="hasPipeline || hasCIError" class="ci-widget media"> <template v-if="hasCIError"> <div - class="add-border ci-status-icon ci-status-icon-failed ci-error - js-ci-error append-right-default" + class="add-border ci-status-icon ci-status-icon-failed ci-error js-ci-error append-right-default" > <icon :size="32" name="status_failed_borderless" /> </div> @@ -101,16 +104,13 @@ export default { <a :href="pipeline.path" class="pipeline-id font-weight-normal pipeline-number" >#{{ pipeline.id }}</a > - {{ pipeline.details.status.label }} - <template v-if="hasCommitInfo"> for <a :href="pipeline.commit.commit_path" class="commit-sha js-commit-link font-weight-normal" - > - {{ pipeline.commit.short_id }}</a + >{{ pipeline.commit.short_id }}</a > on <tooltip-on-truncate @@ -126,15 +126,22 @@ export default { </div> <div> <span class="mr-widget-pipeline-graph"> - <span v-if="hasStages" class="stage-cell"> - <div - v-for="(stage, i) in pipeline.details.stages" - :key="i" - class="stage-container dropdown js-mini-pipeline-graph mr-widget-pipeline-stages" - > - <pipeline-stage :stage="stage" /> - </div> + <span class="stage-cell"> + <linked-pipelines-mini-list v-if="triggeredBy.length" :triggered-by="triggeredBy" /> + <template v-if="hasStages"> + <div + v-for="(stage, i) in pipeline.details.stages" + :key="i" + :class="{ + 'has-downstream': hasDownstream(i), + }" + class="stage-container dropdown js-mini-pipeline-graph mr-widget-pipeline-stages" + > + <pipeline-stage :stage="stage" /> + </div> + </template> </span> + <linked-pipelines-mini-list v-if="triggered.length" :triggered="triggered" /> </span> </div> </div> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue index b3c1c0e329d..b6722de5277 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue @@ -20,7 +20,6 @@ export default { <div> <gl-dropdown right - no-caret text="Use an existing commit message" variant="link" class="mr-commit-dropdown" diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index ce4207864ea..9b4e80ee3a3 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -329,7 +329,7 @@ export default { > <ul class="border-top content-list commits-list flex-list"> <commit-edit - v-if="squashBeforeMerge" + v-if="squashBeforeMerge && shouldShowSquashBeforeMerge" v-model="squashCommitMessage" :label="__('Squash commit message')" input-id="squash-message-edit" diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/mr_widget_pipeline.js b/app/assets/javascripts/vue_merge_request_widget/mixins/mr_widget_pipeline.js new file mode 100644 index 00000000000..96e8bb45e34 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/mixins/mr_widget_pipeline.js @@ -0,0 +1,15 @@ +export default { + computed: { + triggered() { + return []; + }, + triggeredBy() { + return []; + }, + }, + methods: { + hasDownstream() { + return false; + }, + }, +}; diff --git a/app/assets/javascripts/vue_shared/components/ci_icon.vue b/app/assets/javascripts/vue_shared/components/ci_icon.vue index 2f498c4fa2a..e6f0a1c69cd 100644 --- a/app/assets/javascripts/vue_shared/components/ci_icon.vue +++ b/app/assets/javascripts/vue_shared/components/ci_icon.vue @@ -21,6 +21,7 @@ import Icon from '../../vue_shared/components/icon.vue'; * - Jobs table * - Jobs show view header * - Jobs show view sidebar + * - Linked pipelines */ const validSizes = [8, 12, 16, 18, 24, 32, 48, 72]; diff --git a/app/assets/javascripts/vue_shared/components/empty_component.js b/app/assets/javascripts/vue_shared/components/empty_component.js new file mode 100644 index 00000000000..e4402020096 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/empty_component.js @@ -0,0 +1,3 @@ +export default { + render: () => null, +}; diff --git a/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue b/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue new file mode 100644 index 00000000000..27cfa8abb24 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/issue/related_issuable_item.vue @@ -0,0 +1,116 @@ +<script> +import { GlTooltipDirective } from '@gitlab/ui'; +import { __, sprintf } from '~/locale'; +import IssueMilestone from '~/vue_shared/components/issue/issue_milestone.vue'; +import IssueAssignees from '~/vue_shared/components/issue/issue_assignees.vue'; +import relatedIssuableMixin from '~/vue_shared/mixins/related_issuable_mixin'; + +export default { + name: 'IssueItem', + components: { + IssueMilestone, + IssueAssignees, + }, + directives: { + GlTooltip: GlTooltipDirective, + }, + mixins: [relatedIssuableMixin], + props: { + canReorder: { + type: Boolean, + required: false, + default: false, + }, + }, + computed: { + stateTitle() { + return sprintf( + '<span class="bold">%{state}</span> %{timeInWords}<br/><span class="text-tertiary">%{timestamp}</span>', + { + state: this.isOpen ? __('Opened') : __('Closed'), + timeInWords: this.isOpen ? this.createdAtInWords : this.closedAtInWords, + timestamp: this.isOpen ? this.createdAtTimestamp : this.closedAtTimestamp, + }, + ); + }, + }, +}; +</script> + +<template> + <div + :class="{ + 'issuable-info-container': !canReorder, + 'card-body': canReorder, + }" + class="item-body" + > + <div class="item-contents"> + <div class="item-title d-flex align-items-center"> + <icon + v-if="hasState" + v-tooltip + :css-classes="iconClass" + :name="iconName" + :size="16" + :title="stateTitle" + :aria-label="state" + data-html="true" + /> + <icon + v-if="confidential" + v-gl-tooltip + name="eye-slash" + :size="16" + :title="__('Confidential')" + class="confidential-icon append-right-4" + :aria-label="__('Confidential')" + /> + <a :href="computedPath" class="sortable-link">{{ title }}</a> + </div> + <div class="item-meta"> + <div class="d-flex align-items-center item-path-id"> + <icon + v-if="hasState" + v-tooltip + :css-classes="iconClass" + :name="iconName" + :size="16" + :title="stateTitle" + :aria-label="state" + data-html="true" + /> + <span v-tooltip :title="itemPath" class="path-id-text">{{ itemPath }}</span> + {{ pathIdSeparator }}{{ itemId }} + </div> + <div class="item-meta-child d-flex align-items-center"> + <issue-milestone + v-if="hasMilestone" + :milestone="milestone" + class="d-flex align-items-center item-milestone" + /> + <slot name="dueDate"></slot> + <slot name="weight"></slot> + </div> + <issue-assignees + v-if="assignees.length" + :assignees="assignees" + class="item-assignees d-inline-flex" + /> + </div> + </div> + <button + v-if="canRemove" + ref="removeButton" + v-tooltip + :disabled="removeDisabled" + type="button" + class="btn btn-default btn-svg btn-item-remove js-issue-item-remove-button qa-remove-issue-button" + title="Remove" + aria-label="Remove" + @click="onRemoveRequest" + > + <icon :size="16" class="btn-item-remove-icon" name="close" /> + </button> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index dbfa32cd0ce..cc6ecdb0395 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -79,7 +79,7 @@ export default { <ul class="nav-links clearfix"> <li :class="{ active: !previewMarkdown }" class="md-header-tab"> <button class="js-write-link" tabindex="-1" type="button" @click="writeMarkdownTab($event)"> - Write + {{ __('Write') }} </button> </li> <li :class="{ active: previewMarkdown }" class="md-header-tab"> @@ -89,36 +89,41 @@ export default { type="button" @click="previewMarkdownTab($event)" > - Preview + {{ __('Preview') }} </button> </li> <li :class="{ active: !previewMarkdown }" class="md-header-toolbar"> - <toolbar-button tag="**" button-title="Add bold text" icon="bold" /> - <toolbar-button tag="*" button-title="Add italic text" icon="italic" /> - <toolbar-button :prepend="true" tag="> " button-title="Insert a quote" icon="quote" /> - <toolbar-button tag="`" tag-block="```" button-title="Insert code" icon="code" /> + <toolbar-button tag="**" :button-title="__('Add bold text')" icon="bold" /> + <toolbar-button tag="*" :button-title="__('Add italic text')" icon="italic" /> + <toolbar-button + :prepend="true" + tag="> " + :button-title="__('Insert a quote')" + icon="quote" + /> + <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" /> <toolbar-button tag="[{text}](url)" tag-select="url" - button-title="Add a link" + :button-title="__('Add a link')" icon="link" /> <toolbar-button :prepend="true" tag="* " - button-title="Add a bullet list" + :button-title="__('Add a bullet list')" icon="list-bulleted" /> <toolbar-button :prepend="true" tag="1. " - button-title="Add a numbered list" + :button-title="__('Add a numbered list')" icon="list-numbered" /> <toolbar-button :prepend="true" tag="* [ ] " - button-title="Add a task list" + :button-title="__('Add a task list')" icon="task-done" /> <toolbar-button @@ -139,11 +144,11 @@ export default { /> <button v-gl-tooltip - aria-label="Go full screen" + :aria-label="__('Go full screen')" class="toolbar-btn toolbar-fullscreen-btn js-zen-enter" data-container="body" tabindex="-1" - title="Go full screen" + :title="__('Go full screen')" type="button" > <icon name="screen-full" /> diff --git a/app/assets/javascripts/vue_shared/components/table_pagination.vue b/app/assets/javascripts/vue_shared/components/table_pagination.vue index 9f38c2e4b9e..8e0b08032f7 100644 --- a/app/assets/javascripts/vue_shared/components/table_pagination.vue +++ b/app/assets/javascripts/vue_shared/components/table_pagination.vue @@ -54,15 +54,14 @@ export default { return this.pageInfo.nextPage; }, getItems() { - const total = this.pageInfo.totalPages; - const { page } = this.pageInfo; + const { totalPages, nextPage, previousPage, page } = this.pageInfo; const items = []; if (page > 1) { items.push({ title: FIRST, first: true }); } - if (page > 1) { + if (previousPage) { items.push({ title: PREV, prev: true }); } else { items.push({ title: PREV, disabled: true, prev: true }); @@ -70,32 +69,34 @@ export default { 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); + if (totalPages) { + const start = Math.max(page - PAGINATION_UI_BUTTON_LIMIT, 1); + const end = Math.min(page + PAGINATION_UI_BUTTON_LIMIT, totalPages); - for (let i = start; i <= end; i += 1) { - const isActive = i === page; - items.push({ title: i, active: isActive, page: true }); - } + for (let i = start; i <= end; i += 1) { + 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 (totalPages - 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) { + if (nextPage) { items.push({ title: NEXT, next: true }); + } else { + items.push({ title: NEXT, disabled: true, next: true }); } - if (total - page >= 1) { + if (totalPages && totalPages - page >= 1) { items.push({ title: LAST, last: true }); } return items; }, showPagination() { - return this.pageInfo.totalPages > 1; + return this.pageInfo.nextPage || this.pageInfo.previousPage; }, }, methods: { diff --git a/app/assets/javascripts/vue_shared/mixins/is_ee.js b/app/assets/javascripts/vue_shared/mixins/is_ee.js new file mode 100644 index 00000000000..8e00d93ef18 --- /dev/null +++ b/app/assets/javascripts/vue_shared/mixins/is_ee.js @@ -0,0 +1,10 @@ +import Vue from 'vue'; +import { isEE } from '~/lib/utils/common_utils'; + +Vue.mixin({ + computed: { + isEE() { + return isEE(); + }, + }, +}); diff --git a/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js b/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js new file mode 100644 index 00000000000..455ae832234 --- /dev/null +++ b/app/assets/javascripts/vue_shared/mixins/related_issuable_mixin.js @@ -0,0 +1,155 @@ +import _ from 'underscore'; +import { formatDate } from '~/lib/utils/datetime_utility'; +import tooltip from '~/vue_shared/directives/tooltip'; +import icon from '~/vue_shared/components/icon.vue'; +import timeagoMixin from '~/vue_shared/mixins/timeago'; + +const mixins = { + data() { + return { + removeDisabled: false, + }; + }, + props: { + idKey: { + type: Number, + required: true, + }, + displayReference: { + type: String, + required: true, + }, + pathIdSeparator: { + type: String, + required: true, + }, + eventNamespace: { + type: String, + required: false, + default: '', + }, + confidential: { + type: Boolean, + required: false, + default: false, + }, + title: { + type: String, + required: false, + default: '', + }, + path: { + type: String, + required: false, + default: '', + }, + state: { + type: String, + required: false, + default: '', + }, + createdAt: { + type: String, + required: false, + default: '', + }, + closedAt: { + type: String, + required: false, + default: '', + }, + milestone: { + type: Object, + required: false, + default: () => ({}), + }, + dueDate: { + type: String, + required: false, + default: '', + }, + assignees: { + type: Array, + required: false, + default: () => [], + }, + weight: { + type: Number, + required: false, + default: 0, + }, + canRemove: { + type: Boolean, + required: false, + default: false, + }, + }, + components: { + icon, + }, + directives: { + tooltip, + }, + mixins: [timeagoMixin], + computed: { + hasState() { + return this.state && this.state.length > 0; + }, + isOpen() { + return this.state === 'opened'; + }, + isClosed() { + return this.state === 'closed'; + }, + hasTitle() { + return this.title.length > 0; + }, + hasMilestone() { + return !_.isEmpty(this.milestone); + }, + iconName() { + return this.isOpen ? 'issue-open-m' : 'issue-close'; + }, + iconClass() { + return this.isOpen ? 'issue-token-state-icon-open' : 'issue-token-state-icon-closed'; + }, + computedLinkElementType() { + return this.path.length > 0 ? 'a' : 'span'; + }, + computedPath() { + return this.path.length ? this.path : null; + }, + itemPath() { + return this.displayReference.split(this.pathIdSeparator)[0]; + }, + itemId() { + return this.displayReference.split(this.pathIdSeparator).pop(); + }, + createdAtInWords() { + return this.createdAt ? this.timeFormated(this.createdAt) : ''; + }, + createdAtTimestamp() { + return this.createdAt ? formatDate(new Date(this.createdAt)) : ''; + }, + closedAtInWords() { + return this.closedAt ? this.timeFormated(this.closedAt) : ''; + }, + closedAtTimestamp() { + return this.closedAt ? formatDate(new Date(this.closedAt)) : ''; + }, + }, + methods: { + onRemoveRequest() { + let namespacePrefix = ''; + if (this.eventNamespace && this.eventNamespace.length > 0) { + namespacePrefix = `${this.eventNamespace}`; + } + + this.$emit(`${namespacePrefix}RemoveRequest`, this.idKey); + + this.removeDisabled = true; + }, + }, +}; + +export default mixins; diff --git a/app/assets/stylesheets/components/related_items_list.scss b/app/assets/stylesheets/components/related_items_list.scss index 048a5c0300c..edf7b26ebaa 100644 --- a/app/assets/stylesheets/components/related_items_list.scss +++ b/app/assets/stylesheets/components/related_items_list.scss @@ -195,8 +195,7 @@ $item-weight-max-width: 48px; } .mr-status-wrapper, -.mr-ci-status - { +.mr-ci-status { line-height: 0; } diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 555ea276c6c..216877a4461 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -66,3 +66,4 @@ @import 'framework/read_more'; @import 'framework/flex_grid'; @import 'framework/system_messages'; +@import "framework/spinner"; diff --git a/app/assets/stylesheets/framework/animations.scss b/app/assets/stylesheets/framework/animations.scss index 70d50c74ca9..257d788873c 100644 --- a/app/assets/stylesheets/framework/animations.scss +++ b/app/assets/stylesheets/framework/animations.scss @@ -27,7 +27,7 @@ &.flipOutY, &.bounceIn, &.bounceOut { - @include webkit-prefix(animation-duration, .75s); + @include webkit-prefix(animation-duration, 0.75s); } &.short { @@ -73,22 +73,10 @@ @mixin disable-all-animation { /*CSS transitions*/ - -o-transition-property: none !important; - -moz-transition-property: none !important; - -ms-transition-property: none !important; - -webkit-transition-property: none !important; transition-property: none !important; /*CSS transforms*/ - -o-transform: none !important; - -moz-transform: none !important; - -ms-transform: none !important; - -webkit-transform: none !important; transform: none !important; /*CSS animations*/ - -webkit-animation: none !important; - -moz-animation: none !important; - -o-animation: none !important; - -ms-animation: none !important; animation: none !important; } @@ -202,7 +190,7 @@ a { } } - [class^="skeleton-line-"] { + [class^='skeleton-line-'] { position: relative; background-color: $gray-100; height: 10px; @@ -218,13 +206,11 @@ a { animation: blockTextShine 1s linear infinite forwards; background-repeat: no-repeat; background-size: cover; - background-image: linear-gradient( - to right, - $gray-100 0%, - $gray-50 20%, - $gray-100 40%, - $gray-100 100% - ); + background-image: linear-gradient(to right, + $gray-100 0%, + $gray-50 20%, + $gray-100 40%, + $gray-100 100%); height: 10px; } } diff --git a/app/assets/stylesheets/framework/asciidoctor.scss b/app/assets/stylesheets/framework/asciidoctor.scss index 62493c32833..1586265d40e 100644 --- a/app/assets/stylesheets/framework/asciidoctor.scss +++ b/app/assets/stylesheets/framework/asciidoctor.scss @@ -1,7 +1,7 @@ .admonitionblock td.icon { width: 1%; - [class^="fa icon-"] { + [class^='fa icon-'] { @extend .fa-2x; } diff --git a/app/assets/stylesheets/framework/avatar.scss b/app/assets/stylesheets/framework/avatar.scss index bfd3d776bd4..af79a4d9392 100644 --- a/app/assets/stylesheets/framework/avatar.scss +++ b/app/assets/stylesheets/framework/avatar.scss @@ -45,7 +45,6 @@ display: inline-block; margin-left: 2px; flex-shrink: 0; - -webkit-flex-shrink: 0; &.s16 { margin-right: 4px; } &.s24 { margin-right: 4px; } @@ -74,20 +73,48 @@ background-color: $gray-darker; // Sizes - &.s16 { font-size: 12px; line-height: 1.33; } - &.s24 { font-size: 13px; line-height: 1.8; } - &.s26 { font-size: 20px; line-height: 1.33; } - &.s32 { font-size: 20px; line-height: 30px; } - &.s40 { font-size: 16px; line-height: 38px; } - &.s48 { font-size: 20px; line-height: 46px; } - &.s60 { font-size: 32px; line-height: 58px; } - &.s64 { font-size: 32px; line-height: 64px; } - &.s70 { font-size: 34px; line-height: 70px; } - &.s90 { font-size: 36px; line-height: 88px; } - &.s100 { font-size: 36px; line-height: 98px; } - &.s110 { font-size: 40px; line-height: 108px; font-weight: $gl-font-weight-normal; } - &.s140 { font-size: 72px; line-height: 138px; } - &.s160 { font-size: 96px; line-height: 158px; } + &.s16 { font-size: 12px; + line-height: 1.33; } + + &.s24 { font-size: 13px; + line-height: 1.8; } + + &.s26 { font-size: 20px; + line-height: 1.33; } + + &.s32 { font-size: 20px; + line-height: 30px; } + + &.s40 { font-size: 16px; + line-height: 38px; } + + &.s48 { font-size: 20px; + line-height: 46px; } + + &.s60 { font-size: 32px; + line-height: 58px; } + + &.s64 { font-size: 32px; + line-height: 64px; } + + &.s70 { font-size: 34px; + line-height: 70px; } + + &.s90 { font-size: 36px; + line-height: 88px; } + + &.s100 { font-size: 36px; + line-height: 98px; } + + &.s110 { font-size: 40px; + line-height: 108px; + font-weight: $gl-font-weight-normal; } + + &.s140 { font-size: 72px; + line-height: 138px; } + + &.s160 { font-size: 96px; + line-height: 158px; } // Background colors &.bg1 { background-color: $identicon-red; } @@ -120,8 +147,11 @@ align-self: center; } - &.s40 { min-width: 40px; min-height: 40px; } - &.s64 { min-width: 64px; min-height: 64px; } + &.s40 { min-width: 40px; + min-height: 40px; } + + &.s64 { min-width: 64px; + min-height: 64px; } } .rect-avatar { diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss index 5cfd5bbd4f5..648e1944388 100644 --- a/app/assets/stylesheets/framework/awards.scss +++ b/app/assets/stylesheets/framework/awards.scss @@ -23,9 +23,9 @@ box-shadow: 0 6px 12px $award-emoji-menu-shadow; pointer-events: none; opacity: 0; - transform: scale(.2); + transform: scale(0.2); transform-origin: 0 -45px; - transition: .3s cubic-bezier(.67, .06, .19, 1.44); + transition: 0.3s cubic-bezier(0.67, 0.06, 0.19, 1.44); transition-property: transform, opacity; &.is-rendered { @@ -62,7 +62,7 @@ } .emoji-search { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAFu0lEQVRIia1WTahkVxH+quqce7vf6zdvJpHoIlkYJ2SiJiIokmQjgoGgIAaEIYuYXWICgojiwkmC4taFwhjcyIDusogEIwwiSSCKPwsdwzAg0SjJ9Izzk5n3+nXfe8+pqizOvd395scfsJqi6dPnnDr11Vc/NJ1OwUTosqJLCmYCHCAC2mSHs+ojZv6AO46Y+20AhIneJsafhPhXVZSXDk7qi+aOLhtQNuBmQtcarAKjTXpn2+l3u2yPunvZSABRucjcAV/eMZuM48/Go/g1d19kc4wq+e8MZjWkbI/P5t2P3RFFbv7SQdyBlBUx8N8OTuqjMcof+N94yMPrY2DMm/ytnb32J0QrY+6AqsHM4Q64O9SKDmerKDD3Oy/tNL9vk342CC8RuU6n0ymCMHb22scu7zQngtASOjUHE1BX4UUAv4b7Ow6qiXCXuz/UdvogAAweDY943/b4cAz0ZlYHXeMsnT07RVb7wMUr8ykI4H5HVkMd5Rcb4/jNURVOL5qErAaAUUdCCIJ5kx5q2nw8m39ImEAAsjpE6PStB0YfMcd1wqqG3Xn7A3PfZyyKnNjaqD4fmE/fCNKshirIyY1xvI+Av6g5QIAIIWX7cJPssboSiBBEeKmsZne0Sb8kzAUWNYyq8NvbDo0fZ6beqxuLmqOOMr/lwOh+YXpXtbjERGja9JyZ9+HxpXKb9Gj5oywRESbj+Cj1ENG1QViTGBl1FbC1We1tbVRfHWIoQkhqH9xbpE92XUbb6VJZ1R4crjRz1JWcDMJvLdoMcyAEhjuwHo8Bfndg3mbszhOY+adVlMtD3po51OwzIQiEaams7oeJhxRw1FFOVpFRRUYIhMBAFRnjOsC8IFHHUA4TQQhgAqpAiIFfGbxkIqj54ayGbL7UoOqHCniAEKHLNr26l+D9wQJzeUwMAnfHvEnLECzZRwRV++d60ptjW9VLZeolEJG6GwCCE0CFVNB+Ay0NEqoQYG4YYFu7B8IEVRt3uRzy/osIoLV9QZimWXGHUMFdmI6M64DUF2Je88R9VZqCSP+QlcF5k+4tCzSsXaqjINuK6UyE0+s/mk6/qFq8oAIL9pqMLhkGsNrOyoOIlszust3aJv0U9+kFdwjTGwWl1YdF+KWlQSZ0Se/psj8yGVdg5tJyfH96EBWmLtoEMwMzMFt031NzGWLLzKhC+KV7H5ZeeaMOPxemma2x68puc0LN3+/u6LJiePS6MKHvn4wu6cPzJj0hsioeMfDrEvjv5r6W9gBvjKJujuKzQ0URIZj75NylvT+mbHfXQa4rwAMaVRTMm/SFyzvNy0yF6+4AM+1ubcSnqkAIUjQKl1RKSbE5jt+vovx1MBqF0WW7/d1Z80ab9BtmuJ3Xk5cJKds9TZt/uLPXvtiTrQ+dIwqfAejUvM1os6FNikXKUHfQ+ekUsXT5u85enJ0CaBSkkGEo1syUQ+DfMdE/4GA1uzupf9zdbzhOmLsF4efHVXjaHHAzmDtGdQRd/Nc5wAEJjNki3XfhyvwVNz80xANrht3LsENY9cBBdN1L9GUyyvFRFZ42t75sBvCQRykbRlU4tT2pPxoCvzx09d4GmPs200M6wKdWSDGK8mppYSWdhAlt0qeaLv+IadXU9/Evq4FAZ8ej+LmtcTxaRX4NWI0Uag5Vg1p5MYg8BnlhXIdPHDow+vTWZvVMVttXDLqkTzZdPj6Qii6cP1cSvIdl3iQkNYyi9HH0I22y+93tY3DcQkTZgQtM+POoCr8x97eylkmtrgKuztrvXJ21x/aNKuqIkZ/fntRfCdcTfhUTAIhRzoDojJD0aSNLLwMzmpT7+JaLtyf1MwDo6qz9djFaUq3t9MlFmy/c1OCSceY9fMsVaL9mvH9ocXdkdWxv1scAePG0THAhMOaLdOw/Gvxfxb1w4eCapyIENUcV5M3/u8FitAxZ25P6GAHT3UX39Srw+QOb1ZffA98Dl2Wy1BYkAAAAAElFTkSuQmCC"); + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAYAAAByDd+UAAAFu0lEQVRIia1WTahkVxH+quqce7vf6zdvJpHoIlkYJ2SiJiIokmQjgoGgIAaEIYuYXWICgojiwkmC4taFwhjcyIDusogEIwwiSSCKPwsdwzAg0SjJ9Izzk5n3+nXfe8+pqizOvd395scfsJqi6dPnnDr11Vc/NJ1OwUTosqJLCmYCHCAC2mSHs+ojZv6AO46Y+20AhIneJsafhPhXVZSXDk7qi+aOLhtQNuBmQtcarAKjTXpn2+l3u2yPunvZSABRucjcAV/eMZuM48/Go/g1d19kc4wq+e8MZjWkbI/P5t2P3RFFbv7SQdyBlBUx8N8OTuqjMcof+N94yMPrY2DMm/ytnb32J0QrY+6AqsHM4Q64O9SKDmerKDD3Oy/tNL9vk342CC8RuU6n0ymCMHb22scu7zQngtASOjUHE1BX4UUAv4b7Ow6qiXCXuz/UdvogAAweDY943/b4cAz0ZlYHXeMsnT07RVb7wMUr8ykI4H5HVkMd5Rcb4/jNURVOL5qErAaAUUdCCIJ5kx5q2nw8m39ImEAAsjpE6PStB0YfMcd1wqqG3Xn7A3PfZyyKnNjaqD4fmE/fCNKshirIyY1xvI+Av6g5QIAIIWX7cJPssboSiBBEeKmsZne0Sb8kzAUWNYyq8NvbDo0fZ6beqxuLmqOOMr/lwOh+YXpXtbjERGja9JyZ9+HxpXKb9Gj5oywRESbj+Cj1ENG1QViTGBl1FbC1We1tbVRfHWIoQkhqH9xbpE92XUbb6VJZ1R4crjRz1JWcDMJvLdoMcyAEhjuwHo8Bfndg3mbszhOY+adVlMtD3po51OwzIQiEaams7oeJhxRw1FFOVpFRRUYIhMBAFRnjOsC8IFHHUA4TQQhgAqpAiIFfGbxkIqj54ayGbL7UoOqHCniAEKHLNr26l+D9wQJzeUwMAnfHvEnLECzZRwRV++d60ptjW9VLZeolEJG6GwCCE0CFVNB+Ay0NEqoQYG4YYFu7B8IEVRt3uRzy/osIoLV9QZimWXGHUMFdmI6M64DUF2Je88R9VZqCSP+QlcF5k+4tCzSsXaqjINuK6UyE0+s/mk6/qFq8oAIL9pqMLhkGsNrOyoOIlszust3aJv0U9+kFdwjTGwWl1YdF+KWlQSZ0Se/psj8yGVdg5tJyfH96EBWmLtoEMwMzMFt031NzGWLLzKhC+KV7H5ZeeaMOPxemma2x68puc0LN3+/u6LJiePS6MKHvn4wu6cPzJj0hsioeMfDrEvjv5r6W9gBvjKJujuKzQ0URIZj75NylvT+mbHfXQa4rwAMaVRTMm/SFyzvNy0yF6+4AM+1ubcSnqkAIUjQKl1RKSbE5jt+vovx1MBqF0WW7/d1Z80ab9BtmuJ3Xk5cJKds9TZt/uLPXvtiTrQ+dIwqfAejUvM1os6FNikXKUHfQ+ekUsXT5u85enJ0CaBSkkGEo1syUQ+DfMdE/4GA1uzupf9zdbzhOmLsF4efHVXjaHHAzmDtGdQRd/Nc5wAEJjNki3XfhyvwVNz80xANrht3LsENY9cBBdN1L9GUyyvFRFZ42t75sBvCQRykbRlU4tT2pPxoCvzx09d4GmPs200M6wKdWSDGK8mppYSWdhAlt0qeaLv+IadXU9/Evq4FAZ8ej+LmtcTxaRX4NWI0Uag5Vg1p5MYg8BnlhXIdPHDow+vTWZvVMVttXDLqkTzZdPj6Qii6cP1cSvIdl3iQkNYyi9HH0I22y+93tY3DcQkTZgQtM+POoCr8x97eylkmtrgKuztrvXJ21x/aNKuqIkZ/fntRfCdcTfhUTAIhRzoDojJD0aSNLLwMzmpT7+JaLtyf1MwDo6qz9djFaUq3t9MlFmy/c1OCSceY9fMsVaL9mvH9ocXdkdWxv1scAePG0THAhMOaLdOw/Gvxfxb1w4eCapyIENUcV5M3/u8FitAxZ25P6GAHT3UX39Srw+QOb1ZffA98Dl2Wy1BYkAAAAAElFTkSuQmCC'); background-repeat: no-repeat; background-position: right 5px center; background-size: 16px; @@ -90,7 +90,7 @@ background: none; border: 0; border-radius: $border-radius-base; - transition: transform .15s cubic-bezier(.3, 0, .2, 2); + transition: transform 0.15s cubic-bezier(0.3, 0, 0.2, 2); &:hover { background-color: transparent; diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss index 43b7c26b272..e6c55252b24 100644 --- a/app/assets/stylesheets/framework/blocks.scss +++ b/app/assets/stylesheets/framework/blocks.scss @@ -86,11 +86,8 @@ } .block-controls { - display: -webkit-flex; display: flex; - -webkit-justify-content: flex-end; justify-content: flex-end; - -webkit-flex: 1; flex: 1; .control { @@ -153,7 +150,7 @@ display: inline-block; margin-left: 5px; font-size: 18px; - color: color("gray"); + color: color('gray'); } p { @@ -228,7 +225,6 @@ } .group-info { - h1 { display: inline; font-weight: $gl-font-weight-normal; diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index cb2c8879c5f..a4af84f8d27 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -395,8 +395,6 @@ cursor: default; &:active { - -moz-box-shadow: inset 0 0 0 $white-light; - -webkit-box-shadow: inset 0 0 0 $white-light; box-shadow: inset 0 0 0 $white-light; } } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index b09e44e052a..aad5150c0b5 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -57,7 +57,11 @@ text-decoration: underline; } -.hint { font-style: italic; color: $gl-gray-400; } +.hint { + font-style: italic; + color: $gl-gray-400; +} + .light { color: $gl-text-color; } .slead { @@ -158,13 +162,14 @@ p.time { text-shadow: none; } -.thin_area { +.thin-area { height: 150px; } // Fix issue with notes & lists creating a bunch of bottom borders. li.note { img { max-width: 100%; } + .note-title { li { border-bottom: 0 !important; @@ -335,7 +340,7 @@ img.emoji { .disabled-content { pointer-events: none; - opacity: .5; + opacity: 0.5; } .break-word { @@ -399,7 +404,9 @@ img.emoji { .flex-grow { flex-grow: 1; } .flex-no-shrink { flex-shrink: 0; } .ws-initial { white-space: initial; } +.ws-normal { white-space: normal; } .overflow-auto { overflow: auto; } + .d-flex-center { display: flex; align-items: center; diff --git a/app/assets/stylesheets/framework/contextual_sidebar.scss b/app/assets/stylesheets/framework/contextual_sidebar.scss index 8b6a7017c47..3238b01c6c0 100644 --- a/app/assets/stylesheets/framework/contextual_sidebar.scss +++ b/app/assets/stylesheets/framework/contextual_sidebar.scss @@ -5,7 +5,7 @@ padding-left: $contextual-sidebar-collapsed-width; } - @include media-breakpoint-up(lg) { + @include media-breakpoint-up(xl) { padding-left: $contextual-sidebar-width; } @@ -15,7 +15,7 @@ } .page-with-icon-sidebar { - @include media-breakpoint-up(sm) { + @include media-breakpoint-up(md) { padding-left: $contextual-sidebar-collapsed-width; } } @@ -71,6 +71,44 @@ } } +@mixin collapse-contextual-sidebar-content { + .context-header { + height: 60px; + width: $contextual-sidebar-collapsed-width; + + a { + padding: 10px 4px; + } + } + + .sidebar-top-level-items > li { + .sidebar-sub-level-items { + &:not(.flyout-list) { + display: none; + } + } + } + + .nav-icon-container { + margin-right: 0; + } + + .toggle-sidebar-button { + padding: 16px; + width: $contextual-sidebar-collapsed-width - 1px; + + .collapse-text, + .icon-angle-double-left { + display: none; + } + + .icon-angle-double-right { + display: block; + margin: 0; + } + } +} + .nav-sidebar { transition: width $sidebar-transition-duration, left $sidebar-transition-duration; position: fixed; @@ -89,7 +127,7 @@ } } - &.sidebar-collapsed-desktop { + @mixin collapse-contextual-sidebar { width: $contextual-sidebar-collapsed-width; .nav-sidebar-inner-scroll { @@ -115,6 +153,10 @@ } } + &.sidebar-collapsed-desktop { + @include collapse-contextual-sidebar; + } + &.sidebar-expanded-mobile { left: 0; } @@ -150,7 +192,7 @@ } } - @include media-breakpoint-down(xs) { + @include media-breakpoint-down(sm) { left: (-$contextual-sidebar-width); } @@ -167,16 +209,19 @@ height: 16px; width: 16px; } + + @media (min-width: map-get($grid-breakpoints, md)) and (max-width: map-get($grid-breakpoints, xl) - 1px) { + &:not(.sidebar-expanded-mobile) { + @include collapse-contextual-sidebar; + @include collapse-contextual-sidebar-content; + } + } } .nav-sidebar-inner-scroll { height: 100%; width: 100%; overflow: auto; - - @include media-breakpoint-up(sm) { - overflow: hidden; - } } .with-performance-bar .nav-sidebar { @@ -346,53 +391,13 @@ } } -.toggle-sidebar-button { - @include media-breakpoint-down(xs) { - display: none; - } -} - .collapse-text { white-space: nowrap; overflow: hidden; } .sidebar-collapsed-desktop { - .context-header { - height: 60px; - width: $contextual-sidebar-collapsed-width; - - a { - padding: 10px 4px; - } - } - - .sidebar-top-level-items > li { - .sidebar-sub-level-items { - &:not(.flyout-list) { - display: none; - } - } - } - - .nav-icon-container { - margin-right: 0; - } - - .toggle-sidebar-button { - padding: 16px; - width: $contextual-sidebar-collapsed-width - 1px; - - .collapse-text, - .icon-angle-double-left { - display: none; - } - - .icon-angle-double-right { - display: block; - margin: 0; - } - } + @include collapse-contextual-sidebar-content; } .fly-out-top-item { @@ -428,16 +433,14 @@ color: $gl-text-color-secondary; } - @include media-breakpoint-down(xs) { + @include media-breakpoint-down(sm) { display: flex; align-items: center; i { font-size: 18px; } - } - @include media-breakpoint-down(xs) { + .breadcrumbs-links { padding-left: $gl-padding; border-left: 1px solid $gl-text-color-quaternary; @@ -445,21 +448,25 @@ } } -@include media-breakpoint-down(xs) { +@include media-breakpoint-down(sm) { .close-nav-button { display: flex; } -} -.mobile-overlay { - display: none; + .toggle-sidebar-button { + display: none; + } - &.mobile-nav-open { - display: block; - position: fixed; - background-color: $black-transparent; - height: 100%; - width: 100%; - z-index: 300; + .mobile-overlay { + display: none; + + &.mobile-nav-open { + display: block; + position: fixed; + background-color: $black-transparent; + height: 100%; + width: 100%; + z-index: 300; + } } } diff --git a/app/assets/stylesheets/framework/emojis.scss b/app/assets/stylesheets/framework/emojis.scss index be85e03430e..13c5541da92 100644 --- a/app/assets/stylesheets/framework/emojis.scss +++ b/app/assets/stylesheets/framework/emojis.scss @@ -2,7 +2,7 @@ gl-emoji { font-style: normal; display: inline-flex; vertical-align: middle; - font-family: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; font-size: 1.4em; line-height: 1em; } diff --git a/app/assets/stylesheets/framework/filters.scss b/app/assets/stylesheets/framework/filters.scss index f48b3ddc912..e5b529ae11d 100644 --- a/app/assets/stylesheets/framework/filters.scss +++ b/app/assets/stylesheets/framework/filters.scss @@ -50,19 +50,15 @@ } .filtered-search-wrapper { - display: -webkit-flex; display: flex; @include media-breakpoint-down(xs) { - -webkit-flex-direction: column; flex-direction: column; } .tokens-container { - display: -webkit-flex; display: flex; flex: 1; - -webkit-flex: 1; padding-left: 12px; position: relative; margin-bottom: 0; @@ -82,21 +78,18 @@ .input-token:only-child, .input-token:last-child { flex: 1; - -webkit-flex: 1; max-width: inherit; } } .filtered-search-token, .filtered-search-term { - display: -webkit-flex; display: flex; flex-shrink: 0; margin-top: 4px; margin-bottom: 4px; .selectable { - display: -webkit-flex; display: flex; } @@ -176,7 +169,6 @@ } .scroll-container { - display: -webkit-flex; display: flex; overflow-x: auto; white-space: nowrap; @@ -186,7 +178,6 @@ .filtered-search-box { position: relative; flex: 1; - display: -webkit-flex; display: flex; width: 100%; min-width: 0; @@ -194,7 +185,6 @@ background-color: $white-light; @include media-breakpoint-down(xs) { - -webkit-flex: 1 1 auto; flex: 1 1 auto; margin-bottom: 10px; } @@ -349,7 +339,6 @@ } .filter-dropdown-container { - display: -webkit-flex; display: flex; .dropdown-toggle { diff --git a/app/assets/stylesheets/framework/forms.scss b/app/assets/stylesheets/framework/forms.scss index cbf9ee24ec5..3b1d1d67509 100644 --- a/app/assets/stylesheets/framework/forms.scss +++ b/app/assets/stylesheets/framework/forms.scss @@ -156,8 +156,6 @@ label { .select-control { padding-left: 10px; padding-right: 10px; - -webkit-appearance: none; - -moz-appearance: none; appearance: none; &::-ms-expand { @@ -178,7 +176,8 @@ label { font-weight: $gl-font-weight-normal; } -.form-control::-webkit-input-placeholder { + +.form-control::placeholder { color: $gl-text-color-tertiary; } diff --git a/app/assets/stylesheets/framework/gfm.scss b/app/assets/stylesheets/framework/gfm.scss index 50d4298d418..6943bfbc3d0 100644 --- a/app/assets/stylesheets/framework/gfm.scss +++ b/app/assets/stylesheets/framework/gfm.scss @@ -32,7 +32,7 @@ height: $chip-size; background: $white-light; background-image: linear-gradient(135deg, $gray-dark 25%, transparent 0%, transparent 75%, $gray-dark 0%), - linear-gradient(135deg, $gray-dark 25%, transparent 0%, transparent 75%, $gray-dark 0%); + linear-gradient(135deg, $gray-dark 25%, transparent 0%, transparent 75%, $gray-dark 0%); background-size: $bg-size $bg-size; background-position: 0 0, $bg-pos $bg-pos; diff --git a/app/assets/stylesheets/framework/header.scss b/app/assets/stylesheets/framework/header.scss index 23dcc1817b1..f5ed6621c55 100644 --- a/app/assets/stylesheets/framework/header.scss +++ b/app/assets/stylesheets/framework/header.scss @@ -39,7 +39,6 @@ .header-content { width: 100%; - display: -webkit-flex; display: flex; justify-content: space-between; position: relative; @@ -47,11 +46,8 @@ padding-left: 0; .title-container { - display: -webkit-flex; display: flex; - -webkit-align-items: stretch; align-items: stretch; - -webkit-flex: 1 1 auto; flex: 1 1 auto; padding-top: 0; overflow: visible; @@ -60,7 +56,6 @@ .title { padding-right: 0; color: currentColor; - display: -webkit-flex; display: flex; position: relative; margin: 0; @@ -85,7 +80,6 @@ } a { - display: -webkit-flex; display: flex; align-items: center; padding: 2px 8px; @@ -173,7 +167,6 @@ .navbar-nav { @include media-breakpoint-down(xs) { - display: -webkit-flex; display: flex; padding-right: 10px; flex-direction: row; @@ -258,7 +251,6 @@ > li { > a, > button { - display: -webkit-flex; display: flex; align-items: center; justify-content: center; @@ -294,7 +286,6 @@ } .navbar-sub-nav { - display: -webkit-flex; display: flex; margin: 0 0 0 6px; @@ -326,14 +317,12 @@ } .breadcrumbs { - display: -webkit-flex; display: flex; min-height: $breadcrumb-min-height; color: $gl-text-color; } .breadcrumbs-container { - display: -webkit-flex; display: flex; width: 100%; position: relative; @@ -344,7 +333,6 @@ } .breadcrumbs-links { - -webkit-flex: 1; flex: 1; min-width: 0; align-self: center; @@ -379,7 +367,6 @@ } .breadcrumbs-list { - display: -webkit-flex; display: flex; margin-bottom: 0; line-height: 16px; @@ -430,7 +417,6 @@ } .breadcrumbs-extra { - display: -webkit-flex; display: flex; flex: 0 0 auto; margin-left: auto; diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index d9d4a210f5f..1a74e06a75d 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -15,7 +15,7 @@ word-wrap: break-word; &::after { - content: " "; + content: ' '; display: table; clear: both; } @@ -167,7 +167,7 @@ ul.content-list { } .no-comments { - opacity: .5; + opacity: 0.5; } } @@ -196,8 +196,6 @@ ul.content-list { // Content list using flexbox .flex-list { .flex-row { - display: -webkit-flex; - display: -ms-flexbox; display: flex; align-items: center; white-space: nowrap; diff --git a/app/assets/stylesheets/framework/logo.scss b/app/assets/stylesheets/framework/logo.scss index 429cfbe7235..c5feefb8c54 100644 --- a/app/assets/stylesheets/framework/logo.scss +++ b/app/assets/stylesheets/framework/logo.scss @@ -9,7 +9,6 @@ } .tanuki-logo { - .tanuki-left-ear, .tanuki-right-ear, .tanuki-nose { @@ -34,7 +33,9 @@ .tanuki-left-cheek { @include include-keyframes(animate-tanuki-left-cheek) { - 0%, 10%, 100% { + 0%, + 10%, + 100% { fill: lighten($tanuki-yellow, 25%); } @@ -46,11 +47,13 @@ .tanuki-left-eye { @include include-keyframes(animate-tanuki-left-eye) { - 10%, 80% { + 10%, + 80% { fill: $tanuki-orange; } - 20%, 90% { + 20%, + 90% { fill: lighten($tanuki-orange, 25%); } } @@ -58,11 +61,13 @@ .tanuki-left-ear { @include include-keyframes(animate-tanuki-left-ear) { - 10%, 80% { + 10%, + 80% { fill: $tanuki-red; } - 20%, 90% { + 20%, + 90% { fill: lighten($tanuki-red, 25%); } } @@ -70,11 +75,13 @@ .tanuki-nose { @include include-keyframes(animate-tanuki-nose) { - 20%, 70% { + 20%, + 70% { fill: $tanuki-red; } - 30%, 80% { + 30%, + 80% { fill: lighten($tanuki-red, 25%); } } @@ -82,11 +89,13 @@ .tanuki-right-eye { @include include-keyframes(animate-tanuki-right-eye) { - 30%, 60% { + 30%, + 60% { fill: $tanuki-orange; } - 40%, 70% { + 40%, + 70% { fill: lighten($tanuki-orange, 25%); } } @@ -94,11 +103,13 @@ .tanuki-right-ear { @include include-keyframes(animate-tanuki-right-ear) { - 30%, 60% { + 30%, + 60% { fill: $tanuki-red; } - 40%, 70% { + 40%, + 70% { fill: lighten($tanuki-red, 25%); } } diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index 3b0869e31a9..ba3b0906e28 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -26,16 +26,11 @@ */ @mixin markdown-table { width: auto; - display: inline-block; + display: block; overflow-x: auto; border: 0; border-color: $gl-gray-100; - @supports (width: fit-content) { - display: block; - width: fit-content; - } - tr { th { border-bottom: solid 2px $gl-gray-100; @@ -120,16 +115,13 @@ /* http://phrappe.com/css/conditional-css-for-webkit-based-browsers/ */ @mixin on-webkit-only { + /* stylelint-disable-next-line media-feature-name-no-vendor-prefix */ @media screen and (-webkit-min-device-pixel-ratio: 0) { @content; } } @mixin keyframes($animation-name) { - @-webkit-keyframes #{$animation-name} { - @content; - } - @keyframes #{$animation-name} { @content; } @@ -169,12 +161,10 @@ width: 43px; height: 30px; transition-duration: 0.3s; - -webkit-transform: translateZ(0); - background: linear-gradient( - to $gradient-direction, - $gradient-color 45%, - rgba($gradient-color, 0.4) - ); + transform: translateZ(0); + background: linear-gradient(to $gradient-direction, + $gradient-color 45%, + rgba($gradient-color, 0.4)); &.scrolling { visibility: visible; @@ -270,7 +260,6 @@ border: 1px solid $border-color; color: $gl-text-color; position: sticky; - position: -webkit-sticky; top: $header-height; padding: $grid-size; diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index bcd601e198a..ac673eafdc7 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -32,7 +32,7 @@ } &::after { - content: "\f078"; + content: '\f078'; position: absolute; z-index: 1; text-align: center; diff --git a/app/assets/stylesheets/framework/spinner.scss b/app/assets/stylesheets/framework/spinner.scss new file mode 100644 index 00000000000..91fe75075dc --- /dev/null +++ b/app/assets/stylesheets/framework/spinner.scss @@ -0,0 +1,51 @@ +@mixin spinner-color($color) { + border-color: rgba($color, 0.25); + border-top-color: $color; +} + +@mixin spinner-size($size, $border-width) { + width: $size; + height: $size; + border-width: $border-width; + @include webkit-prefix(transform-origin, 50% 50% calc((#{$size} / 2) + #{$border-width})); +} + +@keyframes spinner-rotate { + 0% { + transform: rotate(0); + } + + 100% { + transform: rotate(360deg); + } +} + +.spinner { + border-radius: 50%; + position: relative; + margin: 0 auto; + animation-name: spinner-rotate; + animation-duration: 0.6s; + animation-timing-function: linear; + animation-iteration-count: infinite; + border-style: solid; + display: inline-flex; + @include spinner-size(16px, 2px); + @include spinner-color($orange-600); + + &.spinner-md { + @include spinner-size(32px, 3px); + } + + &.spinner-lg { + @include spinner-size(64px, 4px); + } + + &.spinner-dark { + @include spinner-color($gray-700); + } + + &.spinner-light { + @include spinner-color($white); + } +} diff --git a/app/assets/stylesheets/framework/tables.scss b/app/assets/stylesheets/framework/tables.scss index 295a5b5ee7a..ba406bac50b 100644 --- a/app/assets/stylesheets/framework/tables.scss +++ b/app/assets/stylesheets/framework/tables.scss @@ -161,4 +161,3 @@ table { border-top: 0; } } - diff --git a/app/assets/stylesheets/framework/terms.scss b/app/assets/stylesheets/framework/terms.scss index 3f4be8829d7..b07d6023127 100644 --- a/app/assets/stylesheets/framework/terms.scss +++ b/app/assets/stylesheets/framework/terms.scss @@ -13,7 +13,6 @@ .card { .card-header { - display: -webkit-flex; display: flex; align-items: center; justify-content: space-between; diff --git a/app/assets/stylesheets/framework/toggle.scss b/app/assets/stylesheets/framework/toggle.scss index 8258da07e4d..5f8ac3b7e37 100644 --- a/app/assets/stylesheets/framework/toggle.scss +++ b/app/assets/stylesheets/framework/toggle.scss @@ -34,7 +34,7 @@ background: $gl-gray-400; border-radius: 12px; padding: 3px; - transition: all .4s ease; + transition: all 0.4s ease; &::selection, &::before::selection, @@ -52,7 +52,7 @@ left: 0; border-radius: 9px; background: $feature-toggle-color; - transition: all .2s ease; + transition: all 0.2s ease; &, .toggle-icon-svg { @@ -135,12 +135,18 @@ } @keyframes animate-enabled { - 0%, 35% { opacity: 0; } + 0%, + + 35% { opacity: 0; } + 100% { opacity: 1; } } @keyframes animate-disabled { - 0%, 35% { opacity: 0; } + 0%, + + 35% { opacity: 0; } + 100% { opacity: 1; } } } diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 1b36c1f4862..55ce0d7004e 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -2,7 +2,7 @@ color: $gl-text-color; word-wrap: break-word; - [dir="auto"] { + [dir='auto'] { text-align: initial; } @@ -224,8 +224,8 @@ } } - a[href*="/uploads/"], - a[href*="storage.googleapis.com/google-code-attachments/"] { + a[href*='/uploads/'], + a[href*='storage.googleapis.com/google-code-attachments/'] { &::before { margin-right: 4px; @@ -233,7 +233,7 @@ font-size: inherit; text-rendering: auto; -webkit-font-smoothing: antialiased; - content: "\f0c6"; + content: '\f0c6'; } &:hover::before { @@ -423,6 +423,7 @@ h4 { /** * form text input i.e. search bar, comments, forms, etc. */ +/* stylelint-disable selector-no-vendor-prefix */ input, textarea { &::-webkit-input-placeholder { @@ -447,5 +448,6 @@ textarea { color: $gl-text-color-tertiary; } } +/* stylelint-enable */ .lh-100 { line-height: 1; } diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 25b272ab3a9..0333b9445c5 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -41,13 +41,13 @@ $t-gray-a-04: rgba($black, 0.04); $t-gray-a-06: rgba($black, 0.06); $t-gray-a-08: rgba($black, 0.08); -$gl-gray-100: #dddddd; -$gl-gray-200: #cccccc; -$gl-gray-350: #aaaaaa; -$gl-gray-400: #999999; -$gl-gray-500: #777777; -$gl-gray-600: #666666; -$gl-gray-700: #555555; +$gl-gray-100: #ddd; +$gl-gray-200: #ccc; +$gl-gray-350: #aaa; +$gl-gray-400: #999; +$gl-gray-500: #777; +$gl-gray-600: #666; +$gl-gray-700: #555; $green-50: #f1fdf6; $green-100: #dcf5e7; @@ -100,7 +100,7 @@ $red-950: #4b140b; $gray-50: #fafafa; $gray-100: #f2f2f2; $gray-200: #dfdfdf; -$gray-300: #cccccc; +$gray-300: #ccc; $gray-400: #bababa; $gray-500: #a7a7a7; $gray-600: #919191; @@ -323,8 +323,8 @@ $line-select-yellow: #fcf8e7; $line-select-yellow-dark: #f0e2bd; $dark-diff-match-bg: rgba(255, 255, 255, 0.3); $dark-diff-match-color: rgba(255, 255, 255, 0.1); -$diff-image-info-color: gray; -$diff-view-modes-color: gray; +$diff-image-info-color: #808080; +$diff-view-modes-color: #808080; $diff-view-modes-border: #c1c1c1; $diff-jagged-border-gradient-color: darken($white-normal, 8%); @@ -343,6 +343,7 @@ $regular-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-San $dropdown-width: 300px; $dropdown-min-height: 40px; $dropdown-max-height: 312px; +$dropdown-max-height-lg: 445px; $dropdown-vertical-offset: 4px; $dropdown-empty-row-bg: rgba(#000, 0.04); $dropdown-shadow-color: rgba(#000, 0.1); diff --git a/app/assets/stylesheets/framework/variables_overrides.scss b/app/assets/stylesheets/framework/variables_overrides.scss index 9b52493fd4d..79d52932719 100644 --- a/app/assets/stylesheets/framework/variables_overrides.scss +++ b/app/assets/stylesheets/framework/variables_overrides.scss @@ -37,7 +37,7 @@ $h6-font-size: 14px; $spacer: $grid-size; $spacers: ( 0: 0, - 1: ($spacer * .5), + 1: ($spacer * 0.5), 2: ($spacer), 3: ($spacer * 2), 4: ($spacer * 3), diff --git a/app/assets/stylesheets/highlight/common.scss b/app/assets/stylesheets/highlight/common.scss index 2b0794759d5..ac3214a07d9 100644 --- a/app/assets/stylesheets/highlight/common.scss +++ b/app/assets/stylesheets/highlight/common.scss @@ -1,4 +1,4 @@ -@import "../framework/variables"; +@import '../framework/variables'; @mixin diff-background($background, $idiff, $border) { background: $background; diff --git a/app/assets/stylesheets/highlight/embedded.scss b/app/assets/stylesheets/highlight/embedded.scss index 44c8a1d39ec..74364ee4ddb 100644 --- a/app/assets/stylesheets/highlight/embedded.scss +++ b/app/assets/stylesheets/highlight/embedded.scss @@ -1,3 +1,3 @@ .code { - @import "white_base"; + @import 'white_base'; } diff --git a/app/assets/stylesheets/highlight/white_base.scss b/app/assets/stylesheets/highlight/white_base.scss index 23ec3380ce9..ee0ec94c636 100644 --- a/app/assets/stylesheets/highlight/white_base.scss +++ b/app/assets/stylesheets/highlight/white_base.scss @@ -1,6 +1,6 @@ /* https://github.com/aahan/pygments-github-style */ -@import "./common"; +@import './common'; /* * White Syntax Colors @@ -37,16 +37,16 @@ $white-kt: #458; $white-m: #099; $white-s: #d14; $white-n: #333; -$white-na: teal; +$white-na: #008080; $white-nb: #0086b3; $white-nc: #458; -$white-no: teal; -$white-ni: purple; +$white-no: #008080; +$white-ni: #800080; $white-ne: #900; $white-nf: #900; $white-nn: #555; -$white-nt: navy; -$white-nv: teal; +$white-nt: #000080; +$white-nv: #008080; $white-w: #bbb; $white-mf: #099; $white-mh: #099; @@ -64,9 +64,9 @@ $white-sr: #009926; $white-s1: #d14; $white-ss: #990073; $white-bp: #999; -$white-vc: teal; -$white-vg: teal; -$white-vi: teal; +$white-vc: #008080; +$white-vg: #008080; +$white-vi: #008080; $white-il: #099; $white-gc-color: #999; $white-gc-bg: #eaf2f5; @@ -77,7 +77,7 @@ $white-gc-bg: #eaf2f5; background-color: $gray-light; } - // Line numbers +// Line numbers .line-numbers, .diff-line-num { background-color: $gray-light; @@ -103,7 +103,6 @@ pre.code, // Diff line .line_holder { - &.match .line_content, .new-nonewline.line_content, .old-nonewline.line_content { @@ -201,25 +200,38 @@ pre .hll { background-color: $white-pre-hll-bg !important; } - // Search result highlight +// Search result highlight span.highlight_word { background-color: $white-highlight !important; } - // Links to URLs, emails, or dependencies +// Links to URLs, emails, or dependencies .line a { color: $white-nb; } .hll { background-color: $white-hll-bg; } -.c { color: $white-c; font-style: italic; } -.err { color: $white-err; background-color: $white-err-bg; } + +.c { color: $white-c; + font-style: italic; } + +.err { color: $white-err; + background-color: $white-err-bg; } .k { font-weight: $gl-font-weight-bold; } .o { font-weight: $gl-font-weight-bold; } -.cm { color: $white-cm; font-style: italic; } -.cp { color: $white-cp; font-weight: $gl-font-weight-bold; } -.c1 { color: $white-c1; font-style: italic; } -.cs { color: $white-cs; font-weight: $gl-font-weight-bold; font-style: italic; } + +.cm { color: $white-cm; + font-style: italic; } + +.cp { color: $white-cp; + font-weight: $gl-font-weight-bold; } + +.c1 { color: $white-c1; + font-style: italic; } + +.cs { color: $white-cs; + font-weight: $gl-font-weight-bold; + font-style: italic; } .gd { color: $white-gd; @@ -248,24 +260,34 @@ span.highlight_word { .go { color: $white-go; } .gp { color: $white-gp; } .gs { font-weight: $gl-font-weight-bold; } -.gu { color: $white-gu; font-weight: $gl-font-weight-bold; } + +.gu { color: $white-gu; + font-weight: $gl-font-weight-bold; } .gt { color: $white-gt; } .kc { font-weight: $gl-font-weight-bold; } .kd { font-weight: $gl-font-weight-bold; } .kn { font-weight: $gl-font-weight-bold; } .kp { font-weight: $gl-font-weight-bold; } .kr { font-weight: $gl-font-weight-bold; } -.kt { color: $white-kt; font-weight: $gl-font-weight-bold; } + +.kt { color: $white-kt; + font-weight: $gl-font-weight-bold; } .m { color: $white-m; } .s { color: $white-s; } .n { color: $white-n; } .na { color: $white-na; } .nb { color: $white-nb; } -.nc { color: $white-nc; font-weight: $gl-font-weight-bold; } + +.nc { color: $white-nc; + font-weight: $gl-font-weight-bold; } .no { color: $white-no; } .ni { color: $white-ni; } -.ne { color: $white-ne; font-weight: $gl-font-weight-bold; } -.nf { color: $white-nf; font-weight: $gl-font-weight-bold; } + +.ne { color: $white-ne; + font-weight: $gl-font-weight-bold; } + +.nf { color: $white-nf; + font-weight: $gl-font-weight-bold; } .nn { color: $white-nn; } .nt { color: $white-nt; } .nv { color: $white-nv; } @@ -291,4 +313,6 @@ span.highlight_word { .vg { color: $white-vg; } .vi { color: $white-vi; } .il { color: $white-il; } -.gc { color: $white-gc-color; background-color: $white-gc-bg; } + +.gc { color: $white-gc-color; + background-color: $white-gc-bg; } diff --git a/app/assets/stylesheets/mailers/highlighted_diff_email.scss b/app/assets/stylesheets/mailers/highlighted_diff_email.scss index 8b234a5a656..33c114838c2 100644 --- a/app/assets/stylesheets/mailers/highlighted_diff_email.scss +++ b/app/assets/stylesheets/mailers/highlighted_diff_email.scss @@ -1,4 +1,4 @@ -@import "framework/variables"; +@import 'framework/variables'; // This file is largely copied from `highlight/white.scss`, but modified to // avoid all descendant selectors (`table td`). This is because the CSS inlining @@ -40,16 +40,16 @@ $highlighted-kt: #458; $highlighted-m: #099; $highlighted-s: #d14; $highlighted-n: #333; -$highlighted-na: teal; +$highlighted-na: #008080; $highlighted-nb: #0086b3; $highlighted-nc: #458; -$highlighted-no: teal; -$highlighted-ni: purple; +$highlighted-no: #008080; +$highlighted-ni: #800080; $highlighted-ne: #900; $highlighted-nf: #900; $highlighted-nn: #555; -$highlighted-nt: navy; -$highlighted-nv: teal; +$highlighted-nt: #000080; +$highlighted-nv: #008080; $highlighted-w: #bbb; $highlighted-mf: #099; $highlighted-mh: #099; @@ -67,9 +67,9 @@ $highlighted-sr: #009926; $highlighted-s1: #d14; $highlighted-ss: #990073; $highlighted-bp: #999; -$highlighted-vc: teal; -$highlighted-vg: teal; -$highlighted-vi: teal; +$highlighted-vc: #008080; +$highlighted-vg: #008080; +$highlighted-vi: #008080; $highlighted-il: #099; $highlighted-gc: #999; $highlighted-gc-bg: #eaf2f5; @@ -151,14 +151,27 @@ span.highlight_word { } .hll { background-color: $highlighted-hll-bg; } -.c { color: $highlighted-c; font-style: italic; } -.err { color: $highlighted-err; background-color: $highlighted-err-bg; } + +.c { color: $highlighted-c; + font-style: italic; } + +.err { color: $highlighted-err; + background-color: $highlighted-err-bg; } .k { font-weight: $gl-font-weight-bold; } .o { font-weight: $gl-font-weight-bold; } -.cm { color: $highlighted-cm; font-style: italic; } -.cp { color: $highlighted-cp; font-weight: $gl-font-weight-bold; } -.c1 { color: $highlighted-c1; font-style: italic; } -.cs { color: $highlighted-cs; font-weight: $gl-font-weight-bold; font-style: italic; } + +.cm { color: $highlighted-cm; + font-style: italic; } + +.cp { color: $highlighted-cp; + font-weight: $gl-font-weight-bold; } + +.c1 { color: $highlighted-c1; + font-style: italic; } + +.cs { color: $highlighted-cs; + font-weight: $gl-font-weight-bold; + font-style: italic; } .gd { color: $highlighted-gd; @@ -187,24 +200,34 @@ span.highlight_word { .go { color: $highlighted-go; } .gp { color: $highlighted-gp; } .gs { font-weight: $gl-font-weight-bold; } -.gu { color: $highlighted-gu; font-weight: $gl-font-weight-bold; } + +.gu { color: $highlighted-gu; + font-weight: $gl-font-weight-bold; } .gt { color: $highlighted-gt; } .kc { font-weight: $gl-font-weight-bold; } .kd { font-weight: $gl-font-weight-bold; } .kn { font-weight: $gl-font-weight-bold; } .kp { font-weight: $gl-font-weight-bold; } .kr { font-weight: $gl-font-weight-bold; } -.kt { color: $highlighted-kt; font-weight: $gl-font-weight-bold; } + +.kt { color: $highlighted-kt; + font-weight: $gl-font-weight-bold; } .m { color: $highlighted-m; } .s { color: $highlighted-s; } .n { color: $highlighted-n; } .na { color: $highlighted-na; } .nb { color: $highlighted-nb; } -.nc { color: $highlighted-nc; font-weight: $gl-font-weight-bold; } + +.nc { color: $highlighted-nc; + font-weight: $gl-font-weight-bold; } .no { color: $highlighted-no; } .ni { color: $highlighted-ni; } -.ne { color: $highlighted-ne; font-weight: $gl-font-weight-bold; } -.nf { color: $highlighted-nf; font-weight: $gl-font-weight-bold; } + +.ne { color: $highlighted-ne; + font-weight: $gl-font-weight-bold; } + +.nf { color: $highlighted-nf; + font-weight: $gl-font-weight-bold; } .nn { color: $highlighted-nn; } .nt { color: $highlighted-nt; } .nv { color: $highlighted-nv; } @@ -230,4 +253,6 @@ span.highlight_word { .vg { color: $highlighted-vg; } .vi { color: $highlighted-vi; } .il { color: $highlighted-il; } -.gc { color: $highlighted-gc; background-color: $highlighted-gc-bg; } + +.gc { color: $highlighted-gc; + background-color: $highlighted-gc-bg; } diff --git a/app/assets/stylesheets/page_bundles/xterm.scss b/app/assets/stylesheets/page_bundles/xterm.scss index 7f040ac9b96..de3f2a1177d 100644 --- a/app/assets/stylesheets/page_bundles/xterm.scss +++ b/app/assets/stylesheets/page_bundles/xterm.scss @@ -6,11 +6,11 @@ $black: #000; $red: #ea1010; - $green: #009900; - $yellow: #999900; + $green: #090; + $yellow: #990; $blue: #0073e6; $magenta: #d411d4; - $cyan: #009999; + $cyan: #099; $white: #ccc; $l-black: #373b41; $l-red: #ff6161; diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss index a9324ba2ed0..81216b2b98e 100644 --- a/app/assets/stylesheets/pages/boards.scss +++ b/app/assets/stylesheets/pages/boards.scss @@ -3,7 +3,6 @@ } .user-can-drag { - cursor: -webkit-grab; cursor: grab; } @@ -12,12 +11,8 @@ opacity: 1 !important; * { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; user-select: none; // !important to make sure no style can override this when dragging - cursor: -webkit-grabbing !important; cursor: grabbing !important; } } @@ -501,7 +496,6 @@ } .add-issues-modal { - display: -webkit-flex; display: flex; position: fixed; top: 0; @@ -513,9 +507,7 @@ } .add-issues-container { - display: -webkit-flex; display: flex; - -webkit-flex-direction: column; flex-direction: column; width: 90vw; height: 85vh; @@ -528,16 +520,12 @@ box-shadow: 0 2px 12px rgba($black, 0.5); .empty-state { - display: -webkit-flex; display: flex; - -webkit-flex: 1; flex: 1; margin-top: 0; &.add-issues-empty-state-filter { - -webkit-flex-direction: column; flex-direction: column; - -webkit-justify-content: center; justify-content: center; } @@ -566,11 +554,9 @@ } .add-issues-search { - display: -webkit-flex; display: flex; .issues-filters { - -webkit-flex: 1; flex: 1; } } @@ -588,9 +574,7 @@ } .add-issues-list { - display: -webkit-flex; display: flex; - -webkit-flex: 1; flex: 1; padding-top: 3px; margin-left: -$gl-vert-padding; @@ -609,7 +593,6 @@ } .add-issues-list-loading { - -webkit-align-self: center; align-self: center; width: 100%; padding-left: $gl-vert-padding; diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index 11966931a6c..670e320dbc2 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -342,11 +342,11 @@ } &.invalid { - @include status-color($gray-dark, color("gray"), $gray-darkest); + @include status-color($gray-dark, color('gray'), $gray-darkest); border-color: $gray-darkest; &:not(span):hover { - color: color("gray"); + color: color('gray'); } } } diff --git a/app/assets/stylesheets/pages/cycle_analytics.scss b/app/assets/stylesheets/pages/cycle_analytics.scss index ec2108b15be..2b932d164a5 100644 --- a/app/assets/stylesheets/pages/cycle_analytics.scss +++ b/app/assets/stylesheets/pages/cycle_analytics.scss @@ -330,7 +330,6 @@ // Custom Styles for stage items .item-build-component { - .item-title { .icon-build-status { float: left; diff --git a/app/assets/stylesheets/pages/diff.scss b/app/assets/stylesheets/pages/diff.scss index d001dff7986..e50db5310a6 100644 --- a/app/assets/stylesheets/pages/diff.scss +++ b/app/assets/stylesheets/pages/diff.scss @@ -9,7 +9,6 @@ @media (min-width: map-get($grid-breakpoints, md)) { $mr-file-header-top: $mr-version-controls-height + $header-height + $mr-tabs-height; - position: -webkit-sticky; position: sticky; top: $mr-file-header-top; z-index: 102; @@ -54,6 +53,10 @@ background-color: $gray-normal; } + a { + color: $gray-700; + } + svg { vertical-align: middle; top: -1px; @@ -239,22 +242,18 @@ img { border: 1px solid $white-light; - background-image: linear-gradient( - 45deg, - $border-color 25%, - transparent 25%, - transparent 75%, - $border-color 75%, - $border-color 100% - ), - linear-gradient( - 45deg, - $border-color 25%, - transparent 25%, - transparent 75%, - $border-color 75%, - $border-color 100% - ); + background-image: linear-gradient(45deg, + $border-color 25%, + transparent 25%, + transparent 75%, + $border-color 75%, + $border-color 100%), + linear-gradient(45deg, + $border-color 25%, + transparent 25%, + transparent 75%, + $border-color 75%, + $border-color 100%); background-size: 10px 10px; background-position: 0 0, 5px 5px; max-width: 100%; @@ -510,10 +509,10 @@ .diff-stats { align-items: center; - padding: 0 .25rem; + padding: 0 0.25rem; .diff-stats-group { - padding: 0 .25rem; + padding: 0 0.25rem; } svg.diff-stats-icon { @@ -522,7 +521,7 @@ &.is-compare-versions-header { .diff-stats-group { - padding: 0 .5rem; + padding: 0 0.5rem; } } } @@ -726,7 +725,6 @@ } @include media-breakpoint-up(sm) { - position: -webkit-sticky; position: sticky; top: $header-height; background-color: $white-light; @@ -834,34 +832,26 @@ width: 100%; height: 10px; background-color: $white-light; - background-image: linear-gradient( - 45deg, - transparent, - transparent 73%, - $diff-jagged-border-gradient-color 75%, - $white-light 80% - ), - linear-gradient( - 225deg, - transparent, - transparent 73%, - $diff-jagged-border-gradient-color 75%, - $white-light 80% - ), - linear-gradient( - 135deg, - transparent, - transparent 73%, - $diff-jagged-border-gradient-color 75%, - $white-light 80% - ), - linear-gradient( - -45deg, - transparent, - transparent 73%, - $diff-jagged-border-gradient-color 75%, - $white-light 80% - ); + background-image: linear-gradient(45deg, + transparent, + transparent 73%, + $diff-jagged-border-gradient-color 75%, + $white-light 80%), + linear-gradient(225deg, + transparent, + transparent 73%, + $diff-jagged-border-gradient-color 75%, + $white-light 80%), + linear-gradient(135deg, + transparent, + transparent 73%, + $diff-jagged-border-gradient-color 75%, + $white-light 80%), + linear-gradient(-45deg, + transparent, + transparent 73%, + $diff-jagged-border-gradient-color 75%, + $white-light 80%); background-position: 5px 5px, 0 5px, 0 5px, 5px 5px; background-size: 10px 10px; background-repeat: repeat; @@ -904,7 +894,7 @@ } } -.files:not([data-can-create-note="true"]) .frame { +.files:not([data-can-create-note='true']) .frame { cursor: auto; } @@ -913,15 +903,14 @@ .btn-transparent.image-diff-overlay-add-comment { position: relative; cursor: image-url('illustrations/image_comment_light_cursor.svg') - $image-comment-cursor-left-offset $image-comment-cursor-top-offset, + $image-comment-cursor-left-offset $image-comment-cursor-top-offset, auto; // Retina cursor - cursor: -webkit-image-set( - image-url('illustrations/image_comment_light_cursor.svg') 1x, - image-url('illustrations/image_comment_light_cursor@2x.svg') 2x - ) - $image-comment-cursor-left-offset $image-comment-cursor-top-offset, + // scss-lint:disable DuplicateProperty + cursor: image-set(image-url('illustrations/image_comment_light_cursor.svg') 1x, + image-url('illustrations/image_comment_light_cursor@2x.svg') 2x) + $image-comment-cursor-left-offset $image-comment-cursor-top-offset, auto; .comment-indicator { @@ -1026,7 +1015,6 @@ } .diff-tree-list { - position: -webkit-sticky; position: sticky; $top-pos: $header-height + $mr-tabs-height + $mr-version-controls-height + 10px; top: $header-height + $mr-tabs-height + $mr-version-controls-height + 10px; diff --git a/app/assets/stylesheets/pages/graph.scss b/app/assets/stylesheets/pages/graph.scss index 83b1680512d..3febf4cf826 100644 --- a/app/assets/stylesheets/pages/graph.scss +++ b/app/assets/stylesheets/pages/graph.scss @@ -71,12 +71,10 @@ .svg-graph-container-with-grab { cursor: grab; - cursor: -webkit-grab; } .svg-graph-container-grabbed { cursor: grabbing; - cursor: -webkit-grabbing; } @keyframes flickerAnimation { diff --git a/app/assets/stylesheets/pages/help.scss b/app/assets/stylesheets/pages/help.scss index 2c23f31c240..161d4dbfb22 100644 --- a/app/assets/stylesheets/pages/help.scss +++ b/app/assets/stylesheets/pages/help.scss @@ -30,7 +30,7 @@ .key { @extend .badge.badge-pill; background-color: $label-inverse-bg; - font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + font: 11px Consolas, 'Liberation Mono', Menlo, Courier, monospace; padding: 3px 5px; } } diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index e0bdc1341b1..623fa485ba6 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -22,6 +22,7 @@ .detail-page-header, .page-content-header, .commit-box, + .info-well, .commit-ci-menu, .files-changed-inner, .limited-header-width, @@ -136,7 +137,7 @@ color: $blue-800; .avatar { - border-color: rgba($gray-normal, .2); + border-color: rgba($gray-normal, 0.2); } } @@ -223,7 +224,7 @@ } a.edit-link:not([href]):hover { - color: rgba($gray-normal, .2); + color: rgba($gray-normal, 0.2); } .lock-edit, // uses same style, different js behaviour @@ -711,14 +712,11 @@ .issuable-list { li { - .issue-box { - display: -webkit-flex; display: flex; } .issuable-info-container { - -webkit-flex: 1; flex: 1; display: flex; padding-right: $gl-padding; @@ -813,7 +811,6 @@ .sidebar-collapsed-icon { - > .stopwatch-svg { display: inline-block; } @@ -871,11 +868,11 @@ } .help-state-toggle-enter-active { - transition: all .8s ease; + transition: all 0.8s ease; } .help-state-toggle-leave-active { - transition: all .5s ease; + transition: all 0.5s ease; } .help-state-toggle-enter, diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 0037364978c..9f30495a7ef 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -58,8 +58,6 @@ form.edit-issue { } ul.related-merge-requests > li { - display: -ms-flexbox; - display: -webkit-flex; display: flex; align-items: center; diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss index 2372640277e..75d219320ef 100644 --- a/app/assets/stylesheets/pages/labels.scss +++ b/app/assets/stylesheets/pages/labels.scss @@ -95,13 +95,11 @@ .prioritized-labels & { box-shadow: 0 1px 2px $issue-boards-card-shadow; cursor: move; - cursor: -webkit-grab; - cursor: -moz-grab; + cursor: grab; border: 0; &:active { - cursor: -webkit-grabbing; - cursor: -moz-grabbing; + cursor: grabbing; } } } diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss index 67d7a8175ac..22a515cbdaa 100644 --- a/app/assets/stylesheets/pages/login.scss +++ b/app/assets/stylesheets/pages/login.scss @@ -120,7 +120,6 @@ } .new-session-tabs { - display: -webkit-flex; display: flex; box-shadow: 0 0 0 1px $border-color; border-top-right-radius: $border-radius-default; @@ -190,7 +189,7 @@ margin-top: 16px; } - input[type="submit"] { + input[type='submit'] { @extend .btn-block; margin-bottom: 0; } diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss index 99609a96976..eb32beb0972 100644 --- a/app/assets/stylesheets/pages/members.scss +++ b/app/assets/stylesheets/pages/members.scss @@ -27,7 +27,6 @@ .controls { @include media-breakpoint-up(sm) { - display: -webkit-flex; display: flex; } diff --git a/app/assets/stylesheets/pages/merge_conflicts.scss b/app/assets/stylesheets/pages/merge_conflicts.scss index e0f7d075fc7..278a9014458 100644 --- a/app/assets/stylesheets/pages/merge_conflicts.scss +++ b/app/assets/stylesheets/pages/merge_conflicts.scss @@ -20,81 +20,81 @@ $colors: ( white-header-not-chosen : #f0f0f0, white-line-not-chosen : $gray-light, - dark-header-head-neutral : rgba(#3f3, .2), - dark-line-head-neutral : rgba(#3f3, .1), + dark-header-head-neutral : rgba(#3f3, 0.2), + dark-line-head-neutral : rgba(#3f3, 0.1), dark-button-head-neutral : #40874f, - dark-header-head-chosen : rgba(#3f3, .33), - dark-line-head-chosen : rgba(#3f3, .2), + dark-header-head-chosen : rgba(#3f3, 0.33), + dark-line-head-chosen : rgba(#3f3, 0.2), dark-button-head-chosen : #258537, - dark-header-origin-neutral : rgba(#2878c9, .4), - dark-line-origin-neutral : rgba(#2878c9, .3), + dark-header-origin-neutral : rgba(#2878c9, 0.4), + dark-line-origin-neutral : rgba(#2878c9, 0.3), dark-button-origin-neutral : #2a5c8c, - dark-header-origin-chosen : rgba(#2878c9, .6), - dark-line-origin-chosen : rgba(#2878c9, .4), + dark-header-origin-chosen : rgba(#2878c9, 0.6), + dark-line-origin-chosen : rgba(#2878c9, 0.4), dark-button-origin-chosen : #1d6cbf, - dark-header-not-chosen : rgba(#fff, .25), - dark-line-not-chosen : rgba(#fff, .1), + dark-header-not-chosen : rgba(#fff, 0.25), + dark-line-not-chosen : rgba(#fff, 0.1), - monokai-header-head-neutral : rgba(#a6e22e, .25), - monokai-line-head-neutral : rgba(#a6e22e, .1), + monokai-header-head-neutral : rgba(#a6e22e, 0.25), + monokai-line-head-neutral : rgba(#a6e22e, 0.1), monokai-button-head-neutral : #376b20, - monokai-header-head-chosen : rgba(#a6e22e, .4), - monokai-line-head-chosen : rgba(#a6e22e, .25), + monokai-header-head-chosen : rgba(#a6e22e, 0.4), + monokai-line-head-chosen : rgba(#a6e22e, 0.25), monokai-button-head-chosen : #39800d, - monokai-header-origin-neutral : rgba(#60d9f1, .35), - monokai-line-origin-neutral : rgba(#60d9f1, .15), + monokai-header-origin-neutral : rgba(#60d9f1, 0.35), + monokai-line-origin-neutral : rgba(#60d9f1, 0.15), monokai-button-origin-neutral : #38848c, - monokai-header-origin-chosen : rgba(#60d9f1, .5), - monokai-line-origin-chosen : rgba(#60d9f1, .35), + monokai-header-origin-chosen : rgba(#60d9f1, 0.5), + monokai-line-origin-chosen : rgba(#60d9f1, 0.35), monokai-button-origin-chosen : #3ea4b2, - monokai-header-not-chosen : rgba(#76715d, .24), - monokai-line-not-chosen : rgba(#76715d, .1), + monokai-header-not-chosen : rgba(#76715d, 0.24), + monokai-line-not-chosen : rgba(#76715d, 0.1), - solarized-light-header-head-neutral : rgba(#859900, .37), - solarized-light-line-head-neutral : rgba(#859900, .2), + solarized-light-header-head-neutral : rgba(#859900, 0.37), + solarized-light-line-head-neutral : rgba(#859900, 0.2), solarized-light-button-head-neutral : #afb262, - solarized-light-header-head-chosen : rgba(#859900, .5), - solarized-light-line-head-chosen : rgba(#859900, .37), + solarized-light-header-head-chosen : rgba(#859900, 0.5), + solarized-light-line-head-chosen : rgba(#859900, 0.37), solarized-light-button-head-chosen : #94993d, - solarized-light-header-origin-neutral : rgba(#2878c9, .37), - solarized-light-line-origin-neutral : rgba(#2878c9, .15), + solarized-light-header-origin-neutral : rgba(#2878c9, 0.37), + solarized-light-line-origin-neutral : rgba(#2878c9, 0.15), solarized-light-button-origin-neutral : #60a1bf, - solarized-light-header-origin-chosen : rgba(#2878c9, .6), - solarized-light-line-origin-chosen : rgba(#2878c9, .37), + solarized-light-header-origin-chosen : rgba(#2878c9, 0.6), + solarized-light-line-origin-chosen : rgba(#2878c9, 0.37), solarized-light-button-origin-chosen : #2482b2, - solarized-light-header-not-chosen : rgba(#839496, .37), - solarized-light-line-not-chosen : rgba(#839496, .2), + solarized-light-header-not-chosen : rgba(#839496, 0.37), + solarized-light-line-not-chosen : rgba(#839496, 0.2), - solarized-dark-header-head-neutral : rgba(#859900, .35), - solarized-dark-line-head-neutral : rgba(#859900, .15), + solarized-dark-header-head-neutral : rgba(#859900, 0.35), + solarized-dark-line-head-neutral : rgba(#859900, 0.15), solarized-dark-button-head-neutral : #376b20, - solarized-dark-header-head-chosen : rgba(#859900, .5), - solarized-dark-line-head-chosen : rgba(#859900, .35), + solarized-dark-header-head-chosen : rgba(#859900, 0.5), + solarized-dark-line-head-chosen : rgba(#859900, 0.35), solarized-dark-button-head-chosen : #39800d, - solarized-dark-header-origin-neutral : rgba(#2878c9, .35), - solarized-dark-line-origin-neutral : rgba(#2878c9, .15), + solarized-dark-header-origin-neutral : rgba(#2878c9, 0.35), + solarized-dark-line-origin-neutral : rgba(#2878c9, 0.15), solarized-dark-button-origin-neutral : #086799, - solarized-dark-header-origin-chosen : rgba(#2878c9, .6), - solarized-dark-line-origin-chosen : rgba(#2878c9, .35), + solarized-dark-header-origin-chosen : rgba(#2878c9, 0.6), + solarized-dark-line-origin-chosen : rgba(#2878c9, 0.35), solarized-dark-button-origin-chosen : #0082cc, - solarized_dark_header_not_chosen : rgba(#839496, .25), - solarized_dark_line_not_chosen : rgba(#839496, .15), + solarized_dark_header_not_chosen : rgba(#839496, 0.25), + solarized_dark_line_not_chosen : rgba(#839496, 0.15), none_header_head_neutral : $gray-normal, none_line_head_neutral : $gray-normal, @@ -210,26 +210,20 @@ $colors: ( } #conflicts { - .white { - @include color-scheme('white') - } + @include color-scheme('white'); } .dark { - @include color-scheme('dark') - } + @include color-scheme('dark'); } .monokai { - @include color-scheme('monokai') - } + @include color-scheme('monokai'); } .solarized-light { - @include color-scheme('solarized-light') - } + @include color-scheme('solarized-light'); } .solarized-dark { - @include color-scheme('solarized-dark') - } + @include color-scheme('solarized-dark'); } .diff-wrap-lines .line_content { white-space: normal; diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index cfd3faab122..e73d1a1289d 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -491,11 +491,9 @@ .merge-request { padding: 10px 0 10px 15px; position: relative; - display: -webkit-flex; display: flex; .issuable-info-container { - -webkit-flex: 1; flex: 1; } @@ -786,7 +784,6 @@ } @include media-breakpoint-up(md) { - position: -webkit-sticky; position: sticky; top: $header-height + $mr-tabs-height; width: 100%; @@ -814,7 +811,6 @@ @include media-breakpoint-up(sm) { position: sticky; - position: -webkit-sticky; } &.affix { diff --git a/app/assets/stylesheets/pages/milestone.scss b/app/assets/stylesheets/pages/milestone.scss index 15f3a2ef4a8..3ca8e943a3a 100644 --- a/app/assets/stylesheets/pages/milestone.scss +++ b/app/assets/stylesheets/pages/milestone.scss @@ -67,18 +67,14 @@ $status-box-line-height: 26px; .card-header { line-height: $line-height-base; padding: 14px 16px; - display: -webkit-flex; display: flex; .title { - -webkit-flex: 1; - -webkit-flex-grow: 1; flex: 1; flex-grow: 2; } .counter { - -webkit-flex: 1; flex: 0; padding-left: 16px; } diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 51f755c67af..3343b55d24b 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -58,7 +58,7 @@ border: 1px solid $border-color; border-radius: $border-radius-base; transition: border-color ease-in-out 0.15s, - box-shadow ease-in-out 0.15s; + box-shadow ease-in-out 0.15s; &.is-focused { @extend .form-control:focus; @@ -72,7 +72,7 @@ &.is-dropzone-hover { border-color: $green-500; box-shadow: 0 0 2px $black-transparent, - 0 0 4px $green-500-focus; + 0 0 4px $green-500-focus; .comment-toolbar, .nav-links { @@ -84,9 +84,7 @@ .md-header .nav-links { display: flex; - display: -webkit-flex; flex-flow: row wrap; - -webkit-flex-flow: row wrap; width: 100%; .float-right { @@ -444,7 +442,7 @@ table { .uploading-error-message { @include media-breakpoint-down(xs) { &::after { - content: "\a"; + content: '\a'; white-space: pre; } } diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 1198b9ea143..72f48e98c24 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -4,7 +4,7 @@ $note-form-margin-left: 72px; @mixin vertical-line($left) { &::before { - content: ""; + content: ''; border-left: 2px solid $gray-100; position: absolute; top: 0; @@ -53,12 +53,12 @@ $note-form-margin-left: 72px; &.note-form { margin-left: 0; - @include notes-media("min", map-get($grid-breakpoints, md)) { + @include notes-media('min', map-get($grid-breakpoints, md)) { margin-left: $note-form-margin-left; } .timeline-icon { - @include notes-media("min", map-get($grid-breakpoints, sm)) { + @include notes-media('min', map-get($grid-breakpoints, sm)) { margin-left: -$note-icon-gutter-width; } } @@ -242,7 +242,7 @@ $note-form-margin-left: 72px; } .note-header { - @include notes-media("max", map-get($grid-breakpoints, xs)) { + @include notes-media('max', map-get($grid-breakpoints, xs)) { .inline { display: block; } @@ -304,7 +304,7 @@ $note-form-margin-left: 72px; } .timeline-content { - @include notes-media("min", map-get($grid-breakpoints, sm)) { + @include notes-media('min', map-get($grid-breakpoints, sm)) { margin-left: 30px; } } @@ -348,7 +348,7 @@ $note-form-margin-left: 72px; } &::after { - content: ""; + content: ''; height: 70px; position: absolute; left: $gl-padding-24; @@ -590,7 +590,7 @@ $note-form-margin-left: 72px; .note-headline-light { display: inline; - @include notes-media("max", map-get($grid-breakpoints, xs)) { + @include notes-media('max', map-get($grid-breakpoints, xs)) { display: block; } } @@ -656,7 +656,7 @@ $note-form-margin-left: 72px; margin-left: 10px; color: $gray-darkest; - @include notes-media("max", map-get($grid-breakpoints, sm) - 1) { + @include notes-media('max', map-get($grid-breakpoints, sm) - 1) { float: none; margin-left: 0; } @@ -775,7 +775,7 @@ $note-form-margin-left: 72px; } .line-resolve-all-container { - @include notes-media("min", map-get($grid-breakpoints, sm)) { + @include notes-media('min', map-get($grid-breakpoints, sm)) { margin-right: 0; } diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index e676d48c1f4..2b6319ddd4f 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -341,13 +341,15 @@ &.builds .ci-table tr { height: 71px; } -} -.build-failures { - th { - border-top: 0; + .ci-table { + thead th { + border-top: 0; + } } +} +.build-failures { .build-state { padding: 20px 2px; @@ -994,7 +996,6 @@ button.mini-pipeline-graph-dropdown-toggle { * Top arrow in the dropdown in the mini pipeline graph */ .mini-pipeline-graph-dropdown-menu { - &::before, &::after { content: ''; diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index a1e847009fc..ab26259c007 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -270,11 +270,9 @@ position: static; padding: 0 16px; margin-bottom: 20px; - display: -webkit-flex; display: flex; .btn { - -webkit-flex-grow: 1; flex-grow: 1; &:first-child { diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss index 277030ad3af..1349845f300 100644 --- a/app/assets/stylesheets/pages/projects.scss +++ b/app/assets/stylesheets/pages/projects.scss @@ -571,9 +571,7 @@ .import-buttons { padding-left: 0; - display: -webkit-flex; display: flex; - -webkit-flex-wrap: wrap; flex-wrap: wrap; .btn { diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss index 149c3254d84..20bdc6596e9 100644 --- a/app/assets/stylesheets/pages/search.scss +++ b/app/assets/stylesheets/pages/search.scss @@ -84,9 +84,7 @@ input[type='checkbox']:hover { .search-icon { transition: color $default-transition-duration; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; + user-select: none; } .clear-icon { @@ -185,13 +183,11 @@ input[type='checkbox']:hover { .search-holder { @include media-breakpoint-up(sm) { - display: -webkit-flex; display: flex; } .search-field-holder, .project-filter-form { - -webkit-flex: 1 0 auto; flex: 1 0 auto; position: relative; margin-right: 0; diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index 811cc310a8f..4f9d96da4bd 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -316,8 +316,4 @@ .push-pull-table { margin-top: 1em; - - .mirror-action-buttons { - padding-right: 0; - } } diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss index 7d59dd3b5d1..f4d568d02ac 100644 --- a/app/assets/stylesheets/pages/status.scss +++ b/app/assets/stylesheets/pages/status.scss @@ -33,7 +33,7 @@ border-color: $gl-text-color; &:not(span):hover { - background-color: rgba($gl-text-color, .07); + background-color: rgba($gl-text-color, 0.07); } } @@ -54,7 +54,7 @@ border-color: $gl-text-color-secondary; &:not(span):hover { - background-color: rgba($gl-text-color-secondary, .07); + background-color: rgba($gl-text-color-secondary, 0.07); } } } diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss index 3fc37e20c36..2a1e8345755 100644 --- a/app/assets/stylesheets/pages/todos.scss +++ b/app/assets/stylesheets/pages/todos.scss @@ -6,9 +6,7 @@ .todos-list > .todo { // workaround because we cannot use border-colapse border-top: 1px solid transparent; - display: -webkit-flex; display: flex; - -webkit-flex-direction: row; flex-direction: row; &:hover { @@ -29,23 +27,18 @@ .todo-avatar, .todo-actions { @include transition(opacity); - -webkit-flex: 0 0 auto; flex: 0 0 auto; } .todo-actions { - display: -webkit-flex; display: flex; - -webkit-justify-content: center; justify-content: center; - -webkit-flex-direction: column; flex-direction: column; margin-left: 10px; min-width: 55px; } .todo-item { - -webkit-flex: 0 1 100%; flex: 0 1 100%; min-width: 0; } @@ -60,13 +53,13 @@ .todo-avatar, .todo-item { - opacity: .6; + opacity: 0.6; } } .todo-avatar, .todo-item { - opacity: .2; + opacity: 0.2; } .btn { @@ -82,7 +75,6 @@ display: flex; > .title-item { - -webkit-flex: 0 0 auto; flex: 0 0 auto; margin: 0 2px; @@ -96,7 +88,6 @@ } .todo-label { - -webkit-flex: 0 1 auto; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; @@ -222,23 +213,19 @@ } .todos-empty { - display: -webkit-flex; display: flex; - -webkit-flex-direction: column; flex-direction: column; max-width: 900px; margin-left: auto; margin-right: auto; @include media-breakpoint-up(sm) { - -webkit-flex-direction: row; flex-direction: row; padding-top: 80px; } } .todos-empty-content { - -webkit-align-self: center; align-self: center; max-width: 480px; margin-right: 20px; @@ -252,7 +239,6 @@ @include media-breakpoint-up(sm) { width: 300px; margin-right: 0; - -webkit-order: 2; order: 2; } } diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss index a46b8679a42..5664f46484e 100644 --- a/app/assets/stylesheets/pages/tree.scss +++ b/app/assets/stylesheets/pages/tree.scss @@ -172,26 +172,6 @@ text-decoration: inherit; } } - - .tree_commit { - max-width: 320px; - - .str-truncated { - max-width: 100%; - } - } - - .tree_time_ago { - min-width: 135px; - } - } - - .tree_author { - padding-right: 8px; - - .commit-author-name { - color: $gl-text-color; - } } .tree-truncated-warning { diff --git a/app/assets/stylesheets/pages/ui_dev_kit.scss b/app/assets/stylesheets/pages/ui_dev_kit.scss index 84c617c7ec0..7744fd814d0 100644 --- a/app/assets/stylesheets/pages/ui_dev_kit.scss +++ b/app/assets/stylesheets/pages/ui_dev_kit.scss @@ -10,7 +10,7 @@ margin-bottom: 15px; &::before { - content: "Example"; + content: 'Example'; color: $ui-dev-kit-example-color; } } diff --git a/app/controllers/admin/appearances_controller.rb b/app/controllers/admin/appearances_controller.rb index 2b9cae21da2..189fee98aa0 100644 --- a/app/controllers/admin/appearances_controller.rb +++ b/app/controllers/admin/appearances_controller.rb @@ -78,6 +78,7 @@ class Admin::AppearancesController < Admin::ApplicationController footer_message message_background_color message_font_color + email_header_and_footer_enabled ] end end diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index 0b6ff491c66..8a00408001e 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Admin::RunnersController < Admin::ApplicationController - before_action :runner, except: :index + before_action :runner, except: [:index, :tag_list] def index finder = Admin::RunnersFinder.new(params: params) @@ -48,6 +48,12 @@ class Admin::RunnersController < Admin::ApplicationController end end + def tag_list + tags = Autocomplete::ActsAsTaggableOn::TagsFinder.new(params: params).execute + + render json: ActsAsTaggableOn::TagSerializer.new.represent(tags) + end + private def runner diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb index c4e7fc950f9..73c744efeba 100644 --- a/app/controllers/clusters/applications_controller.rb +++ b/app/controllers/clusters/applications_controller.rb @@ -3,26 +3,41 @@ class Clusters::ApplicationsController < Clusters::BaseController before_action :cluster before_action :authorize_create_cluster!, only: [:create] + before_action :authorize_update_cluster!, only: [:update] def create - Clusters::Applications::CreateService - .new(@cluster, current_user, create_cluster_application_params) - .execute(request) + request_handler do + Clusters::Applications::CreateService + .new(@cluster, current_user, cluster_application_params) + .execute(request) + end + end + + def update + request_handler do + Clusters::Applications::UpdateService + .new(@cluster, current_user, cluster_application_params) + .execute(request) + end + end + + private + + def request_handler + yield head :no_content - rescue Clusters::Applications::CreateService::InvalidApplicationError + rescue Clusters::Applications::BaseService::InvalidApplicationError render_404 rescue StandardError head :bad_request end - private - def cluster @cluster ||= clusterable.clusters.find(params[:id]) || render_404 end - def create_cluster_application_params + def cluster_application_params params.permit(:application, :hostname, :email) end end diff --git a/app/controllers/concerns/continue_params.rb b/app/controllers/concerns/continue_params.rb index f0e6adf4dec..54c0510497f 100644 --- a/app/controllers/concerns/continue_params.rb +++ b/app/controllers/concerns/continue_params.rb @@ -6,7 +6,7 @@ module ContinueParams def continue_params continue_params = params[:continue] - return nil unless continue_params + return unless continue_params continue_params = continue_params.permit(:to, :notice, :notice_now) continue_params[:to] = safe_redirect_path(continue_params[:to]) diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index cd3fa641e89..05d88429cfe 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -8,7 +8,7 @@ module IssuableActions before_action :authorize_destroy_issuable!, only: :destroy before_action :authorize_admin_issuable!, only: :bulk_update before_action only: :show do - push_frontend_feature_flag(:reply_to_individual_notes) + push_frontend_feature_flag(:reply_to_individual_notes, default_enabled: true) end end diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb index eccbe35577b..c0c0160a827 100644 --- a/app/controllers/concerns/milestone_actions.rb +++ b/app/controllers/concerns/milestone_actions.rb @@ -8,7 +8,7 @@ module MilestoneActions format.html { redirect_to milestone_redirect_path } format.json do render json: tabs_json("shared/milestones/_merge_requests_tab", { - merge_requests: @milestone.sorted_merge_requests, # rubocop:disable Gitlab/ModuleWithInstanceVariables + merge_requests: @milestone.sorted_merge_requests(current_user), # rubocop:disable Gitlab/ModuleWithInstanceVariables show_project_name: true }) end diff --git a/app/controllers/concerns/renders_notes.rb b/app/controllers/concerns/renders_notes.rb index ce36da6b715..18015b1de88 100644 --- a/app/controllers/concerns/renders_notes.rb +++ b/app/controllers/concerns/renders_notes.rb @@ -16,7 +16,7 @@ module RendersNotes private def preload_max_access_for_authors(notes, project) - return nil unless project + return unless project user_ids = notes.map(&:author_id) project.team.max_member_access_for_user_ids(user_ids) diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb index b1d224d026f..b044affd4e8 100644 --- a/app/controllers/dashboard/projects_controller.rb +++ b/app/controllers/dashboard/projects_controller.rb @@ -13,7 +13,13 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController @projects = load_projects(params.merge(non_public: true)) respond_to do |format| - format.html + format.html do + # n+1: https://gitlab.com/gitlab-org/gitlab-ce/issues/37434 + # Also https://gitlab.com/gitlab-org/gitlab-ce/issues/40260 + Gitlab::GitalyClient.allow_n_plus_1_calls do + render + end + end format.atom do load_events render layout: 'xml.atom' diff --git a/app/controllers/google_api/authorizations_controller.rb b/app/controllers/google_api/authorizations_controller.rb index dd9f5af61b3..ed0995e7ffd 100644 --- a/app/controllers/google_api/authorizations_controller.rb +++ b/app/controllers/google_api/authorizations_controller.rb @@ -2,6 +2,10 @@ module GoogleApi class AuthorizationsController < ApplicationController + include Gitlab::Utils::StrongMemoize + + before_action :validate_session_key! + def callback token, expires_at = GoogleApi::CloudPlatform::Client .new(nil, callback_google_api_auth_url) @@ -11,21 +15,27 @@ module GoogleApi session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] = expires_at.to_s - state_redirect_uri = redirect_uri_from_session_key(params[:state]) - - if state_redirect_uri - redirect_to state_redirect_uri - else - redirect_to root_path - end + redirect_to redirect_uri_from_session end private - def redirect_uri_from_session_key(state) - key = GoogleApi::CloudPlatform::Client - .session_key_for_redirect_uri(params[:state]) - session[key] if key + def validate_session_key! + access_denied! unless redirect_uri_from_session.present? + end + + def redirect_uri_from_session + strong_memoize(:redirect_uri_from_session) do + if params[:state].present? + session[session_key_for_redirect_uri(params[:state])] + else + nil + end + end + end + + def session_key_for_redirect_uri(state) + GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(state) end end end diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index 3ef03bc9622..e147d32be2e 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -3,9 +3,16 @@ class GraphqlController < ApplicationController # Unauthenticated users have access to the API for public data skip_before_action :authenticate_user! - prepend_before_action(only: [:execute]) { authenticate_sessionless_user!(:api) } + + # Allow missing CSRF tokens, this would mean that if a CSRF is invalid or missing, + # the user won't be authenticated but can proceed as an anonymous user. + # + # If a CSRF is valid, the user is authenticated. This makes it easier to play + # around in GraphiQL. + protect_from_forgery with: :null_session, only: :execute before_action :check_graphql_feature_flag! + before_action(only: [:execute]) { authenticate_sessionless_user!(:api) } def execute variables = Gitlab::Graphql::Variables.new(params[:variables]).to_h diff --git a/app/controllers/profiles/active_sessions_controller.rb b/app/controllers/profiles/active_sessions_controller.rb index efe7ede5efa..c473023cacb 100644 --- a/app/controllers/profiles/active_sessions_controller.rb +++ b/app/controllers/profiles/active_sessions_controller.rb @@ -2,15 +2,6 @@ class Profiles::ActiveSessionsController < Profiles::ApplicationController def index - @sessions = ActiveSession.list(current_user) - end - - def destroy - ActiveSession.destroy(current_user, params[:id]) - - respond_to do |format| - format.html { redirect_to profile_active_sessions_url, status: :found } - format.js { head :ok } - end + @sessions = ActiveSession.list(current_user).reject(&:is_impersonated) end end diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index e0677ce3fbc..6504fd6c08a 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -17,7 +17,7 @@ class Projects::ApplicationController < ApplicationController def project return @project if @project - return nil unless params[:project_id] || params[:id] + return unless params[:project_id] || params[:id] path = File.join(params[:namespace_id], params[:project_id] || params[:id]) auth_proc = ->(project) { !project.pending_delete? } diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index 9c130af8394..0e3f13045ce 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Projects::AutocompleteSourcesController < Projects::ApplicationController + before_action :authorize_read_milestone!, only: :milestones + def members render json: ::Projects::ParticipantsService.new(@project, current_user).execute(target) end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 77672e7d9fc..0a33856a8d3 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -90,65 +90,21 @@ class Projects::BlobController < Projects::ApplicationController def diff apply_diff_view_cookie! - @blob.load_all_data! - @lines = @blob.present.highlight.lines - - @form = UnfoldForm.new(params.to_unsafe_h) - - @lines = @lines[@form.since - 1..@form.to - 1].map(&:html_safe) - - if @form.bottom? - @match_line = '' - else - lines_length = @lines.length - 1 - line = [@form.since, lines_length].join(',') - @match_line = "@@ -#{line}+#{line} @@" - end + @form = Blobs::UnfoldPresenter.new(blob, params.to_unsafe_h) - # We can keep only 'render_diff_lines' from this conditional when + # keep only json rendering when # https://gitlab.com/gitlab-org/gitlab-ce/issues/44988 is done if rendered_for_merge_request? - render_diff_lines + render json: DiffLineSerializer.new.represent(@form.diff_lines) else + @lines = @form.lines + @match_line = @form.match_line_text render layout: false end end private - # Converts a String array to Gitlab::Diff::Line array - def render_diff_lines - @lines.map! do |line| - # These are marked as context lines but are loaded from blobs. - # We also have context lines loaded from diffs in other places. - diff_line = Gitlab::Diff::Line.new(line, nil, nil, nil, nil) - diff_line.rich_text = line - diff_line - end - - add_match_line - - render json: DiffLineSerializer.new.represent(@lines) - end - - def add_match_line - return unless @form.unfold? - - if @form.bottom? && @form.to < @blob.lines.size - old_pos = @form.to - @form.offset - new_pos = @form.to - elsif @form.since != 1 - old_pos = new_pos = @form.since - end - - # Match line is not needed when it reaches the top limit or bottom limit of the file. - return unless new_pos - - @match_line = Gitlab::Diff::Line.new(@match_line, 'match', nil, old_pos, new_pos) - - @form.bottom? ? @lines.push(@match_line) : @lines.unshift(@match_line) - end - def blob @blob ||= @repository.blob_at(@commit.id, @path) @@ -231,6 +187,8 @@ class Projects::BlobController < Projects::ApplicationController end def validate_diff_params + return if params[:full] + if [:since, :to, :offset].any? { |key| params[key].blank? } head :ok end diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index b13c0ae3967..939a09d4fd2 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -65,7 +65,11 @@ class Projects::CommitController < Projects::ApplicationController # rubocop: enable CodeReuse/ActiveRecord def merge_requests - @merge_requests = @commit.merge_requests.map do |mr| + @merge_requests = MergeRequestsFinder.new( + current_user, + project_id: @project.id, + commit_sha: @commit.sha + ).execute.map do |mr| { iid: mr.iid, path: merge_request_path(mr), title: mr.title } end diff --git a/app/controllers/projects/group_links_controller.rb b/app/controllers/projects/group_links_controller.rb index 7c713c19762..bc942ba9288 100644 --- a/app/controllers/projects/group_links_controller.rb +++ b/app/controllers/projects/group_links_controller.rb @@ -13,9 +13,10 @@ class Projects::GroupLinksController < Projects::ApplicationController group = Group.find(params[:link_group_id]) if params[:link_group_id].present? if group - return render_404 unless can?(current_user, :read_group, group) + result = Projects::GroupLinks::CreateService.new(project, current_user, group_link_create_params).execute(group) + return render_404 if result[:http_status] == 404 - Projects::GroupLinks::CreateService.new(project, current_user, group_link_create_params).execute(group) + flash[:alert] = result[:message] if result[:http_status] == 409 else flash[:alert] = 'Please select a group.' end diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb index 518d41bd3fb..456d2c34768 100644 --- a/app/controllers/projects/merge_requests/diffs_controller.rb +++ b/app/controllers/projects/merge_requests/diffs_controller.rb @@ -46,8 +46,8 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic # rubocop: disable CodeReuse/ActiveRecord def commit - return nil unless commit_id = params[:commit_id].presence - return nil unless @merge_request.all_commits.exists?(sha: commit_id) + return unless commit_id = params[:commit_id].presence + return unless @merge_request.all_commits.exists?(sha: commit_id) @commit ||= @project.commit(commit_id) end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 46a44841c31..2903f7d705b 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -18,6 +18,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo before_action only: [:show] do push_frontend_feature_flag(:diff_tree_filtering, default_enabled: true) + push_frontend_feature_flag(:expand_diff_full_file) end def index diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb index 521ec2acebb..7276964b6e1 100644 --- a/app/controllers/projects/settings/operations_controller.rb +++ b/app/controllers/projects/settings/operations_controller.rb @@ -14,16 +14,37 @@ module Projects def update result = ::Projects::Operations::UpdateService.new(project, current_user, update_params).execute + render_update_response(result) + end + + private + + # overridden in EE + def render_update_response(result) + respond_to do |format| + format.json do + render_update_json_response(result) + end + end + end + + def render_update_json_response(result) if result[:status] == :success flash[:notice] = _('Your changes have been saved') - redirect_to project_settings_operations_path(@project) + render json: { + status: result[:status] + } else - render 'show' + render( + status: result[:http_status] || :bad_request, + json: { + status: result[:status], + message: result[:message] + } + ) end end - private - def error_tracking_setting @error_tracking_setting ||= project.error_tracking_setting || project.build_error_tracking_setting @@ -35,7 +56,14 @@ module Projects # overridden in EE def permitted_project_params - { error_tracking_setting_attributes: [:enabled, :api_url, :token] } + { + error_tracking_setting_attributes: [ + :enabled, + :api_host, + :token, + project: [:slug, :name, :organization_slug, :organization_name] + ] + } end def check_license diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index 519e7439205..568c6e2a852 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -28,13 +28,13 @@ class UploadsController < ApplicationController end def find_model - return nil unless params[:id] + return unless params[:id] upload_model_class.find(params[:id]) end def authorize_access! - return nil unless model + return unless model authorized = case model @@ -54,7 +54,7 @@ class UploadsController < ApplicationController end def authorize_create_access! - return nil unless model + return unless model # for now we support only personal snippets comments authorized = can?(current_user, :comment_personal_snippet, model) diff --git a/app/finders/admin/runners_finder.rb b/app/finders/admin/runners_finder.rb index 8d936b8121c..b2799565f57 100644 --- a/app/finders/admin/runners_finder.rb +++ b/app/finders/admin/runners_finder.rb @@ -11,6 +11,7 @@ class Admin::RunnersFinder < UnionFinder search! filter_by_status! filter_by_runner_type! + filter_by_tag_list! sort! paginate! @@ -44,6 +45,14 @@ class Admin::RunnersFinder < UnionFinder filter_by!(:type_type, Ci::Runner::AVAILABLE_TYPES) end + def filter_by_tag_list! + tag_list = @params[:tag_name].presence + + if tag_list + @runners = @runners.tagged_with(tag_list) + end + end + def sort! @runners = @runners.order_by(sort_key) end diff --git a/app/finders/autocomplete/acts_as_taggable_on/tags_finder.rb b/app/finders/autocomplete/acts_as_taggable_on/tags_finder.rb new file mode 100644 index 00000000000..f38c187799c --- /dev/null +++ b/app/finders/autocomplete/acts_as_taggable_on/tags_finder.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Autocomplete + module ActsAsTaggableOn + class TagsFinder + LIMIT = 20 + + def initialize(params:) + @params = params + end + + def execute + tags = all_tags + tags = filter_by_name(tags) + limit(tags) + end + + private + + def all_tags + ::ActsAsTaggableOn::Tag.all + end + + def filter_by_name(tags) + return tags unless search + return tags.none if search.empty? + + if search.length >= Gitlab::SQL::Pattern::MIN_CHARS_FOR_PARTIAL_MATCHING + tags.named_like(search) + else + tags.named(search) + end + end + + def limit(tags) + tags.limit(LIMIT) # rubocop: disable CodeReuse/ActiveRecord + end + + def search + @params[:search] + end + end + end +end diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb index 5870f158690..072d07e0ed2 100644 --- a/app/finders/issuable_finder.rb +++ b/app/finders/issuable_finder.rb @@ -78,13 +78,15 @@ class IssuableFinder items = init_collection items = filter_items(items) - # This has to be last as we may use a CTE as an optimization fence - # by passing the attempt_group_search_optimizations param and - # enabling the use_cte_for_group_issues_search feature flag + # This has to be last as we use a CTE as an optimization fence + # for counts by passing the force_cte param and enabling the + # attempt_group_search_optimizations feature flag # https://www.postgresql.org/docs/current/static/queries-with.html items = by_search(items) - sort(items) + items = sort(items) unless use_cte_for_count? + + items end def filter_items(items) @@ -117,8 +119,9 @@ class IssuableFinder # # rubocop: disable CodeReuse/ActiveRecord def count_by_state - count_params = params.merge(state: nil, sort: nil) + count_params = params.merge(state: nil, sort: nil, force_cte: true) finder = self.class.new(current_user, count_params) + counts = Hash.new(0) # Searching by label includes a GROUP BY in the query, but ours will be last @@ -128,8 +131,11 @@ class IssuableFinder # # This does not apply when we are using a CTE for the search, as the labels # GROUP BY is inside the subquery in that case, so we set labels_count to 1. + # + # We always use CTE when searching in Groups if the feature flag is enabled, + # but never when searching in Projects. labels_count = label_names.any? ? label_names.count : 1 - labels_count = 1 if use_cte_for_search? + labels_count = 1 if use_cte_for_count? finder.execute.reorder(nil).group(:state).count.each do |key, value| counts[count_key(key)] += value / labels_count @@ -305,27 +311,31 @@ class IssuableFinder def use_subquery_for_search? strong_memoize(:use_subquery_for_search) do - attempt_group_search_optimizations? && - Feature.enabled?(:use_subquery_for_group_issues_search, default_enabled: true) + !force_cte? && attempt_group_search_optimizations? end end - def use_cte_for_search? - strong_memoize(:use_cte_for_search) do - attempt_group_search_optimizations? && - !use_subquery_for_search? && - Feature.enabled?(:use_cte_for_group_issues_search, default_enabled: true) + def use_cte_for_count? + strong_memoize(:use_cte_for_count) do + force_cte? && attempt_group_search_optimizations? end end private + def force_cte? + !!params[:force_cte] + end + def init_collection klass.all end def attempt_group_search_optimizations? - search && Gitlab::Database.postgresql? && params[:attempt_group_search_optimizations] + search && + Gitlab::Database.postgresql? && + params[:attempt_group_search_optimizations] && + Feature.enabled?(:attempt_group_search_optimizations, default_enabled: true) end def count_key(value) @@ -411,7 +421,7 @@ class IssuableFinder def by_search(items) return items unless search - if use_cte_for_search? + if use_cte_for_count? cte = Gitlab::SQL::RecursiveCTE.new(klass.table_name) cte << items diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb index b645011a3c5..93bee3f1488 100644 --- a/app/finders/merge_requests_finder.rb +++ b/app/finders/merge_requests_finder.rb @@ -37,13 +37,20 @@ class MergeRequestsFinder < IssuableFinder end def filter_items(_items) - items = by_source_branch(super) + items = by_commit(super) + items = by_source_branch(items) items = by_wip(items) by_target_branch(items) end private + def by_commit(items) + return items unless params[:commit_sha].presence + + items.by_commit_sha(params[:commit_sha]) + end + def source_branch @source_branch ||= params[:source_branch].presence end diff --git a/app/finders/snippets_finder.rb b/app/finders/snippets_finder.rb index d3774746cb8..bf29f15642d 100644 --- a/app/finders/snippets_finder.rb +++ b/app/finders/snippets_finder.rb @@ -69,6 +69,8 @@ class SnippetsFinder < UnionFinder base.with_optional_visibility(visibility_from_scope).fresh end + private + # Produces a query that retrieves snippets from multiple projects. # # The resulting query will, depending on the user's permissions, include the diff --git a/app/graphql/resolvers/metadata_resolver.rb b/app/graphql/resolvers/metadata_resolver.rb new file mode 100644 index 00000000000..3a79e6434fb --- /dev/null +++ b/app/graphql/resolvers/metadata_resolver.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Resolvers + class MetadataResolver < BaseResolver + type Types::MetadataType, null: false + + def resolve(**args) + { version: Gitlab::VERSION, revision: Gitlab.revision } + end + end +end diff --git a/app/graphql/types/metadata_type.rb b/app/graphql/types/metadata_type.rb new file mode 100644 index 00000000000..2d8bad0614b --- /dev/null +++ b/app/graphql/types/metadata_type.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Types + class MetadataType < ::Types::BaseObject + graphql_name 'Metadata' + + field :version, GraphQL::STRING_TYPE, null: false + field :revision, GraphQL::STRING_TYPE, null: false + end +end diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 3ef0cc5020c..b96c2f3afb2 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -16,7 +16,6 @@ module Types field :description, GraphQL::STRING_TYPE, null: true - field :default_branch, GraphQL::STRING_TYPE, null: true field :tag_list, GraphQL::STRING_TYPE, null: true field :ssh_url_to_repo, GraphQL::STRING_TYPE, null: true @@ -59,7 +58,6 @@ module Types end field :import_status, GraphQL::STRING_TYPE, null: true - field :ci_config_path, GraphQL::STRING_TYPE, null: true field :only_allow_merge_if_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 954bcc0a5a3..472fe5d6ec2 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Types - class QueryType < BaseObject + class QueryType < ::Types::BaseObject graphql_name 'Query' field :project, Types::ProjectType, @@ -10,6 +10,14 @@ module Types description: "Find a project", authorize: :read_project + field :metadata, Types::MetadataType, + null: true, + resolver: Resolvers::MetadataResolver, + description: 'Metadata about GitLab' do |*args| + + authorize :read_instance_metadata + end + field :echo, GraphQL::STRING_TYPE, null: false, function: Functions::Echo.new end end diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb index 023e44258b7..c0db9910143 100644 --- a/app/helpers/appearances_helper.rb +++ b/app/helpers/appearances_helper.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true module AppearancesHelper + include MarkupHelper + def brand_title current_appearance&.title.presence || default_brand_title end @@ -47,7 +49,7 @@ module AppearancesHelper class_names = [] class_names << 'with-performance-bar' if performance_bar_enabled? - render_message(:header_message, class_names) + render_message(:header_message, class_names: class_names) end def footer_message @@ -58,10 +60,10 @@ module AppearancesHelper private - def render_message(field_sym, class_names = []) + def render_message(field_sym, class_names: [], style: message_style) class_names << field_sym.to_s.dasherize - content_tag :div, class: class_names, style: message_style do + content_tag :div, class: class_names, style: style do markdown_field(current_appearance, field_sym) end end diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 06beeebe2ba..3e1bb9af5cc 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -37,7 +37,7 @@ module BlobHelper end def ide_edit_button(project = @project, ref = @ref, path = @path, options = {}) - return unless Feature.enabled?(:web_ide_default) + return if Feature.enabled?(:web_ide_default) return unless blob = readable_blob(options, path, project, ref) edit_button_tag(blob, diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 923a06a0512..355b91a8661 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -100,17 +100,6 @@ module CiStatusHelper "pipeline-status/#{pipeline_status.sha}-#{pipeline_status.status}" end - def render_project_pipeline_status(pipeline_status, tooltip_placement: 'left') - project = pipeline_status.project - path = pipelines_project_commit_path(project, pipeline_status.sha, ref: pipeline_status.ref) - - render_status_with_link( - 'commit', - pipeline_status.status, - path, - tooltip_placement: tooltip_placement) - end - def render_commit_status(commit, ref: nil, tooltip_placement: 'left') project = commit.project path = pipelines_project_commit_path(project, commit, ref: ref) @@ -123,12 +112,6 @@ module CiStatusHelper icon_size: 24) end - def render_pipeline_status(pipeline, tooltip_placement: 'left') - project = pipeline.project - path = project_pipeline_path(project, pipeline) - render_status_with_link('pipeline', pipeline.status, path, tooltip_placement: tooltip_placement) - end - def render_status_with_link(type, status, path = nil, tooltip_placement: 'left', cssclass: '', container: 'body', icon_size: 16) klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}" title = "#{type.titleize}: #{ci_label_for_status(status)}" diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index dedc58f482b..96471d15aac 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -131,4 +131,42 @@ module EmailsHelper project.id.to_s + "." + project_path_as_domain + "." + Gitlab.config.gitlab.host end + + def html_header_message + return unless show_header? + + render_message(:header_message, style: '') + end + + def html_footer_message + return unless show_footer? + + render_message(:footer_message, style: '') + end + + def text_header_message + return unless show_header? + + strip_tags(render_message(:header_message, style: '')) + end + + def text_footer_message + return unless show_footer? + + strip_tags(render_message(:footer_message, style: '')) + end + + private + + def show_footer? + email_header_and_footer_enabled? && current_appearance&.show_footer? + end + + def show_header? + email_header_and_footer_enabled? && current_appearance&.show_header? + end + + def email_header_and_footer_enabled? + current_appearance&.email_header_and_footer_enabled? + end end diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index af28e6fcb93..0622cdfc196 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -191,7 +191,7 @@ module IssuablesHelper output << content_tag(:strong) do author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "d-none d-sm-inline") - author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-block d-sm-none") + author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "d-inline d-sm-none") if status = user_status(issuable.author) author_output << "#{status}".html_safe diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb index 66f4b7b3f30..d83c69603a9 100644 --- a/app/helpers/markup_helper.rb +++ b/app/helpers/markup_helper.rb @@ -74,7 +74,7 @@ module MarkupHelper # the tag contents are truncated without removing the closing tag. def first_line_in_markdown(object, attribute, max_chars = nil, options = {}) md = markdown_field(object, attribute, options) - return nil unless md.present? + return unless md.present? tags = %w(a gl-emoji b pre code p span) tags << 'img' if options[:allow_images] diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 23d7aa427bb..991ca42c445 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -29,7 +29,7 @@ module MergeRequestsHelper def ci_build_details_path(merge_request) build_url = merge_request.source_project.ci_service.build_page(merge_request.diff_head_sha, merge_request.source_branch) - return nil unless build_url + return unless build_url parsed_url = URI.parse(build_url) @@ -92,7 +92,7 @@ module MergeRequestsHelper end def version_index(merge_request_diff) - return nil if @merge_request_diffs.empty? + return if @merge_request_diffs.empty? @merge_request_diffs.size - @merge_request_diffs.index(merge_request_diff) end @@ -149,7 +149,7 @@ module MergeRequestsHelper def merge_request_source_project_for_project(project = @project) unless can?(current_user, :create_merge_request_in, project) - return nil + return end if can?(current_user, :create_merge_request_from, project) diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index aaf38cbfe70..a50137bea3d 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -122,7 +122,7 @@ module NotesHelper end def new_form_url - return nil unless @snippet.is_a?(PersonalSnippet) + return unless @snippet.is_a?(PersonalSnippet) snippet_notes_path(@snippet) end diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb index eed529f93db..766508b6609 100644 --- a/app/helpers/preferences_helper.rb +++ b/app/helpers/preferences_helper.rb @@ -46,7 +46,8 @@ module PreferencesHelper def first_day_of_week_choices [ [_('Sunday'), 0], - [_('Monday'), 1] + [_('Monday'), 1], + [_('Saturday'), 6] ] end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index c400302cda3..2ac8ddc5244 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -284,6 +284,20 @@ module ProjectsHelper can?(current_user, :read_environment, @project) end + def error_tracking_setting_project_json + setting = @project.error_tracking_setting + + return if setting.blank? || setting.project_slug.blank? || + setting.organization_slug.blank? + + { + name: setting.project_name, + organization_name: setting.organization_name, + organization_slug: setting.organization_slug, + slug: setting.project_slug + }.to_json + end + private def get_project_nav_tabs(project, current_user) diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index e2879bfdcf1..c5bab877c00 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -136,18 +136,9 @@ module TreeHelper end # returns the relative path of the first subdir that doesn't have only one directory descendant - # rubocop: disable CodeReuse/ActiveRecord def flatten_tree(root_path, tree) - return tree.flat_path.sub(%r{\A#{Regexp.escape(root_path)}/}, '') if tree.flat_path.present? - - subtree = Gitlab::Git::Tree.where(@repository, @commit.id, tree.path) - if subtree.count == 1 && subtree.first.dir? - return tree_join(tree.name, flatten_tree(root_path, subtree.first)) - else - return tree.name - end + tree.flat_path.sub(%r{\A#{Regexp.escape(root_path)}/}, '') end - # rubocop: enable CodeReuse/ActiveRecord def selected_branch @branch_name || tree_edit_branch diff --git a/app/helpers/user_callouts_helper.rb b/app/helpers/user_callouts_helper.rb index 1ad7bb81784..5d658d35107 100644 --- a/app/helpers/user_callouts_helper.rb +++ b/app/helpers/user_callouts_helper.rb @@ -17,6 +17,9 @@ module UserCalloutsHelper render 'shared/flash_user_callout', flash_type: flash_type, message: message, feature_name: feature_name end + def render_dashboard_gold_trial(user) + end + private def user_dismissed?(feature_name) diff --git a/app/mailers/abuse_report_mailer.rb b/app/mailers/abuse_report_mailer.rb index e032f568913..e0aa66e6de3 100644 --- a/app/mailers/abuse_report_mailer.rb +++ b/app/mailers/abuse_report_mailer.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true class AbuseReportMailer < BaseMailer + layout 'empty_mailer' + + helper EmailsHelper + def notify(abuse_report_id) return unless deliverable? diff --git a/app/mailers/email_rejection_mailer.rb b/app/mailers/email_rejection_mailer.rb index 45fc5a6c383..d743533b1bc 100644 --- a/app/mailers/email_rejection_mailer.rb +++ b/app/mailers/email_rejection_mailer.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true class EmailRejectionMailer < BaseMailer + layout 'empty_mailer' + + helper EmailsHelper + def rejection(reason, original_raw, can_retry = false) @reason = reason @original_message = Mail::Message.new(original_raw) diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb index 654ae211310..d2e334fb856 100644 --- a/app/mailers/emails/issues.rb +++ b/app/mailers/emails/issues.rb @@ -74,6 +74,7 @@ module Emails @new_issue = new_issue @new_project = new_issue.project + @can_access_project = recipient.can?(:read_project, @new_project) mail_answer_thread(issue, issue_thread_options(updated_by_user.id, recipient.id, reason)) end diff --git a/app/mailers/emails/pipelines.rb b/app/mailers/emails/pipelines.rb index 31e183640ad..fb57c0da34d 100644 --- a/app/mailers/emails/pipelines.rb +++ b/app/mailers/emails/pipelines.rb @@ -15,7 +15,7 @@ module Emails def pipeline_mail(pipeline, recipients, status) @project = pipeline.project @pipeline = pipeline - @merge_request = pipeline.merge_requests.first + @merge_request = pipeline.merge_requests_as_head_pipeline.first add_headers # We use bcc here because we don't want to generate this emails for a diff --git a/app/mailers/repository_check_mailer.rb b/app/mailers/repository_check_mailer.rb index 145169be8a6..a24d3476d0e 100644 --- a/app/mailers/repository_check_mailer.rb +++ b/app/mailers/repository_check_mailer.rb @@ -2,6 +2,10 @@ class RepositoryCheckMailer < BaseMailer # rubocop: disable CodeReuse/ActiveRecord + layout 'empty_mailer' + + helper EmailsHelper + def notify(failed_count) @message = if failed_count == 1 diff --git a/app/models/active_session.rb b/app/models/active_session.rb index 0d9c6a4a1f0..1e01f1d17e6 100644 --- a/app/models/active_session.rb +++ b/app/models/active_session.rb @@ -5,7 +5,8 @@ class ActiveSession attr_accessor :created_at, :updated_at, :session_id, :ip_address, - :browser, :os, :device_name, :device_type + :browser, :os, :device_name, :device_type, + :is_impersonated def current?(session) return false if session_id.nil? || session.id.nil? @@ -31,7 +32,8 @@ class ActiveSession device_type: client.device_type, created_at: user.current_sign_in_at || timestamp, updated_at: timestamp, - session_id: session_id + session_id: session_id, + is_impersonated: request.session[:impersonator_id].present? ) redis.pipelined do diff --git a/app/models/appearance.rb b/app/models/appearance.rb index b9ad676ca47..bdee9b2b73c 100644 --- a/app/models/appearance.rb +++ b/app/models/appearance.rb @@ -20,6 +20,7 @@ class Appearance < ActiveRecord::Base default_value_for :message_background_color, '#E75E40' default_value_for :message_font_color, '#FFFFFF' + default_value_for :email_header_and_footer_enabled, false mount_uploader :logo, AttachmentUploader mount_uploader :header_logo, AttachmentUploader diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index daadf9427ba..c5035797621 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -7,7 +7,7 @@ class ApplicationSetting < ActiveRecord::Base include IgnorableColumn include ChronicDurationAttribute - add_authentication_token_field :runners_registration_token, encrypted: true, fallback: true + add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption) ? :optional : :required } add_authentication_token_field :health_check_access_token DOMAIN_LIST_SEPARATOR = %r{\s*[,;]\s* # comma or semicolon, optionally surrounded by whitespace diff --git a/app/models/board_group_recent_visit.rb b/app/models/board_group_recent_visit.rb index 92abbb67222..f5b75270595 100644 --- a/app/models/board_group_recent_visit.rb +++ b/app/models/board_group_recent_visit.rb @@ -10,7 +10,7 @@ class BoardGroupRecentVisit < ActiveRecord::Base validates :group, presence: true validates :board, presence: true - scope :by_user_group, -> (user, group) { where(user: user, group: group).order(:updated_at) } + scope :by_user_group, -> (user, group) { where(user: user, group: group) } def self.visited!(user, board) visit = find_or_create_by(user: user, group: board.group, board: board) @@ -19,7 +19,10 @@ class BoardGroupRecentVisit < ActiveRecord::Base retry end - def self.latest(user, group) - by_user_group(user, group).last + def self.latest(user, group, count: nil) + visits = by_user_group(user, group).order(updated_at: :desc) + visits = visits.preload(:board) if count && count > 1 + + visits.first(count) end end diff --git a/app/models/board_project_recent_visit.rb b/app/models/board_project_recent_visit.rb index 7cffff906d8..2a1b14b3ae0 100644 --- a/app/models/board_project_recent_visit.rb +++ b/app/models/board_project_recent_visit.rb @@ -10,7 +10,7 @@ class BoardProjectRecentVisit < ActiveRecord::Base validates :project, presence: true validates :board, presence: true - scope :by_user_project, -> (user, project) { where(user: user, project: project).order(:updated_at) } + scope :by_user_project, -> (user, project) { where(user: user, project: project) } def self.visited!(user, board) visit = find_or_create_by(user: user, project: board.project, board: board) @@ -19,7 +19,10 @@ class BoardProjectRecentVisit < ActiveRecord::Base retry end - def self.latest(user, project) - by_user_project(user, project).last + def self.latest(user, project, count: nil) + visits = by_user_project(user, project).order(updated_at: :desc) + visits = visits.preload(:board) if count && count > 1 + + visits.first(count) end end diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb index 5450d40ea95..0d8d7d95791 100644 --- a/app/models/ci/bridge.rb +++ b/app/models/ci/bridge.rb @@ -3,14 +3,18 @@ module Ci class Bridge < CommitStatus include Ci::Processable + include Ci::Contextable include Importable include AfterCommitQueue + include HasRef include Gitlab::Utils::StrongMemoize belongs_to :project belongs_to :trigger_request validates :ref, presence: true + delegate :merge_request_event?, to: :pipeline + def self.retry(bridge, current_user) raise NotImplementedError end @@ -37,11 +41,11 @@ module Ci false end - def expanded_environment_name + def runnable? + false end - def predefined_variables - raise NotImplementedError + def expanded_environment_name end def execute_hooks diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index c902e49ee6d..a64c6051f95 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -5,6 +5,7 @@ module Ci prepend ArtifactMigratable include Ci::Processable include Ci::Metadatable + include Ci::Contextable include TokenAuthenticatable include AfterCommitQueue include ObjectStorage::BackgroundMove @@ -46,7 +47,7 @@ module Ci delegate :terminal_specification, to: :runner_session, allow_nil: true delegate :gitlab_deploy_token, to: :project delegate :trigger_short_token, to: :trigger_request, allow_nil: true - delegate :merge_request?, to: :pipeline + delegate :merge_request_event?, to: :pipeline ## # Since Gitlab 11.5, deployments records started being created right after @@ -137,7 +138,7 @@ module Ci acts_as_taggable - add_authentication_token_field :token, encrypted: true, fallback: true + add_authentication_token_field :token, encrypted: :optional before_save :update_artifacts_size, if: :artifacts_file_changed? before_save :ensure_token @@ -289,6 +290,10 @@ module Ci self.name == 'pages' end + def runnable? + true + end + def archived? return true if degenerated? @@ -398,46 +403,6 @@ module Ci options&.dig(:environment, :on_stop) end - # A slugified version of the build ref, suitable for inclusion in URLs and - # domain names. Rules: - # - # * Lowercased - # * Anything not matching [a-z0-9-] is replaced with a - - # * Maximum length is 63 bytes - # * First/Last Character is not a hyphen - def ref_slug - Gitlab::Utils.slugify(ref.to_s) - end - - ## - # Variables in the environment name scope. - # - def scoped_variables(environment: expanded_environment_name) - Gitlab::Ci::Variables::Collection.new.tap do |variables| - variables.concat(predefined_variables) - variables.concat(project.predefined_variables) - variables.concat(pipeline.predefined_variables) - variables.concat(runner.predefined_variables) if runner - variables.concat(project.deployment_variables(environment: environment)) if environment - variables.concat(yaml_variables) - variables.concat(user_variables) - variables.concat(secret_group_variables) - variables.concat(secret_project_variables(environment: environment)) - variables.concat(trigger_request.user_variables) if trigger_request - variables.concat(pipeline.variables) - variables.concat(pipeline.pipeline_schedule.job_variables) if pipeline.pipeline_schedule - end - end - - ## - # Variables that do not depend on the environment name. - # - def simple_variables - strong_memoize(:simple_variables) do - scoped_variables(environment: nil).to_runner_variables - end - end - ## # All variables, including persisted environment variables. # @@ -451,12 +416,46 @@ module Ci end end - ## - # Regular Ruby hash of scoped variables, without duplicates that are - # possible to be present in an array of hashes returned from `variables`. - # - def scoped_variables_hash - scoped_variables.to_hash + CI_REGISTRY_USER = 'gitlab-ci-token'.freeze + + def persisted_variables + Gitlab::Ci::Variables::Collection.new.tap do |variables| + break variables unless persisted? + + variables + .concat(pipeline.persisted_variables) + .append(key: 'CI_JOB_ID', value: id.to_s) + .append(key: 'CI_JOB_URL', value: Gitlab::Routing.url_helpers.project_job_url(project, self)) + .append(key: 'CI_JOB_TOKEN', value: token.to_s, public: false) + .append(key: 'CI_BUILD_ID', value: id.to_s) + .append(key: 'CI_BUILD_TOKEN', value: token.to_s, public: false) + .append(key: 'CI_REGISTRY_USER', value: CI_REGISTRY_USER) + .append(key: 'CI_REGISTRY_PASSWORD', value: token.to_s, public: false) + .append(key: 'CI_REPOSITORY_URL', value: repo_url.to_s, public: false) + .concat(deploy_token_variables) + end + end + + def persisted_environment_variables + Gitlab::Ci::Variables::Collection.new.tap do |variables| + break variables unless persisted? && persisted_environment.present? + + variables.concat(persisted_environment.predefined_variables) + + # Here we're passing unexpanded environment_url for runner to expand, + # and we need to make sure that CI_ENVIRONMENT_NAME and + # CI_ENVIRONMENT_SLUG so on are available for the URL be expanded. + variables.append(key: 'CI_ENVIRONMENT_URL', value: environment_url) if environment_url + end + end + + def deploy_token_variables + Gitlab::Ci::Variables::Collection.new.tap do |variables| + break variables unless gitlab_deploy_token + + variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.username) + variables.append(key: 'CI_DEPLOY_PASSWORD', value: gitlab_deploy_token.token, public: false) + end end def features @@ -634,27 +633,6 @@ module Ci super || project.try(:build_coverage_regex) end - def user_variables - Gitlab::Ci::Variables::Collection.new.tap do |variables| - break variables if user.blank? - - variables.append(key: 'GITLAB_USER_ID', value: user.id.to_s) - variables.append(key: 'GITLAB_USER_EMAIL', value: user.email) - variables.append(key: 'GITLAB_USER_LOGIN', value: user.username) - variables.append(key: 'GITLAB_USER_NAME', value: user.name) - end - end - - def secret_group_variables - return [] unless project.group - - project.group.ci_variables_for(git_ref, project) - end - - def secret_project_variables(environment: persisted_environment) - project.ci_variables_for(ref: git_ref, environment: environment) - end - def steps [Gitlab::Ci::Build::Step.from_commands(self), Gitlab::Ci::Build::Step.from_after_script(self)].compact @@ -757,7 +735,7 @@ module Ci # Virtual deployment status depending on the environment status. def deployment_status - return nil unless starts_environment? + return unless starts_environment? if success? return successful_deployment_status @@ -814,89 +792,6 @@ module Ci @unscoped_project ||= Project.unscoped.find_by(id: project_id) end - CI_REGISTRY_USER = 'gitlab-ci-token'.freeze - - def persisted_variables - Gitlab::Ci::Variables::Collection.new.tap do |variables| - break variables unless persisted? - - variables - .concat(pipeline.persisted_variables) - .append(key: 'CI_JOB_ID', value: id.to_s) - .append(key: 'CI_JOB_URL', value: Gitlab::Routing.url_helpers.project_job_url(project, self)) - .append(key: 'CI_JOB_TOKEN', value: token.to_s, public: false) - .append(key: 'CI_BUILD_ID', value: id.to_s) - .append(key: 'CI_BUILD_TOKEN', value: token.to_s, public: false) - .append(key: 'CI_REGISTRY_USER', value: CI_REGISTRY_USER) - .append(key: 'CI_REGISTRY_PASSWORD', value: token.to_s, public: false) - .append(key: 'CI_REPOSITORY_URL', value: repo_url.to_s, public: false) - .concat(deploy_token_variables) - end - end - - def predefined_variables # rubocop:disable Metrics/AbcSize - Gitlab::Ci::Variables::Collection.new.tap do |variables| - variables.append(key: 'CI', value: 'true') - variables.append(key: 'GITLAB_CI', value: 'true') - variables.append(key: 'GITLAB_FEATURES', value: project.licensed_features.join(',')) - variables.append(key: 'CI_SERVER_NAME', value: 'GitLab') - variables.append(key: 'CI_SERVER_VERSION', value: Gitlab::VERSION) - variables.append(key: 'CI_SERVER_VERSION_MAJOR', value: Gitlab.version_info.major.to_s) - variables.append(key: 'CI_SERVER_VERSION_MINOR', value: Gitlab.version_info.minor.to_s) - variables.append(key: 'CI_SERVER_VERSION_PATCH', value: Gitlab.version_info.patch.to_s) - variables.append(key: 'CI_SERVER_REVISION', value: Gitlab.revision) - variables.append(key: 'CI_JOB_NAME', value: name) - variables.append(key: 'CI_JOB_STAGE', value: stage) - variables.append(key: 'CI_COMMIT_SHA', value: sha) - variables.append(key: 'CI_COMMIT_SHORT_SHA', value: short_sha) - variables.append(key: 'CI_COMMIT_BEFORE_SHA', value: before_sha) - variables.append(key: 'CI_COMMIT_REF_NAME', value: ref) - variables.append(key: 'CI_COMMIT_REF_SLUG', value: ref_slug) - variables.append(key: "CI_COMMIT_TAG", value: ref) if tag? - variables.append(key: "CI_PIPELINE_TRIGGERED", value: 'true') if trigger_request - variables.append(key: "CI_JOB_MANUAL", value: 'true') if action? - variables.append(key: "CI_NODE_INDEX", value: self.options[:instance].to_s) if self.options&.include?(:instance) - variables.append(key: "CI_NODE_TOTAL", value: (self.options&.dig(:parallel) || 1).to_s) - variables.concat(legacy_variables) - end - end - - def legacy_variables - Gitlab::Ci::Variables::Collection.new.tap do |variables| - variables.append(key: 'CI_BUILD_REF', value: sha) - variables.append(key: 'CI_BUILD_BEFORE_SHA', value: before_sha) - variables.append(key: 'CI_BUILD_REF_NAME', value: ref) - variables.append(key: 'CI_BUILD_REF_SLUG', value: ref_slug) - variables.append(key: 'CI_BUILD_NAME', value: name) - variables.append(key: 'CI_BUILD_STAGE', value: stage) - variables.append(key: "CI_BUILD_TAG", value: ref) if tag? - variables.append(key: "CI_BUILD_TRIGGERED", value: 'true') if trigger_request - variables.append(key: "CI_BUILD_MANUAL", value: 'true') if action? - end - end - - def persisted_environment_variables - Gitlab::Ci::Variables::Collection.new.tap do |variables| - break variables unless persisted? && persisted_environment.present? - - variables.concat(persisted_environment.predefined_variables) - - # Here we're passing unexpanded environment_url for runner to expand, - # and we need to make sure that CI_ENVIRONMENT_NAME and - # CI_ENVIRONMENT_SLUG so on are available for the URL be expanded. - variables.append(key: 'CI_ENVIRONMENT_URL', value: environment_url) if environment_url - end - end - - def deploy_token_variables - Gitlab::Ci::Variables::Collection.new.tap do |variables| - break variables unless gitlab_deploy_token - - variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.username) - variables.append(key: 'CI_DEPLOY_PASSWORD', value: gitlab_deploy_token.token, public: false) - end - end - def environment_url options&.dig(:environment, :url) || persisted_environment&.external_url end diff --git a/app/models/ci/build_trace_chunk.rb b/app/models/ci/build_trace_chunk.rb index 33e61cd2111..75017f224a0 100644 --- a/app/models/ci/build_trace_chunk.rb +++ b/app/models/ci/build_trace_chunk.rb @@ -115,7 +115,7 @@ module Ci current_data = get_data unless current_data&.bytesize.to_i == CHUNK_SIZE - raise FailedToPersistDataError, 'Data is not fullfilled in a bucket' + raise FailedToPersistDataError, 'Data is not fulfilled in a bucket' end old_store_class = self.class.get_store_class(data_store) diff --git a/app/models/ci/group_variable.rb b/app/models/ci/group_variable.rb index 492d1d0329e..323ff560564 100644 --- a/app/models/ci/group_variable.rb +++ b/app/models/ci/group_variable.rb @@ -5,6 +5,7 @@ module Ci extend Gitlab::Ci::Model include HasVariable include Presentable + include Maskable belongs_to :group, class_name: "::Group" diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index d4586219333..ca9725f7a04 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -39,7 +39,7 @@ module Ci # Merge requests for which the current pipeline is running against # the merge request's latest commit. - has_many :merge_requests, foreign_key: "head_pipeline_id" + has_many :merge_requests_as_head_pipeline, foreign_key: "head_pipeline_id", class_name: 'MergeRequest' has_many :pending_builds, -> { pending }, foreign_key: :commit_id, class_name: 'Ci::Build' has_many :retryable_builds, -> { latest.failed_or_canceled.includes(:project) }, foreign_key: :commit_id, class_name: 'Ci::Build' @@ -60,9 +60,9 @@ module Ci validates :sha, presence: { unless: :importing? } validates :ref, presence: { unless: :importing? } - validates :merge_request, presence: { if: :merge_request? } - validates :merge_request, absence: { unless: :merge_request? } - validates :tag, inclusion: { in: [false], if: :merge_request? } + validates :merge_request, presence: { if: :merge_request_event? } + validates :merge_request, absence: { unless: :merge_request_event? } + validates :tag, inclusion: { in: [false], if: :merge_request_event? } validates :status, presence: { unless: :importing? } validate :valid_commit_sha, unless: :importing? validates :source, exclusion: { in: %w(unknown), unless: :importing? }, on: :create @@ -179,7 +179,7 @@ module Ci scope :sort_by_merge_request_pipelines, -> do sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC' - query = ActiveRecord::Base.send(:sanitize_sql_array, [sql, sources[:merge_request]]) # rubocop:disable GitlabSecurity/PublicSend + query = ActiveRecord::Base.send(:sanitize_sql_array, [sql, sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend order(query) end @@ -196,7 +196,7 @@ module Ci end scope :triggered_by_merge_request, -> (merge_request) do - where(source: :merge_request, merge_request: merge_request) + where(source: :merge_request_event, merge_request: merge_request) end scope :detached_merge_request_pipelines, -> (merge_request) do @@ -417,10 +417,6 @@ module Ci @commit ||= Commit.lazy(project, sha) end - def branch? - super && !merge_request? - end - def stuck? pending_builds.any?(&:stuck?) end @@ -643,7 +639,7 @@ module Ci variables.append(key: 'CI_COMMIT_TITLE', value: git_commit_full_title.to_s) variables.append(key: 'CI_COMMIT_DESCRIPTION', value: git_commit_description.to_s) - if merge_request? && merge_request + if merge_request_event? && merge_request variables.append(key: 'CI_MERGE_REQUEST_SOURCE_BRANCH_SHA', value: source_sha.to_s) variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_SHA', value: target_sha.to_s) variables.concat(merge_request.predefined_variables) @@ -673,7 +669,7 @@ module Ci # All the merge requests for which the current pipeline runs/ran against def all_merge_requests @all_merge_requests ||= - if merge_request? + if merge_request_event? MergeRequest.where(id: merge_request_id) else MergeRequest.where(source_project_id: project_id, source_branch: ref) @@ -718,7 +714,7 @@ module Ci # * nil: Modified path can not be evaluated def modified_paths strong_memoize(:modified_paths) do - if merge_request? + if merge_request_event? merge_request.modified_paths elsif branch_updated? push_details.modified_paths @@ -731,7 +727,7 @@ module Ci end def triggered_by_merge_request? - merge_request? && merge_request_id.present? + merge_request_event? && merge_request_id.present? end def detached_merge_request_pipeline? @@ -777,7 +773,7 @@ module Ci end def git_ref - if merge_request? + if merge_request_event? ## # In the future, we're going to change this ref to # merge request's merged reference, such as "refs/merge-requests/:iid/merge". diff --git a/app/models/ci/pipeline_enums.rb b/app/models/ci/pipeline_enums.rb index 4be4fdb1ff2..571c4271475 100644 --- a/app/models/ci/pipeline_enums.rb +++ b/app/models/ci/pipeline_enums.rb @@ -23,7 +23,7 @@ module Ci api: 5, external: 6, chat: 8, - merge_request: 10 + merge_request_event: 10 } end diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index d82e11bbb89..ce26ee168ef 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -10,7 +10,7 @@ module Ci include FromUnion include TokenAuthenticatable - add_authentication_token_field :token, encrypted: true, migrating: true + add_authentication_token_field :token, encrypted: -> { Feature.enabled?(:ci_runners_tokens_optional_encryption) ? :optional : :required } enum access_level: { not_protected: 0, diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb index 524d79014f8..64836ea4fa4 100644 --- a/app/models/ci/variable.rb +++ b/app/models/ci/variable.rb @@ -5,6 +5,7 @@ module Ci extend Gitlab::Ci::Model include HasVariable include Presentable + include Maskable belongs_to :project diff --git a/app/models/clusters/applications/jupyter.rb b/app/models/clusters/applications/jupyter.rb index 421a923d386..80205775b6a 100644 --- a/app/models/clusters/applications/jupyter.rb +++ b/app/models/clusters/applications/jupyter.rb @@ -3,7 +3,7 @@ module Clusters module Applications class Jupyter < ActiveRecord::Base - VERSION = 'v0.6'.freeze + VERSION = '0.9-174bbd5'.freeze self.table_name = 'clusters_applications_jupyter' @@ -75,17 +75,22 @@ module Clusters "gitlab" => { "clientId" => oauth_application.uid, "clientSecret" => oauth_application.secret, - "callbackUrl" => callback_url + "callbackUrl" => callback_url, + "gitlabProjectIdWhitelist" => [project_id] } }, "singleuser" => { "extraEnv" => { - "GITLAB_CLUSTER_ID" => cluster.id + "GITLAB_CLUSTER_ID" => cluster.id.to_s } } } end + def project_id + cluster&.project&.id + end + def gitlab_url Gitlab.config.gitlab.url end diff --git a/app/models/clusters/concerns/application_core.rb b/app/models/clusters/concerns/application_core.rb index 683b45331f6..ee964fb7c93 100644 --- a/app/models/clusters/concerns/application_core.rb +++ b/app/models/clusters/concerns/application_core.rb @@ -30,6 +30,12 @@ module Clusters # Override if you need extra data synchronized # from K8s after installation end + + def update_command + install_command.tap do |command| + command.version = version + end + end end end end diff --git a/app/models/clusters/platforms/kubernetes.rb b/app/models/clusters/platforms/kubernetes.rb index 46d0898014e..814fc591408 100644 --- a/app/models/clusters/platforms/kubernetes.rb +++ b/app/models/clusters/platforms/kubernetes.rb @@ -41,7 +41,7 @@ module Clusters validate :no_namespace, unless: :allow_user_defined_namespace? # We expect to be `active?` only when enabled and cluster is created (the api_url is assigned) - validates :api_url, url: true, presence: true + validates :api_url, public_url: true, presence: true validates :token, presence: true validates :ca_cert, certificate: true, allow_blank: true, if: :ca_cert_changed? diff --git a/app/models/commit_range.rb b/app/models/commit_range.rb index 094747ee48d..920b1d092dd 100644 --- a/app/models/commit_range.rb +++ b/app/models/commit_range.rb @@ -134,25 +134,25 @@ class CommitRange end def sha_from - return nil unless @commit_from + return unless @commit_from @commit_from.id end def sha_to - return nil unless @commit_to + return unless @commit_to @commit_to.id end def sha_start - return nil unless sha_from + return unless sha_from exclude_start? ? sha_from + '^' : sha_from end def commit_start - return nil unless sha_start + return unless sha_start if exclude_start? @commit_start ||= project.commit(sha_start) diff --git a/app/models/concerns/blob_language_from_git_attributes.rb b/app/models/concerns/blob_language_from_git_attributes.rb index 70213d22147..56e1276a220 100644 --- a/app/models/concerns/blob_language_from_git_attributes.rb +++ b/app/models/concerns/blob_language_from_git_attributes.rb @@ -5,7 +5,7 @@ module BlobLanguageFromGitAttributes extend ActiveSupport::Concern def language_from_gitattributes - return nil unless project + return unless project repository = project.repository repository.gitattribute(path, 'gitlab-language') diff --git a/app/models/concerns/ci/contextable.rb b/app/models/concerns/ci/contextable.rb new file mode 100644 index 00000000000..4986a42dbd2 --- /dev/null +++ b/app/models/concerns/ci/contextable.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +module Ci + ## + # This module implements methods that provide context in form of + # essential CI/CD variables that can be used by a build / bridge job. + # + module Contextable + ## + # Variables in the environment name scope. + # + def scoped_variables(environment: expanded_environment_name) + Gitlab::Ci::Variables::Collection.new.tap do |variables| + variables.concat(predefined_variables) + variables.concat(project.predefined_variables) + variables.concat(pipeline.predefined_variables) + variables.concat(runner.predefined_variables) if runnable? && runner + variables.concat(project.deployment_variables(environment: environment)) if environment + variables.concat(yaml_variables) + variables.concat(user_variables) + variables.concat(secret_group_variables) + variables.concat(secret_project_variables(environment: environment)) + variables.concat(trigger_request.user_variables) if trigger_request + variables.concat(pipeline.variables) + variables.concat(pipeline.pipeline_schedule.job_variables) if pipeline.pipeline_schedule + end + end + + ## + # Regular Ruby hash of scoped variables, without duplicates that are + # possible to be present in an array of hashes returned from `variables`. + # + def scoped_variables_hash + scoped_variables.to_hash + end + + ## + # Variables that do not depend on the environment name. + # + def simple_variables + strong_memoize(:simple_variables) do + scoped_variables(environment: nil).to_runner_variables + end + end + + def user_variables + Gitlab::Ci::Variables::Collection.new.tap do |variables| + break variables if user.blank? + + variables.append(key: 'GITLAB_USER_ID', value: user.id.to_s) + variables.append(key: 'GITLAB_USER_EMAIL', value: user.email) + variables.append(key: 'GITLAB_USER_LOGIN', value: user.username) + variables.append(key: 'GITLAB_USER_NAME', value: user.name) + end + end + + def predefined_variables # rubocop:disable Metrics/AbcSize + Gitlab::Ci::Variables::Collection.new.tap do |variables| + variables.append(key: 'CI', value: 'true') + variables.append(key: 'GITLAB_CI', value: 'true') + variables.append(key: 'GITLAB_FEATURES', value: project.licensed_features.join(',')) + variables.append(key: 'CI_SERVER_NAME', value: 'GitLab') + variables.append(key: 'CI_SERVER_VERSION', value: Gitlab::VERSION) + variables.append(key: 'CI_SERVER_VERSION_MAJOR', value: Gitlab.version_info.major.to_s) + variables.append(key: 'CI_SERVER_VERSION_MINOR', value: Gitlab.version_info.minor.to_s) + variables.append(key: 'CI_SERVER_VERSION_PATCH', value: Gitlab.version_info.patch.to_s) + variables.append(key: 'CI_SERVER_REVISION', value: Gitlab.revision) + variables.append(key: 'CI_JOB_NAME', value: name) + variables.append(key: 'CI_JOB_STAGE', value: stage) + variables.append(key: 'CI_COMMIT_SHA', value: sha) + variables.append(key: 'CI_COMMIT_SHORT_SHA', value: short_sha) + variables.append(key: 'CI_COMMIT_BEFORE_SHA', value: before_sha) + variables.append(key: 'CI_COMMIT_REF_NAME', value: ref) + variables.append(key: 'CI_COMMIT_REF_SLUG', value: ref_slug) + variables.append(key: "CI_COMMIT_TAG", value: ref) if tag? + variables.append(key: "CI_PIPELINE_TRIGGERED", value: 'true') if trigger_request + variables.append(key: "CI_JOB_MANUAL", value: 'true') if action? + variables.append(key: "CI_NODE_INDEX", value: self.options[:instance].to_s) if self.options&.include?(:instance) + variables.append(key: "CI_NODE_TOTAL", value: (self.options&.dig(:parallel) || 1).to_s) + variables.concat(legacy_variables) + end + end + + def legacy_variables + Gitlab::Ci::Variables::Collection.new.tap do |variables| + variables.append(key: 'CI_BUILD_REF', value: sha) + variables.append(key: 'CI_BUILD_BEFORE_SHA', value: before_sha) + variables.append(key: 'CI_BUILD_REF_NAME', value: ref) + variables.append(key: 'CI_BUILD_REF_SLUG', value: ref_slug) + variables.append(key: 'CI_BUILD_NAME', value: name) + variables.append(key: 'CI_BUILD_STAGE', value: stage) + variables.append(key: "CI_BUILD_TAG", value: ref) if tag? + variables.append(key: "CI_BUILD_TRIGGERED", value: 'true') if trigger_request + variables.append(key: "CI_BUILD_MANUAL", value: 'true') if action? + end + end + + def secret_group_variables + return [] unless project.group + + project.group.ci_variables_for(git_ref, project) + end + + def secret_project_variables(environment: persisted_environment) + project.ci_variables_for(ref: git_ref, environment: environment) + end + end +end diff --git a/app/models/concerns/ci/processable.rb b/app/models/concerns/ci/processable.rb index 1c78b1413a8..268fa8ec692 100644 --- a/app/models/concerns/ci/processable.rb +++ b/app/models/concerns/ci/processable.rb @@ -23,5 +23,9 @@ module Ci def expanded_environment_name raise NotImplementedError end + + def scoped_variables_hash + raise NotImplementedError + end end end diff --git a/app/models/concerns/feature_gate.rb b/app/models/concerns/feature_gate.rb index 3f84de54ad5..bb095f113e2 100644 --- a/app/models/concerns/feature_gate.rb +++ b/app/models/concerns/feature_gate.rb @@ -2,7 +2,7 @@ module FeatureGate def flipper_id - return nil if new_record? + return if new_record? "#{self.class.name}:#{id}" end diff --git a/app/models/concerns/has_ref.rb b/app/models/concerns/has_ref.rb index d7089294efc..413cd36dcaa 100644 --- a/app/models/concerns/has_ref.rb +++ b/app/models/concerns/has_ref.rb @@ -4,7 +4,7 @@ module HasRef extend ActiveSupport::Concern def branch? - !tag? + !tag? && !merge_request_event? end def git_ref @@ -14,4 +14,15 @@ module HasRef Gitlab::Git::TAG_REF_PREFIX + ref.to_s end end + + # A slugified version of the build ref, suitable for inclusion in URLs and + # domain names. Rules: + # + # * Lowercased + # * Anything not matching [a-z0-9-] is replaced with a - + # * Maximum length is 63 bytes + # * First/Last Character is not a hyphen + def ref_slug + Gitlab::Utils.slugify(ref.to_s) + end end diff --git a/app/models/concerns/has_variable.rb b/app/models/concerns/has_variable.rb index dfbe413a878..2ec42a1029b 100644 --- a/app/models/concerns/has_variable.rb +++ b/app/models/concerns/has_variable.rb @@ -21,9 +21,9 @@ module HasVariable def key=(new_key) super(new_key.to_s.strip) end + end - def to_runner_variable - { key: key, value: value, public: false } - end + def to_runner_variable + { key: key, value: value, public: false } end end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 670103bc3f3..c7ad182ab82 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -75,6 +75,7 @@ module Issuable validates :author, presence: true validates :title, presence: true, length: { maximum: 255 } + validate :milestone_is_valid scope :authored, ->(user) { where(author_id: user) } scope :recent, -> { reorder(id: :desc) } @@ -118,6 +119,16 @@ module Issuable def has_multiple_assignees? assignees.count > 1 end + + def milestone_available? + project_id == milestone&.project_id || project.ancestors_upto.compact.include?(milestone&.group) + end + + private + + def milestone_is_valid + errors.add(:milestone_id, message: "is invalid") if milestone_id.present? && !milestone_available? + end end class_methods do diff --git a/app/models/concerns/maskable.rb b/app/models/concerns/maskable.rb new file mode 100644 index 00000000000..8793f0ec965 --- /dev/null +++ b/app/models/concerns/maskable.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Maskable + extend ActiveSupport::Concern + + # * Single line + # * No escape characters + # * No variables + # * No spaces + # * Minimal length of 8 characters + # * Absolutely no fun is allowed + REGEX = /\A\w{8,}\z/ + + included do + validates :masked, inclusion: { in: [true, false] } + validates :value, format: { with: REGEX }, if: :masked? + end + + def to_runner_variable + super.merge(masked: masked?) + end +end diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb index 055ffe04646..e65bbb8ca07 100644 --- a/app/models/concerns/milestoneish.rb +++ b/app/models/concerns/milestoneish.rb @@ -46,12 +46,31 @@ module Milestoneish end end + def issue_participants_visible_by_user(user) + User.joins(:issue_assignees) + .where('issue_assignees.issue_id' => issues_visible_to_user(user).select(:id)) + .distinct + end + + def issue_labels_visible_by_user(user) + Label.joins(:label_links) + .where('label_links.target_id' => issues_visible_to_user(user).select(:id), 'label_links.target_type' => 'Issue') + .distinct + end + def sorted_issues(user) issues_visible_to_user(user).preload_associations.sort_by_attribute('label_priority') end - def sorted_merge_requests - merge_requests.sort_by_attribute('label_priority') + def sorted_merge_requests(user) + merge_requests_visible_to_user(user).sort_by_attribute('label_priority') + end + + def merge_requests_visible_to_user(user) + memoize_per_user(user, :merge_requests_visible_to_user) do + MergeRequestsFinder.new(user, issues_finder_params) + .execute.where(milestone_id: milestoneish_id) + end end def upcoming? diff --git a/app/models/concerns/mirror_authentication.rb b/app/models/concerns/mirror_authentication.rb index e3e1a0441f8..948094221e5 100644 --- a/app/models/concerns/mirror_authentication.rb +++ b/app/models/concerns/mirror_authentication.rb @@ -79,7 +79,7 @@ module MirrorAuthentication end def ssh_public_key - return nil if ssh_private_key.blank? + return if ssh_private_key.blank? comment = "git@#{::Gitlab.config.gitlab.host}" ::SSHKey.new(ssh_private_key, comment: comment).ssh_public_key diff --git a/app/models/concerns/reactive_caching.rb b/app/models/concerns/reactive_caching.rb index de77ca3e963..d2ead7130e5 100644 --- a/app/models/concerns/reactive_caching.rb +++ b/app/models/concerns/reactive_caching.rb @@ -69,7 +69,7 @@ module ReactiveCaching def with_reactive_cache(*args, &blk) unless within_reactive_cache_lifetime?(*args) refresh_reactive_cache!(*args) - return nil + return end keep_alive_reactive_cache!(*args) diff --git a/app/models/concerns/token_authenticatable_strategies/base.rb b/app/models/concerns/token_authenticatable_strategies/base.rb index 01fb194281a..df14e6e4754 100644 --- a/app/models/concerns/token_authenticatable_strategies/base.rb +++ b/app/models/concerns/token_authenticatable_strategies/base.rb @@ -39,22 +39,6 @@ module TokenAuthenticatableStrategies instance.save! if Gitlab::Database.read_write? end - def fallback? - unless options[:fallback].in?([true, false, nil]) - raise ArgumentError, 'fallback: needs to be a boolean value!' - end - - options[:fallback] == true - end - - def migrating? - unless options[:migrating].in?([true, false, nil]) - raise ArgumentError, 'migrating: needs to be a boolean value!' - end - - options[:migrating] == true - end - def self.fabricate(model, field, options) if options[:digest] && options[:encrypted] raise ArgumentError, 'Incompatible options set!' diff --git a/app/models/concerns/token_authenticatable_strategies/encrypted.rb b/app/models/concerns/token_authenticatable_strategies/encrypted.rb index 152491aa6e9..2c7fa2c5b3c 100644 --- a/app/models/concerns/token_authenticatable_strategies/encrypted.rb +++ b/app/models/concerns/token_authenticatable_strategies/encrypted.rb @@ -2,28 +2,18 @@ module TokenAuthenticatableStrategies class Encrypted < Base - def initialize(*) - super - - if migrating? && fallback? - raise ArgumentError, '`fallback` and `migrating` options are not compatible!' - end - end - def find_token_authenticatable(token, unscoped = false) return if token.blank? - if fully_encrypted? - return find_by_encrypted_token(token, unscoped) - end - - if fallback? + if required? + find_by_encrypted_token(token, unscoped) + elsif optional? find_by_encrypted_token(token, unscoped) || find_by_plaintext_token(token, unscoped) elsif migrating? find_by_plaintext_token(token, unscoped) else - raise ArgumentError, 'Unknown encryption phase!' + raise ArgumentError, "Unknown encryption strategy: #{encrypted_strategy}!" end end @@ -41,8 +31,8 @@ module TokenAuthenticatableStrategies return super if instance.has_attribute?(encrypted_field) - if fully_encrypted? - raise ArgumentError, 'Using encrypted strategy when encrypted field is missing!' + if required? + raise ArgumentError, 'Using required encryption strategy when encrypted field is missing!' else insecure_strategy.ensure_token(instance) end @@ -53,8 +43,7 @@ module TokenAuthenticatableStrategies encrypted_token = instance.read_attribute(encrypted_field) token = Gitlab::CryptoHelper.aes256_gcm_decrypt(encrypted_token) - - token || (insecure_strategy.get_token(instance) if fallback?) + token || (insecure_strategy.get_token(instance) if optional?) end def set_token(instance, token) @@ -62,16 +51,35 @@ module TokenAuthenticatableStrategies instance[encrypted_field] = Gitlab::CryptoHelper.aes256_gcm_encrypt(token) instance[token_field] = token if migrating? - instance[token_field] = nil if fallback? + instance[token_field] = nil if optional? token end - def fully_encrypted? - !migrating? && !fallback? + def required? + encrypted_strategy == :required + end + + def migrating? + encrypted_strategy == :migrating + end + + def optional? + encrypted_strategy == :optional end protected + def encrypted_strategy + value = options[:encrypted] + value = value.call if value.is_a?(Proc) + + unless value.in?([:required, :optional, :migrating]) + raise ArgumentError, 'encrypted: needs to be a :required, :optional or :migrating!' + end + + value + end + def find_by_plaintext_token(token, unscoped) insecure_strategy.find_token_authenticatable(token, unscoped) end @@ -89,7 +97,7 @@ module TokenAuthenticatableStrategies def token_set?(instance) raw_token = instance.read_attribute(encrypted_field) - unless fully_encrypted? + unless required? raw_token ||= insecure_strategy.get_token(instance) end diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb index 279603496b0..805092e527a 100644 --- a/app/models/diff_note.rb +++ b/app/models/diff_note.rb @@ -41,6 +41,14 @@ class DiffNote < Note create_note_diff_file(creation_params) end + # Returns the diff file from `position` + def latest_diff_file + strong_memoize(:latest_diff_file) do + position.diff_file(project.repository) + end + end + + # Returns the diff file from `original_position` def diff_file strong_memoize(:diff_file) do enqueue_diff_file_creation_job if should_create_diff_file? diff --git a/app/models/environment.rb b/app/models/environment.rb index 87bdb52b58b..3d909cc8e5c 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -119,7 +119,7 @@ class Environment < ActiveRecord::Base def first_deployment_for(commit_sha) ref = project.repository.ref_name_for_sha(ref_path, commit_sha) - return nil unless ref + return unless ref deployment_iid = ref.split('/').last deployments.find_by(iid: deployment_iid) @@ -130,7 +130,7 @@ class Environment < ActiveRecord::Base end def formatted_external_url - return nil unless external_url + return unless external_url external_url.gsub(%r{\A.*?://}, '') end diff --git a/app/models/error_tracking/project_error_tracking_setting.rb b/app/models/error_tracking/project_error_tracking_setting.rb index 57283a78ea9..1e2bd3bda7f 100644 --- a/app/models/error_tracking/project_error_tracking_setting.rb +++ b/app/models/error_tracking/project_error_tracking_setting.rb @@ -2,19 +2,30 @@ module ErrorTracking class ProjectErrorTrackingSetting < ActiveRecord::Base + include Gitlab::Utils::StrongMemoize include ReactiveCaching + API_URL_PATH_REGEXP = %r{ + \A + (?<prefix>/api/0/projects/+) + (?: + (?<organization>[^/]+)/+ + (?<project>[^/]+)/* + )? + \z + }x + self.reactive_cache_key = ->(setting) { [setting.class.model_name.singular, setting.project_id] } belongs_to :project validates :api_url, length: { maximum: 255 }, public_url: true, url: { enforce_sanitization: true, ascii_only: true }, allow_nil: true - validates :api_url, presence: true, if: :enabled + validates :api_url, presence: { message: 'is a required field' }, if: :enabled validate :validate_api_url_path, if: :enabled - validates :token, presence: true, if: :enabled + validates :token, presence: { message: 'is a required field' }, if: :enabled attr_encrypted :token, mode: :per_attribute_iv, @@ -23,6 +34,11 @@ module ErrorTracking after_save :clear_reactive_cache! + def api_url=(value) + super + clear_memoization(:api_url_slugs) + end + def project_name super || project_name_from_slug end @@ -40,6 +56,8 @@ module ErrorTracking end def self.build_api_url_from(api_host:, project_slug:, organization_slug:) + return if api_host.blank? + uri = Addressable::URI.parse("#{api_host}/api/0/projects/#{organization_slug}/#{project_slug}/") uri.path = uri.path.squeeze('/') @@ -100,34 +118,39 @@ module ErrorTracking end def project_slug_from_api_url - extract_slug(:project) + api_url_slug(:project) end def organization_slug_from_api_url - extract_slug(:organization) + api_url_slug(:organization) + end + + def api_url_slug(capture) + slugs = strong_memoize(:api_url_slugs) { extract_api_url_slugs || {} } + slugs[capture] end - def extract_slug(capture) + def extract_api_url_slugs return if api_url.blank? begin url = Addressable::URI.parse(api_url) rescue Addressable::URI::InvalidURIError - return nil + return end - @slug_match ||= url.path.match(%r{^/api/0/projects/+(?<organization>[^/]+)/+(?<project>[^/|$]+)}) || {} - @slug_match[capture] + url.path.match(API_URL_PATH_REGEXP) end def validate_api_url_path return if api_url.blank? - begin - unless Addressable::URI.parse(api_url).path.starts_with?('/api/0/projects') - errors.add(:api_url, 'path needs to start with /api/0/projects') - end - rescue Addressable::URI::InvalidURIError + unless api_url_slug(:prefix) + return errors.add(:api_url, 'is invalid') + end + + unless api_url_slug(:organization) + errors.add(:project, 'is a required field') end end end diff --git a/app/models/group.rb b/app/models/group.rb index 52f503404af..495bfe04499 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -56,7 +56,7 @@ class Group < Namespace validates :two_factor_grace_period, presence: true, numericality: { greater_than_or_equal_to: 0 } - add_authentication_token_field :runners_token, encrypted: true, migrating: true + add_authentication_token_field :runners_token, encrypted: -> { Feature.enabled?(:groups_tokens_optional_encryption) ? :optional : :required } after_create :post_create_hook after_destroy :post_destroy_hook diff --git a/app/models/individual_note_discussion.rb b/app/models/individual_note_discussion.rb index b4a661ae5b4..3b6b68a9c5f 100644 --- a/app/models/individual_note_discussion.rb +++ b/app/models/individual_note_discussion.rb @@ -14,7 +14,7 @@ class IndividualNoteDiscussion < Discussion end def can_convert_to_discussion? - noteable.supports_replying_to_individual_notes? && Feature.enabled?(:reply_to_individual_notes) + noteable.supports_replying_to_individual_notes? && Feature.enabled?(:reply_to_individual_notes, default_enabled: true) end def convert_to_discussion!(save: false) diff --git a/app/models/issue.rb b/app/models/issue.rb index 071ad50fddc..deab53d25e7 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -64,6 +64,7 @@ class Issue < ActiveRecord::Base scope :order_closest_future_date, -> { reorder('CASE WHEN issues.due_date >= CURRENT_DATE THEN 0 ELSE 1 END ASC, ABS(CURRENT_DATE - issues.due_date) ASC') } scope :preload_associations, -> { preload(:labels, project: :namespace) } + scope :with_api_entity_associations, -> { preload(:timelogs, :assignees, :author, :notes, :labels, project: [:route, { namespace: :route }] ) } scope :public_only, -> { where(confidential: false) } scope :confidential_only, -> { where(confidential: true) } diff --git a/app/models/label_note.rb b/app/models/label_note.rb index 680952cf421..d6814f4a948 100644 --- a/app/models/label_note.rb +++ b/app/models/label_note.rb @@ -81,7 +81,7 @@ class LabelNote < Note deleted = label_refs.count - existing_refs.count deleted_str = deleted == 0 ? nil : "#{deleted} deleted" - return nil unless refs_str || deleted_str + return unless refs_str || deleted_str label_list_str = [refs_str, deleted_str].compact.join(' + ') suffix = 'label'.pluralize(deleted > 0 ? deleted : existing_refs.count) diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb index 00dec6bb92b..e2c75bc7ee9 100644 --- a/app/models/legacy_diff_note.rb +++ b/app/models/legacy_diff_note.rb @@ -73,7 +73,7 @@ class LegacyDiffNote < Note private def find_diff - return nil unless noteable + return unless noteable return @diff if defined?(@diff) @diff = noteable.raw_diffs(Commit.max_diff_options).find do |d| diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 1468ae1c34a..acf80addc6a 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -71,7 +71,7 @@ class MergeRequest < ActiveRecord::Base serialize :merge_params, Hash # rubocop:disable Cop/ActiveRecordSerialize - after_create :ensure_merge_request_diff, unless: :importing? + after_create :ensure_merge_request_diff after_update :clear_memoized_shas after_update :reload_diff_if_branch_changed after_save :ensure_metrics @@ -184,11 +184,21 @@ class MergeRequest < ActiveRecord::Base scope :assigned, -> { where("assignee_id IS NOT NULL") } scope :unassigned, -> { where("assignee_id IS NULL") } scope :assigned_to, ->(u) { where(assignee_id: u.id)} + scope :with_api_entity_associations, -> { + preload(:author, :assignee, :notes, :labels, :milestone, :timelogs, + latest_merge_request_diff: [:merge_request_diff_commits], + metrics: [:latest_closed_by, :merged_by], + target_project: [:route, { namespace: :route }], + source_project: [:route, { namespace: :route }]) + } participant :assignee after_save :keep_around_commit + alias_attribute :project, :target_project + alias_attribute :project_id, :target_project_id + def self.reference_prefix '!' end @@ -847,10 +857,6 @@ class MergeRequest < ActiveRecord::Base target_project != source_project end - def project - target_project - end - # If the merge request closes any issues, save this information in the # `MergeRequestsClosingIssues` model. This is a performance optimization. # Calculating this information for a number of merge requests requires @@ -1154,35 +1160,16 @@ class MergeRequest < ActiveRecord::Base Gitlab::Ci::Variables::Collection.new.tap do |variables| variables.append(key: 'CI_MERGE_REQUEST_ID', value: id.to_s) variables.append(key: 'CI_MERGE_REQUEST_IID', value: iid.to_s) - - variables.append(key: 'CI_MERGE_REQUEST_REF_PATH', - value: ref_path.to_s) - - variables.append(key: 'CI_MERGE_REQUEST_PROJECT_ID', - value: project.id.to_s) - - variables.append(key: 'CI_MERGE_REQUEST_PROJECT_PATH', - value: project.full_path) - - variables.append(key: 'CI_MERGE_REQUEST_PROJECT_URL', - value: project.web_url) - - variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_NAME', - value: target_branch.to_s) - - if source_project - variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_ID', - value: source_project.id.to_s) - - variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH', - value: source_project.full_path) - - variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL', - value: source_project.web_url) - - variables.append(key: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME', - value: source_branch.to_s) - end + variables.append(key: 'CI_MERGE_REQUEST_REF_PATH', value: ref_path.to_s) + variables.append(key: 'CI_MERGE_REQUEST_PROJECT_ID', value: project.id.to_s) + variables.append(key: 'CI_MERGE_REQUEST_PROJECT_PATH', value: project.full_path) + variables.append(key: 'CI_MERGE_REQUEST_PROJECT_URL', value: project.web_url) + variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_NAME', value: target_branch.to_s) + variables.append(key: 'CI_MERGE_REQUEST_TITLE', value: title) + variables.append(key: 'CI_MERGE_REQUEST_ASSIGNEES', value: assignee.username) if assignee + variables.append(key: 'CI_MERGE_REQUEST_MILESTONE', value: milestone.title) if milestone + variables.append(key: 'CI_MERGE_REQUEST_LABELS', value: label_names.join(',')) if labels.present? + variables.concat(source_project_variables) end end @@ -1389,4 +1376,15 @@ class MergeRequest < ActiveRecord::Base source_project&.ci_pipelines &.latest_for_merge_request(self, source_branch, diff_head_sha) end + + def source_project_variables + Gitlab::Ci::Variables::Collection.new.tap do |variables| + break variables unless source_project + + variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_ID', value: source_project.id.to_s) + variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH', value: source_project.full_path) + variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL', value: source_project.web_url) + variables.append(key: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME', value: source_branch.to_s) + end + end end diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index e286a4e57f2..351a662ae83 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -22,6 +22,8 @@ class MergeRequestDiff < ActiveRecord::Base has_many :merge_request_diff_commits, -> { order(:merge_request_diff_id, :relative_order) } + validates :base_commit_sha, :head_commit_sha, :start_commit_sha, sha: true + state_machine :state, initial: :empty do event :clean do transition any => :without_files diff --git a/app/models/namespace.rb b/app/models/namespace.rb index f7592532c5b..a5c479bdc0c 100644 --- a/app/models/namespace.rb +++ b/app/models/namespace.rb @@ -149,7 +149,7 @@ class Namespace < ApplicationRecord end def find_fork_of(project) - return nil unless project.fork_network + return unless project.fork_network if Gitlab::SafeRequestStore.active? forks_in_namespace = Gitlab::SafeRequestStore.fetch("namespaces:#{id}:forked_projects") do diff --git a/app/models/notification_recipient.rb b/app/models/notification_recipient.rb index 481c1d963c6..793cce191fa 100644 --- a/app/models/notification_recipient.rb +++ b/app/models/notification_recipient.rb @@ -119,7 +119,7 @@ class NotificationRecipient private def read_ability - return nil if @skip_read_ability + return if @skip_read_ability return @read_ability if instance_variable_defined?(:@read_ability) @read_ability = @@ -136,7 +136,7 @@ class NotificationRecipient end def default_project - return nil if @target.nil? + return if @target.nil? return @target if @target.is_a?(Project) return @target.project if @target.respond_to?(:project) end diff --git a/app/models/project.rb b/app/models/project.rb index 47baf899222..4cc13f372c1 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -85,7 +85,7 @@ class Project < ActiveRecord::Base default_value_for :snippets_enabled, gitlab_config_features.snippets default_value_for :only_allow_merge_if_all_discussions_are_resolved, false - add_authentication_token_field :runners_token, encrypted: true, migrating: true + add_authentication_token_field :runners_token, encrypted: -> { Feature.enabled?(:projects_tokens_optional_encryption) ? :optional : :required } before_validation :mark_remote_mirrors_for_removal, if: -> { RemoteMirror.table_exists? } @@ -1230,7 +1230,7 @@ class Project < ActiveRecord::Base end def fork_source - return nil unless forked? + return unless forked? forked_from_project || fork_network&.root_project end @@ -1679,7 +1679,7 @@ class Project < ActiveRecord::Base end def export_path - return nil unless namespace.present? || hashed_storage?(:repository) + return unless namespace.present? || hashed_storage?(:repository) import_export_shared.archive_path end @@ -1970,9 +1970,19 @@ class Project < ActiveRecord::Base return unless storage_upgradable? if git_transfer_in_progress? - ProjectMigrateHashedStorageWorker.perform_in(Gitlab::ReferenceCounter::REFERENCE_EXPIRE_TIME, id) + HashedStorage::ProjectMigrateWorker.perform_in(Gitlab::ReferenceCounter::REFERENCE_EXPIRE_TIME, id) else - ProjectMigrateHashedStorageWorker.perform_async(id) + HashedStorage::ProjectMigrateWorker.perform_async(id) + end + end + + def rollback_to_legacy_storage! + return if legacy_storage? + + if git_transfer_in_progress? + HashedStorage::ProjectRollbackWorker.perform_in(Gitlab::ReferenceCounter::REFERENCE_EXPIRE_TIME, id) + else + HashedStorage::ProjectRollbackWorker.perform_async(id) end end diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb index f700090a493..e6787236c4e 100644 --- a/app/models/project_feature.rb +++ b/app/models/project_feature.rb @@ -76,7 +76,7 @@ class ProjectFeature < ActiveRecord::Base # This feature might not be behind a feature flag at all, so default to true return false unless ::Feature.enabled?(feature, user, default_enabled: true) - get_permission(user, access_level(feature)) + get_permission(user, feature) end def access_level(feature) @@ -134,12 +134,12 @@ class ProjectFeature < ActiveRecord::Base (FEATURES - %i(pages)).each {|f| validator.call("#{f}_access_level")} end - def get_permission(user, level) - case level + def get_permission(user, feature) + case access_level(feature) when DISABLED false when PRIVATE - user && (project.team.member?(user) || user.full_private_access?) + team_access?(user, feature) when ENABLED true when PUBLIC @@ -148,4 +148,11 @@ class ProjectFeature < ActiveRecord::Base true end end + + def team_access?(user, feature) + return unless user + return true if user.full_private_access? + + project.team.member?(user, ProjectFeature.required_minimum_access_level(feature)) + end end diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb index 1d7877a1fb5..ad26e42a21b 100644 --- a/app/models/project_services/campfire_service.rb +++ b/app/models/project_services/campfire_service.rb @@ -57,7 +57,7 @@ class CampfireService < Service # https://github.com/basecamp/campfire-api/blob/master/sections/messages.md#create-message def speak(room_name, message, auth) room = rooms(auth).find { |r| r["name"] == room_name } - return nil unless room + return unless room path = "/room/#{room["id"]}/speak.json" body = { diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb index 83fd9a34438..fb76bc89c98 100644 --- a/app/models/project_services/irker_service.rb +++ b/app/models/project_services/irker_service.rb @@ -112,7 +112,7 @@ class IrkerService < Service end def consider_uri(uri) - return nil if uri.scheme.nil? + return if uri.scheme.nil? # Authorize both irc://domain.com/#chan and irc://domain.com/chan if uri.is_a?(URI) && uri.scheme[/^ircs?\z/] && !uri.path.nil? diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index 9066a0b7f1d..f7064d5aaea 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -215,7 +215,7 @@ class JiraService < IssueTrackerService end def add_issue_solved_comment(issue, commit_id, commit_url) - link_title = "GitLab: Solved by commit #{commit_id}." + link_title = "Solved by commit #{commit_id}." comment = "Issue solved with [#{commit_id}|#{commit_url}]." link_props = build_remote_link_props(url: commit_url, title: link_title, resolved: true) send_message(issue, comment, link_props) @@ -230,7 +230,7 @@ class JiraService < IssueTrackerService project_name = data[:project][:name] message = "[#{user_name}|#{user_url}] mentioned this issue in [a #{entity_name} of #{project_name}|#{entity_url}]:\n'#{entity_title.chomp}'" - link_title = "GitLab: Mentioned on #{entity_name} - #{entity_title}" + link_title = "#{entity_name.capitalize} - #{entity_title}" link_props = build_remote_link_props(url: entity_url, title: link_title) unless comment_exists?(issue, message) @@ -278,6 +278,7 @@ class JiraService < IssueTrackerService { GlobalID: 'GitLab', + relationship: 'mentioned on', object: { url: url, title: title, diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb index 60cb2d380d5..c68a9d923c8 100644 --- a/app/models/project_services/prometheus_service.rb +++ b/app/models/project_services/prometheus_service.rb @@ -71,7 +71,7 @@ class PrometheusService < MonitoringService end def prometheus_client - RestClient::Resource.new(api_url, max_redirects: 0) if api_url && manual_configuration? && active? + RestClient::Resource.new(api_url, max_redirects: 0) if should_return_client? end def prometheus_available? @@ -83,6 +83,10 @@ class PrometheusService < MonitoringService private + def should_return_client? + api_url && manual_configuration? && active? && valid? + end + def synchronize_service_state self.active = prometheus_available? || manual_configuration? diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index d075440b147..597431be65a 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -18,13 +18,23 @@ class ProtectedBranch < ActiveRecord::Base def self.protected?(project, ref_name) return true if project.empty_repo? && default_branch_protected? - refs = project.protected_branches.select(:name) + self.matching(ref_name, protected_refs: protected_refs(project)).present? + end - self.matching(ref_name, protected_refs: refs).present? + def self.any_protected?(project, ref_names) + protected_refs(project).any? do |protected_ref| + ref_names.any? do |ref_name| + protected_ref.matches?(ref_name) + end + end end def self.default_branch_protected? Gitlab::CurrentSettings.default_branch_protection == Gitlab::Access::PROTECTION_FULL || Gitlab::CurrentSettings.default_branch_protection == Gitlab::Access::PROTECTION_DEV_CAN_MERGE end + + def self.protected_refs(project) + project.protected_branches.select(:name) + end end diff --git a/app/models/repository.rb b/app/models/repository.rb index cd761a29618..851175a61b7 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -79,7 +79,7 @@ class Repository end def raw_repository - return nil unless full_path + return unless full_path @raw_repository ||= initialize_raw_repository end @@ -103,7 +103,7 @@ class Repository end def commit(ref = nil) - return nil unless exists? + return unless exists? return ref if ref.is_a?(::Commit) find_commit(ref || root_ref) diff --git a/app/models/ssh_host_key.rb b/app/models/ssh_host_key.rb index fd23cc9ac87..b6fb39ee81f 100644 --- a/app/models/ssh_host_key.rb +++ b/app/models/ssh_host_key.rb @@ -27,7 +27,7 @@ class SshHostKey def self.find_by(opts = {}) opts = HashWithIndifferentAccess.new(opts) - return nil unless opts.key?(:id) + return unless opts.key?(:id) project_id, url = opts[:id].split(':', 2) project = Project.find_by(id: project_id) diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb index 7eee4fbbe5f..09034646bff 100644 --- a/app/models/suggestion.rb +++ b/app/models/suggestion.rb @@ -19,11 +19,6 @@ class Suggestion < ApplicationRecord position.file_path end - def diff_file - repository = project.repository - position.diff_file(repository) - end - # For now, suggestions only serve as a way to send patches that # will change a single line (being able to apply multiple in the same place), # which explains `from_line` and `to_line` being the same line. diff --git a/app/models/todo.rb b/app/models/todo.rb index d9b86d941b6..2b0dee875a3 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -31,7 +31,13 @@ class Todo < ActiveRecord::Base belongs_to :note belongs_to :project belongs_to :group - belongs_to :target, polymorphic: true, touch: true # rubocop:disable Cop/PolymorphicAssociations + belongs_to :target, -> { + if self.klass.respond_to?(:with_api_entity_associations) + self.with_api_entity_associations + else + self + end + }, polymorphic: true, touch: true # rubocop:disable Cop/PolymorphicAssociations belongs_to :user delegate :name, :email, to: :author, prefix: true, allow_nil: true @@ -52,6 +58,7 @@ class Todo < ActiveRecord::Base scope :for_type, -> (type) { where(target_type: type) } scope :for_target, -> (id) { where(target_id: id) } scope :for_commit, -> (id) { where(commit_id: id) } + scope :with_api_entity_associations, -> { preload(:target, :author, :note, group: :route, project: [:route, { namespace: :route }]) } state_machine :state, initial: :pending do event :done do diff --git a/app/models/user.rb b/app/models/user.rb index ee51c35d576..778c9e631bd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -470,7 +470,7 @@ class User < ApplicationRecord end def by_login(login) - return nil unless login + return unless login if login.include?('@'.freeze) unscoped.iwhere(email: login).take diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index b1d6d461928..64daba81dcf 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -132,7 +132,7 @@ class WikiPage # The GitLab Commit instance for this page. def version - return nil unless persisted? + return unless persisted? @version ||= @page.version end diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index 16c58730878..d412a591fdc 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -68,6 +68,10 @@ class GlobalPolicy < BasePolicy enable :read_users_list end + rule { ~anonymous }.policy do + enable :read_instance_metadata + end + rule { admin }.policy do enable :read_custom_attribute enable :update_custom_attribute diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 298769c0eb8..e74e5f008d7 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -53,7 +53,6 @@ class GroupPolicy < BasePolicy rule { admin }.enable :read_group rule { has_projects }.policy do - enable :read_group enable :read_list enable :read_label end diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 533782104ac..cf257ed47c8 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -278,6 +278,7 @@ class ProjectPolicy < BasePolicy enable :admin_cluster enable :create_environment_terminal enable :destroy_release + enable :destroy_artifacts enable :daily_statistics end @@ -300,6 +301,8 @@ class ProjectPolicy < BasePolicy rule { issues_disabled }.policy do prevent(*create_read_update_admin_destroy(:issue)) + prevent(*create_read_update_admin_destroy(:board)) + prevent(*create_read_update_admin_destroy(:list)) end rule { merge_requests_disabled | repository_disabled }.policy do @@ -463,7 +466,7 @@ class ProjectPolicy < BasePolicy when ProjectFeature::DISABLED false when ProjectFeature::PRIVATE - guest? || admin? + admin? || team_access_level >= ProjectFeature.required_minimum_access_level(feature) else true end diff --git a/app/presenters/blobs/unfold_presenter.rb b/app/presenters/blobs/unfold_presenter.rb new file mode 100644 index 00000000000..7b13db3bb74 --- /dev/null +++ b/app/presenters/blobs/unfold_presenter.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'gt_one_coercion' + +module Blobs + class UnfoldPresenter < BlobPresenter + include Virtus.model + include Gitlab::Utils::StrongMemoize + + attribute :full, Boolean, default: false + attribute :since, GtOneCoercion + attribute :to, GtOneCoercion + attribute :bottom, Boolean + attribute :unfold, Boolean, default: true + attribute :offset, Integer + attribute :indent, Integer, default: 0 + + def initialize(blob, params) + @subject = blob + @all_lines = highlight.lines + super(params) + + if full? + self.attributes = { since: 1, to: @all_lines.size, bottom: false, unfold: false, offset: 0, indent: 0 } + end + end + + # Converts a String array to Gitlab::Diff::Line array, with match line added + def diff_lines + diff_lines = lines.map do |line| + Gitlab::Diff::Line.new(line, nil, nil, nil, nil, rich_text: line) + end + + add_match_line(diff_lines) + + diff_lines + end + + def lines + strong_memoize(:lines) do + lines = @all_lines + lines = lines[since - 1..to - 1] unless full? + lines.map(&:html_safe) + end + end + + def match_line_text + return '' if bottom? + + lines_length = lines.length - 1 + line = [since, lines_length].join(',') + "@@ -#{line}+#{line} @@" + end + + private + + def add_match_line(diff_lines) + return unless unfold? + + if bottom? && to < @all_lines.size + old_pos = to - offset + new_pos = to + elsif since != 1 + old_pos = new_pos = since + end + + # Match line is not needed when it reaches the top limit or bottom limit of the file. + return unless new_pos + + match_line = Gitlab::Diff::Line.new(match_line_text, 'match', nil, old_pos, new_pos) + + bottom? ? diff_lines.push(match_line) : diff_lines.unshift(match_line) + end + end +end diff --git a/app/presenters/ci/build_runner_presenter.rb b/app/presenters/ci/build_runner_presenter.rb index d60281c8a0b..29656b17183 100644 --- a/app/presenters/ci/build_runner_presenter.rb +++ b/app/presenters/ci/build_runner_presenter.rb @@ -35,7 +35,7 @@ module Ci specs = [] if git_depth > 0 - specs << refspec_for_branch(ref) if branch? || merge_request? + specs << refspec_for_branch(ref) if branch? || merge_request_event? specs << refspec_for_tag(ref) if tag? else specs << refspec_for_branch diff --git a/app/presenters/clusterable_presenter.rb b/app/presenters/clusterable_presenter.rb index d94d9118eee..34bdf156623 100644 --- a/app/presenters/clusterable_presenter.rb +++ b/app/presenters/clusterable_presenter.rb @@ -44,6 +44,10 @@ class ClusterablePresenter < Gitlab::View::Presenter::Delegated raise NotImplementedError end + def update_applications_cluster_path(cluster, application) + raise NotImplementedError + end + def cluster_path(cluster, params = {}) raise NotImplementedError end diff --git a/app/presenters/group_clusterable_presenter.rb b/app/presenters/group_clusterable_presenter.rb index ef6bbc0d109..f5b0bb64487 100644 --- a/app/presenters/group_clusterable_presenter.rb +++ b/app/presenters/group_clusterable_presenter.rb @@ -14,6 +14,11 @@ class GroupClusterablePresenter < ClusterablePresenter install_applications_group_cluster_path(clusterable, cluster, application) end + override :update_applications_cluster_path + def update_applications_cluster_path(cluster, application) + update_applications_group_cluster_path(clusterable, cluster, application) + end + override :cluster_path def cluster_path(cluster, params = {}) group_cluster_path(clusterable, cluster, params) diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index c59e73f824c..af164858408 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -98,6 +98,12 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated end end + def target_branch_path + if target_branch_exists? + project_branch_path(project, target_branch) + end + end + def source_branch_path if source_branch_exists? project_branch_path(source_project, source_branch) diff --git a/app/presenters/project_clusterable_presenter.rb b/app/presenters/project_clusterable_presenter.rb index 63e69b91b11..8661ee02b68 100644 --- a/app/presenters/project_clusterable_presenter.rb +++ b/app/presenters/project_clusterable_presenter.rb @@ -14,6 +14,11 @@ class ProjectClusterablePresenter < ClusterablePresenter install_applications_project_cluster_path(clusterable, cluster, application) end + override :update_applications_cluster_path + def update_applications_cluster_path(cluster, application) + update_applications_project_cluster_path(clusterable, cluster, application) + end + override :cluster_path def cluster_path(cluster, params = {}) project_cluster_path(clusterable, cluster, params) diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb index 4cac90c2567..000b7c433a2 100644 --- a/app/presenters/project_presenter.rb +++ b/app/presenters/project_presenter.rb @@ -315,6 +315,10 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated project.tag_list.take(MAX_TOPICS_TO_SHOW) # rubocop: disable CodeReuse/ActiveRecord end + def topics_not_shown + project.tag_list - topics_to_show + end + def count_of_extra_topics_not_shown if project.tag_list.count > MAX_TOPICS_TO_SHOW project.tag_list.count - MAX_TOPICS_TO_SHOW diff --git a/app/serializers/acts_as_taggable_on/tag_entity.rb b/app/serializers/acts_as_taggable_on/tag_entity.rb new file mode 100644 index 00000000000..d4e4b69f8fa --- /dev/null +++ b/app/serializers/acts_as_taggable_on/tag_entity.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class ActsAsTaggableOn::TagEntity < Grape::Entity + expose :id + expose :name +end diff --git a/app/serializers/acts_as_taggable_on/tag_serializer.rb b/app/serializers/acts_as_taggable_on/tag_serializer.rb new file mode 100644 index 00000000000..87f53606aa1 --- /dev/null +++ b/app/serializers/acts_as_taggable_on/tag_serializer.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class ActsAsTaggableOn::TagSerializer < BaseSerializer + entity ActsAsTaggableOn::TagEntity +end diff --git a/app/serializers/concerns/user_status_tooltip.rb b/app/serializers/concerns/user_status_tooltip.rb index aa6e67e3351..633b117d392 100644 --- a/app/serializers/concerns/user_status_tooltip.rb +++ b/app/serializers/concerns/user_status_tooltip.rb @@ -11,7 +11,7 @@ module UserStatusTooltip expose :user_status_if_loaded, as: :status_tooltip_html def user_status_if_loaded - return nil unless object.association(:status).loaded? + return unless object.association(:status).loaded? user_status(object) end diff --git a/app/serializers/diff_file_base_entity.rb b/app/serializers/diff_file_base_entity.rb index ede9e04b722..d8630165e49 100644 --- a/app/serializers/diff_file_base_entity.rb +++ b/app/serializers/diff_file_base_entity.rb @@ -27,9 +27,13 @@ class DiffFileBaseEntity < Grape::Entity next unless merge_request.source_project - project_edit_blob_path(merge_request.source_project, - tree_join(merge_request.source_branch, diff_file.new_path), - options) + if Feature.enabled?(:web_ide_default) + ide_edit_path(merge_request.source_project, merge_request.source_branch, diff_file.new_path) + else + project_edit_blob_path(merge_request.source_project, + tree_join(merge_request.source_branch, diff_file.new_path), + options) + end end expose :old_path_html do |diff_file| diff --git a/app/serializers/diff_file_entity.rb b/app/serializers/diff_file_entity.rb index 01ee7af37ed..13711070a46 100644 --- a/app/serializers/diff_file_entity.rb +++ b/app/serializers/diff_file_entity.rb @@ -7,7 +7,7 @@ class DiffFileEntity < DiffFileBaseEntity expose :added_lines expose :removed_lines - expose :load_collapsed_diff_url, if: -> (diff_file, options) { diff_file.viewer.collapsed? && options[:merge_request] } do |diff_file| + expose :load_collapsed_diff_url, if: -> (diff_file, options) { options[:merge_request] } do |diff_file| merge_request = options[:merge_request] project = merge_request.target_project @@ -57,6 +57,10 @@ class DiffFileEntity < DiffFileBaseEntity diff_file.diff_lines_for_serializer end + expose :is_fully_expanded, if: -> (diff_file, _) { Feature.enabled?(:expand_diff_full_file) && diff_file.text? } do |diff_file| + diff_file.fully_expanded? + end + # Used for parallel diffs expose :parallel_diff_lines, using: DiffLineParallelEntity, if: -> (diff_file, _) { diff_file.text? } end diff --git a/app/serializers/merge_request_for_pipeline_entity.rb b/app/serializers/merge_request_for_pipeline_entity.rb new file mode 100644 index 00000000000..7779ddfd65a --- /dev/null +++ b/app/serializers/merge_request_for_pipeline_entity.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class MergeRequestForPipelineEntity < Grape::Entity + include RequestAwareEntity + + expose :iid + + expose :path do |merge_request| + project_merge_request_path(merge_request.project, merge_request) + end + + expose :title + expose :source_branch + expose :source_branch_path + expose :target_branch + expose :target_branch_path +end diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index 29b1a6c244b..5ac1e590d39 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -23,11 +23,12 @@ class PipelineEntity < Grape::Entity expose :latest?, as: :latest expose :stuck?, as: :stuck expose :auto_devops_source?, as: :auto_devops - expose :merge_request?, as: :merge_request + expose :merge_request_event?, as: :merge_request expose :has_yaml_errors?, as: :yaml_errors expose :can_retry?, as: :retryable expose :can_cancel?, as: :cancelable expose :failure_reason?, as: :failure_reason + expose :detached_merge_request_pipeline?, as: :detached end expose :details do @@ -36,6 +37,10 @@ class PipelineEntity < Grape::Entity expose :finished_at end + expose :merge_request, if: -> (*) { has_presentable_merge_request? }, with: MergeRequestForPipelineEntity do |pipeline| + pipeline.merge_request.present(current_user: request.current_user) + end + expose :ref do expose :name do |pipeline| pipeline.ref @@ -49,7 +54,7 @@ class PipelineEntity < Grape::Entity expose :tag?, as: :tag expose :branch?, as: :branch - expose :merge_request?, as: :merge_request + expose :merge_request_event?, as: :merge_request end expose :commit, using: CommitEntity @@ -81,6 +86,11 @@ class PipelineEntity < Grape::Entity pipeline.cancelable? end + def has_presentable_merge_request? + pipeline.triggered_by_merge_request? && + can?(request.current_user, :read_merge_request, pipeline.merge_request) + end + def detailed_status pipeline.detailed_status(request.current_user) end diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb index 7451433a841..dbbeca9431d 100644 --- a/app/serializers/pipeline_serializer.rb +++ b/app/serializers/pipeline_serializer.rb @@ -15,6 +15,7 @@ class PipelineSerializer < BaseSerializer :manual_actions, :scheduled_actions, :artifacts, + :merge_request, { pending_builds: :project, project: [:route, { namespace: :route }], diff --git a/app/services/application_settings/update_service.rb b/app/services/application_settings/update_service.rb index 2e4643ed668..9146eb96533 100644 --- a/app/services/application_settings/update_service.rb +++ b/app/services/application_settings/update_service.rb @@ -38,7 +38,7 @@ module ApplicationSettings def performance_bar_allowed_group_id performance_bar_enabled = !params.key?(:performance_bar_enabled) || params.delete(:performance_bar_enabled) group_full_path = params.delete(:performance_bar_allowed_group_path) - return nil unless Gitlab::Utils.to_boolean(performance_bar_enabled) + return unless Gitlab::Utils.to_boolean(performance_bar_enabled) Group.find_by_full_path(group_full_path)&.id if group_full_path.present? end diff --git a/app/services/boards/visits/latest_service.rb b/app/services/boards/visits/latest_service.rb index 9e4c77a6317..d13e25b4f12 100644 --- a/app/services/boards/visits/latest_service.rb +++ b/app/services/boards/visits/latest_service.rb @@ -4,13 +4,15 @@ module Boards module Visits class LatestService < Boards::BaseService def execute - return nil unless current_user + return unless current_user - if parent.is_a?(Group) - BoardGroupRecentVisit.latest(current_user, parent) - else - BoardProjectRecentVisit.latest(current_user, parent) - end + recent_visit_model.latest(current_user, parent, count: params[:count]) + end + + private + + def recent_visit_model + parent.is_a?(Group) ? BoardGroupRecentVisit : BoardProjectRecentVisit end end end diff --git a/app/services/clusters/applications/base_helm_service.rb b/app/services/clusters/applications/base_helm_service.rb index 8a71730d5ec..c38b2656260 100644 --- a/app/services/clusters/applications/base_helm_service.rb +++ b/app/services/clusters/applications/base_helm_service.rb @@ -46,6 +46,10 @@ module Clusters @install_command ||= app.install_command end + def update_command + @update_command ||= app.update_command + end + def upgrade_command(new_values = "") app.upgrade_command(new_values) end diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb new file mode 100644 index 00000000000..cbd1cf03ae1 --- /dev/null +++ b/app/services/clusters/applications/base_service.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module Clusters + module Applications + class BaseService + InvalidApplicationError = Class.new(StandardError) + + attr_reader :cluster, :current_user, :params + + def initialize(cluster, user, params = {}) + @cluster = cluster + @current_user = user + @params = params.dup + end + + def execute(request) + instantiate_application.tap do |application| + if application.has_attribute?(:hostname) + application.hostname = params[:hostname] + end + + if application.has_attribute?(:email) + application.email = params[:email] + end + + if application.respond_to?(:oauth_application) + application.oauth_application = create_oauth_application(application, request) + end + + worker = worker_class(application) + + application.make_scheduled! + + worker.perform_async(application.name, application.id) + end + end + + protected + + def worker_class(application) + raise NotImplementedError + end + + def builders + raise NotImplementedError + end + + def project_builders + raise NotImplementedError + end + + def instantiate_application + builder.call(@cluster) || raise(InvalidApplicationError, "invalid application: #{application_name}") + end + + def builder + builders[application_name] || raise(InvalidApplicationError, "invalid application: #{application_name}") + end + + def application_name + params[:application] + end + + def create_oauth_application(application, request) + oauth_application_params = { + name: params[:application], + redirect_uri: application.callback_url, + scopes: 'api read_user openid', + owner: current_user + } + + ::Applications::CreateService.new(current_user, oauth_application_params).execute(request) + end + end + end +end diff --git a/app/services/clusters/applications/create_service.rb b/app/services/clusters/applications/create_service.rb index 12f8c849d41..bd7c31bb981 100644 --- a/app/services/clusters/applications/create_service.rb +++ b/app/services/clusters/applications/create_service.rb @@ -2,47 +2,11 @@ module Clusters module Applications - class CreateService - InvalidApplicationError = Class.new(StandardError) - - attr_reader :cluster, :current_user, :params - - def initialize(cluster, user, params = {}) - @cluster = cluster - @current_user = user - @params = params.dup - end - - def execute(request) - create_application.tap do |application| - if application.has_attribute?(:hostname) - application.hostname = params[:hostname] - end - - if application.has_attribute?(:email) - application.email = params[:email] - end - - if application.respond_to?(:oauth_application) - application.oauth_application = create_oauth_application(application, request) - end - - worker = application.updateable? ? ClusterUpgradeAppWorker : ClusterInstallAppWorker - - application.make_scheduled! - - worker.perform_async(application.name, application.id) - end - end - + class CreateService < Clusters::Applications::BaseService private - def create_application - builder.call(@cluster) - end - - def builder - builders[application_name] || raise(InvalidApplicationError, "invalid application: #{application_name}") + def worker_class(application) + application.updateable? ? ClusterUpgradeAppWorker : ClusterInstallAppWorker end def builders @@ -65,21 +29,6 @@ module Clusters "knative" => -> (cluster) { cluster.application_knative || cluster.build_application_knative } } end - - def application_name - params[:application] - end - - def create_oauth_application(application, request) - oauth_application_params = { - name: params[:application], - redirect_uri: application.callback_url, - scopes: 'api read_user openid', - owner: current_user - } - - ::Applications::CreateService.new(current_user, oauth_application_params).execute(request) - end end end end diff --git a/app/services/clusters/applications/install_service.rb b/app/services/clusters/applications/install_service.rb index 5a65dc4ef59..5bd3623a558 100644 --- a/app/services/clusters/applications/install_service.rb +++ b/app/services/clusters/applications/install_service.rb @@ -6,19 +6,17 @@ module Clusters def execute return unless app.scheduled? - begin - app.make_installing! - helm_api.install(install_command) + app.make_installing! + helm_api.install(install_command) - ClusterWaitForAppInstallationWorker.perform_in( - ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id) - rescue Kubeclient::HttpError => e - log_error(e) - app.make_errored!("Kubernetes error: #{e.error_code}") - rescue StandardError => e - log_error(e) - app.make_errored!("Can't start installation process.") - end + ClusterWaitForAppInstallationWorker.perform_in( + ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id) + rescue Kubeclient::HttpError => e + log_error(e) + app.make_errored!("Kubernetes error: #{e.error_code}") + rescue StandardError => e + log_error(e) + app.make_errored!("Can't start installation process.") end end end diff --git a/app/services/clusters/applications/patch_service.rb b/app/services/clusters/applications/patch_service.rb new file mode 100644 index 00000000000..20c739af7a2 --- /dev/null +++ b/app/services/clusters/applications/patch_service.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Clusters + module Applications + class PatchService < BaseHelmService + def execute + return unless app.scheduled? + + app.make_updating! + + helm_api.update(update_command) + + ClusterWaitForAppInstallationWorker.perform_in( + ClusterWaitForAppInstallationWorker::INTERVAL, app.name, app.id) + rescue Kubeclient::HttpError => e + log_error(e) + app.make_update_errored!("Kubernetes error: #{e.error_code}") + rescue StandardError => e + log_error(e) + app.make_update_errored!("Can't start update process.") + end + end + end +end diff --git a/app/services/clusters/applications/update_service.rb b/app/services/clusters/applications/update_service.rb new file mode 100644 index 00000000000..a9d4e609992 --- /dev/null +++ b/app/services/clusters/applications/update_service.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Clusters + module Applications + class UpdateService < Clusters::Applications::BaseService + private + + def worker_class(application) + ClusterPatchAppWorker + end + + def builders + { + "helm" => -> (cluster) { cluster.application_helm }, + "ingress" => -> (cluster) { cluster.application_ingress }, + "cert_manager" => -> (cluster) { cluster.application_cert_manager } + }.tap do |hash| + hash.merge!(project_builders) if cluster.project_type? + end + end + + # These applications will need extra configuration to enable them to work + # with groups of projects + def project_builders + { + "prometheus" => -> (cluster) { cluster.application_prometheus }, + "runner" => -> (cluster) { cluster.application_runner }, + "jupyter" => -> (cluster) { cluster.application_jupyter }, + "knative" => -> (cluster) { cluster.application_knative } + } + end + end + end +end diff --git a/app/services/commits/create_service.rb b/app/services/commits/create_service.rb index 34593e12bd5..bb34a3d3352 100644 --- a/app/services/commits/create_service.rb +++ b/app/services/commits/create_service.rb @@ -11,6 +11,7 @@ module Commits @start_project = params[:start_project] || @project @start_branch = params[:start_branch] @branch_name = params[:branch_name] + @force = params[:force] || false end def execute @@ -42,10 +43,14 @@ module Commits @start_branch != @branch_name || @start_project != @project end + def force? + !!@force + end + def validate! validate_permissions! validate_on_branch! - validate_branch_existance! + validate_branch_existence! validate_new_branch_name! if different_branch? end @@ -64,14 +69,14 @@ module Commits end end - def validate_branch_existance! - if !project.empty_repo? && different_branch? && repository.branch_exists?(@branch_name) + def validate_branch_existence! + if !project.empty_repo? && different_branch? && repository.branch_exists?(@branch_name) && !force? raise_error("A branch called '#{@branch_name}' already exists. Switch to that branch in order to make changes") end end def validate_new_branch_name! - result = ValidateNewBranchService.new(project, current_user).execute(@branch_name) + result = ValidateNewBranchService.new(project, current_user).execute(@branch_name, force: force?) if result[:status] == :error raise_error("Something went wrong when we tried to create '#{@branch_name}' for you: #{result[:message]}") diff --git a/app/services/error_tracking/list_projects_service.rb b/app/services/error_tracking/list_projects_service.rb index c6e8be0f2be..4e92353a13c 100644 --- a/app/services/error_tracking/list_projects_service.rb +++ b/app/services/error_tracking/list_projects_service.rb @@ -28,8 +28,8 @@ module ErrorTracking (project.error_tracking_setting || project.build_error_tracking_setting).tap do |setting| setting.api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from( api_host: params[:api_host], - organization_slug: nil, - project_slug: nil + organization_slug: 'org', + project_slug: 'proj' ) setting.token = params[:token] diff --git a/app/services/files/multi_service.rb b/app/services/files/multi_service.rb index 927634c2159..c1bc26c330a 100644 --- a/app/services/files/multi_service.rb +++ b/app/services/files/multi_service.rb @@ -46,7 +46,8 @@ module Files author_email: @author_email, author_name: @author_name, start_project: @start_project, - start_branch_name: @start_branch + start_branch_name: @start_branch, + force: force? ) rescue ArgumentError => e raise_error(e) diff --git a/app/services/groups/nested_create_service.rb b/app/services/groups/nested_create_service.rb index f01f5656296..01bd685712b 100644 --- a/app/services/groups/nested_create_service.rb +++ b/app/services/groups/nested_create_service.rb @@ -12,7 +12,7 @@ module Groups end def execute - return nil unless group_path + return unless group_path if namespace = namespace_or_group(group_path) return namespace diff --git a/app/services/groups/transfer_service.rb b/app/services/groups/transfer_service.rb index f64e327416a..94185605ab9 100644 --- a/app/services/groups/transfer_service.rb +++ b/app/services/groups/transfer_service.rb @@ -35,7 +35,10 @@ module Groups def proceed_to_transfer Group.transaction do update_group_attributes + ensure_ownership end + + true end def ensure_allowed_transfer @@ -95,6 +98,13 @@ module Groups end # rubocop: enable CodeReuse/ActiveRecord + def ensure_ownership + return if @new_parent_group + return unless @group.owners.empty? + + @group.add_owner(current_user) + end + def raise_transfer_error(message) raise TransferError, ERROR_MESSAGES[message] end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index ef991eaf234..f35ad2a9d8b 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -89,7 +89,7 @@ class IssuableBaseService < BaseService return unless labels - params[:label_ids] = labels.split(",").map do |label_name| + params[:label_ids] = labels.map do |label_name| label = Labels::FindOrCreateService.new( current_user, parent, @@ -387,4 +387,10 @@ class IssuableBaseService < BaseService def parent project end + + # we need to check this because milestone from milestone_id param is displayed on "new" page + # where private project milestone could leak without this check + def ensure_milestone_available(issuable) + issuable.milestone_id = nil unless issuable.milestone_available? + end end diff --git a/app/services/issues/build_service.rb b/app/services/issues/build_service.rb index 3fb2c2b3007..61615ac2058 100644 --- a/app/services/issues/build_service.rb +++ b/app/services/issues/build_service.rb @@ -6,7 +6,9 @@ module Issues def execute filter_resolve_discussion_params - @issue = project.issues.new(issue_params) + @issue = project.issues.new(issue_params).tap do |issue| + ensure_milestone_available(issue) + end end def issue_params_with_info_from_discussions diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index ac51fee0b3f..11ede5223e5 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -67,7 +67,7 @@ module MergeRequests Ci::CreatePipelineService .new(merge_request.source_project, user, ref: merge_request.source_branch) - .execute(:merge_request, + .execute(:merge_request_event, ignore_skip_ci: true, save_on_errors: false, merge_request: merge_request) diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb index 48419da98ad..109c964e577 100644 --- a/app/services/merge_requests/build_service.rb +++ b/app/services/merge_requests/build_service.rb @@ -19,6 +19,7 @@ module MergeRequests merge_request.target_project = find_target_project merge_request.target_branch = find_target_branch merge_request.can_be_created = projects_and_branches_valid? + ensure_milestone_available(merge_request) # compare branches only if branches are valid, otherwise # compare_branches may raise an error diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 8241e408ce5..b29e0b1759e 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -76,8 +76,7 @@ module MergeRequests def try_merge repository.merge(current_user, source, merge_request, commit_message) rescue Gitlab::Git::PreReceiveError => e - handle_merge_error(log_message: e.message) - raise_error('Something went wrong during merge pre-receive hook') + raise_error("Something went wrong during merge pre-receive hook: #{e.message}") rescue => e handle_merge_error(log_message: e.message) raise_error('Something went wrong during merge') diff --git a/app/services/merge_requests/merge_to_ref_service.rb b/app/services/merge_requests/merge_to_ref_service.rb index 586652ae44e..69cc441f1bb 100644 --- a/app/services/merge_requests/merge_to_ref_service.rb +++ b/app/services/merge_requests/merge_to_ref_service.rb @@ -20,7 +20,12 @@ module MergeRequests raise_error('Conflicts detected during merge') unless commit_id - success(commit_id: commit_id) + commit = project.commit(commit_id) + target_id, source_id = commit.parent_ids + + success(commit_id: commit.id, + target_id: target_id, + source_id: source_id) rescue MergeError => error error(error.message) end @@ -38,12 +43,8 @@ module MergeRequests error = if Feature.disabled?(:merge_to_tmp_merge_ref_path, project) 'Feature is not enabled' - elsif !merge_method_supported? - "#{project.human_merge_method} to #{target_ref} is currently not supported." elsif !hooks_validation_pass?(merge_request) hooks_validation_error(merge_request) - elsif @merge_request.should_be_rebased? - 'Fast-forward merge is not possible. Please update your source branch.' elsif !@merge_request.mergeable_to_ref? "Merge request is not mergeable to #{target_ref}" elsif !source @@ -68,9 +69,5 @@ module MergeRequests rescue Gitlab::Git::PreReceiveError => error raise MergeError, error.message end - - def merge_method_supported? - [:merge, :rebase_merge].include?(project.merge_method) - end end end diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb index 5a6e7338b42..1b46f6d8a72 100644 --- a/app/services/notes/create_service.rb +++ b/app/services/notes/create_service.rb @@ -21,7 +21,7 @@ module Notes if quick_actions_service.supported?(note) options = { merge_request_diff_head_sha: merge_request_diff_head_sha } - content, command_params = quick_actions_service.extract_commands(note, options) + content, update_params = quick_actions_service.execute(note, options) only_commands = content.empty? @@ -43,16 +43,17 @@ module Notes Suggestions::CreateService.new(note).execute end - if command_params.present? - quick_actions_service.execute(command_params, note) + if quick_actions_service.commands_executed_count.to_i > 0 + if update_params.present? + quick_actions_service.apply_updates(update_params, note) + note.commands_changes = update_params + end # We must add the error after we call #save because errors are reset # when #save is called if only_commands note.errors.add(:commands_only, 'Commands applied') end - - note.commands_changes = command_params end note diff --git a/app/services/notes/quick_actions_service.rb b/app/services/notes/quick_actions_service.rb index 985a03060bd..0852a708240 100644 --- a/app/services/notes/quick_actions_service.rb +++ b/app/services/notes/quick_actions_service.rb @@ -1,7 +1,18 @@ # frozen_string_literal: true +# QuickActionsService class +# +# Executes quick actions commands extracted from note text +# +# Most commands returns parameters to be applied later +# using QuickActionService#apply_updates +# module Notes class QuickActionsService < BaseService + attr_reader :interpret_service + + delegate :commands_executed_count, to: :interpret_service, allow_nil: true + UPDATE_SERVICES = { 'Issue' => Issues::UpdateService, 'MergeRequest' => MergeRequests::UpdateService, @@ -25,18 +36,21 @@ module Notes self.class.supported?(note) end - def extract_commands(note, options = {}) + def execute(note, options = {}) return [note.note, {}] unless supported?(note) - QuickActions::InterpretService.new(project, current_user, options) - .execute(note.note, note.noteable) + @interpret_service = QuickActions::InterpretService.new(project, current_user, options) + + @interpret_service.execute(note.note, note.noteable) end - def execute(command_params, note) - return if command_params.empty? + # Applies updates extracted to note#noteable + # The update parameters are extracted on self#execute + def apply_updates(update_params, note) + return if update_params.empty? return unless supported?(note) - self.class.noteable_update_service(note).new(note.parent, current_user, command_params).execute(note.noteable) + self.class.noteable_update_service(note).new(note.parent, current_user, update_params).execute(note.noteable) end end end diff --git a/app/services/projects/download_service.rb b/app/services/projects/download_service.rb index dd297c9ba43..aba175eb79b 100644 --- a/app/services/projects/download_service.rb +++ b/app/services/projects/download_service.rb @@ -11,7 +11,7 @@ module Projects end def execute - return nil unless valid_url?(@url) + return unless valid_url?(@url) uploader = FileUploader.new(@project) uploader.download!(@url) diff --git a/app/services/projects/group_links/create_service.rb b/app/services/projects/group_links/create_service.rb index 1392775f805..e3d5bea0852 100644 --- a/app/services/projects/group_links/create_service.rb +++ b/app/services/projects/group_links/create_service.rb @@ -4,13 +4,19 @@ module Projects module GroupLinks class CreateService < BaseService def execute(group) - return false unless group + return error('Not Found', 404) unless group && can?(current_user, :read_namespace, group) - project.project_group_links.create( + link = project.project_group_links.new( group: group, group_access: params[:link_group_access], expires_at: params[:expires_at] ) + + if link.save + success(link: link) + else + error(link.errors.full_messages.to_sentence, 409) + end end end end diff --git a/app/services/projects/hashed_storage/base_attachment_service.rb b/app/services/projects/hashed_storage/base_attachment_service.rb new file mode 100644 index 00000000000..828ab616bab --- /dev/null +++ b/app/services/projects/hashed_storage/base_attachment_service.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Projects + module HashedStorage + AttachmentMigrationError = Class.new(StandardError) + + AttachmentCannotMoveError = Class.new(StandardError) + + class BaseAttachmentService < BaseService + # Returns the disk_path value before the execution + attr_reader :old_disk_path + + # Returns the disk_path value after the execution + attr_reader :new_disk_path + + # Returns the logger currently in use + attr_reader :logger + + # Return whether this operation was skipped or not + # + # @return [Boolean] true if skipped of false otherwise + def skipped? + @skipped + end + + protected + + def move_folder!(old_path, new_path) + unless File.directory?(old_path) + logger.info("Skipped attachments move from '#{old_path}' to '#{new_path}', source path doesn't exist or is not a directory (PROJECT_ID=#{project.id})") + @skipped = true + + return true + end + + if File.exist?(new_path) + logger.error("Cannot move attachments from '#{old_path}' to '#{new_path}', target path already exist (PROJECT_ID=#{project.id})") + raise AttachmentCannotMoveError, "Target path '#{new_path}' already exists" + end + + # Create base path folder on the new storage layout + FileUtils.mkdir_p(File.dirname(new_path)) + + FileUtils.mv(old_path, new_path) + logger.info("Project attachments moved from '#{old_path}' to '#{new_path}' (PROJECT_ID=#{project.id})") + + true + end + end + end +end diff --git a/app/services/projects/hashed_storage/base_repository_service.rb b/app/services/projects/hashed_storage/base_repository_service.rb index 761c81d776f..f97a28b8c3b 100644 --- a/app/services/projects/hashed_storage/base_repository_service.rb +++ b/app/services/projects/hashed_storage/base_repository_service.rb @@ -2,11 +2,8 @@ module Projects module HashedStorage - # Returned when there is an error with the Hashed Storage migration - RepositoryMigrationError = Class.new(StandardError) - - # Returned when there is an error with the Hashed Storage rollback - RepositoryRollbackError = Class.new(StandardError) + # Returned when repository can't be made read-only because there is already a git transfer in progress + RepositoryInUseError = Class.new(StandardError) class BaseRepositoryService < BaseService include Gitlab::ShellAdapter @@ -38,7 +35,10 @@ module Projects # project was not originally empty. if !from_exists && !to_exists logger.warn "Can't find a repository on either source or target paths for #{project.full_path} (ID=#{project.id}) ..." - return false + + # We return true so we still reflect the change in the database. + # Next time the repository is (re)created it will be under the new storage layout + return true elsif !from_exists # Repository have been moved already. return true @@ -52,6 +52,16 @@ module Projects move_repository(new_disk_path, old_disk_path) move_repository("#{new_disk_path}.wiki", old_wiki_disk_path) end + + def try_to_set_repository_read_only! + # Mitigate any push operation to start during migration + unless project.set_repository_read_only! + migration_error = "Target repository '#{old_disk_path}' cannot be made read-only as there is a git transfer in progress" + logger.error migration_error + + raise RepositoryInUseError, migration_error + end + end end end end diff --git a/app/services/projects/hashed_storage/migrate_attachments_service.rb b/app/services/projects/hashed_storage/migrate_attachments_service.rb index 03e0685d2cd..9eaeb6eb4e7 100644 --- a/app/services/projects/hashed_storage/migrate_attachments_service.rb +++ b/app/services/projects/hashed_storage/migrate_attachments_service.rb @@ -2,62 +2,37 @@ module Projects module HashedStorage - AttachmentMigrationError = Class.new(StandardError) - - class MigrateAttachmentsService < BaseService - attr_reader :logger, :old_disk_path, :new_disk_path - + class MigrateAttachmentsService < BaseAttachmentService def initialize(project, old_disk_path, logger: nil) @project = project @logger = logger || Rails.logger @old_disk_path = old_disk_path - @new_disk_path = project.disk_path @skipped = false end def execute origin = FileUploader.absolute_base_dir(project) - # It's possible that old_disk_path does not match project.disk_path. For example, that happens when we rename a project + # It's possible that old_disk_path does not match project.disk_path. + # For example, that happens when we rename a project origin.sub!(/#{Regexp.escape(project.full_path)}\z/, old_disk_path) project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:attachments] target = FileUploader.absolute_base_dir(project) - result = move_folder!(origin, target) - project.save! - - if result && block_given? - yield - end - - result - end - - def skipped? - @skipped - end + @new_disk_path = project.disk_path - private + result = move_folder!(origin, target) - def move_folder!(old_path, new_path) - unless File.directory?(old_path) - logger.info("Skipped attachments migration from '#{old_path}' to '#{new_path}', source path doesn't exist or is not a directory (PROJECT_ID=#{project.id})") - @skipped = true - return true - end + if result + project.save! - if File.exist?(new_path) - logger.error("Cannot migrate attachments from '#{old_path}' to '#{new_path}', target path already exist (PROJECT_ID=#{project.id})") - raise AttachmentMigrationError, "Target path '#{new_path}' already exist" + yield if block_given? + else + # Rollback changes + project.rollback! end - # Create hashed storage base path folder - FileUtils.mkdir_p(File.dirname(new_path)) - - FileUtils.mv(old_path, new_path) - logger.info("Migrated project attachments from '#{old_path}' to '#{new_path}' (PROJECT_ID=#{project.id})") - - true + result end end end diff --git a/app/services/projects/hashed_storage/migrate_repository_service.rb b/app/services/projects/hashed_storage/migrate_repository_service.rb index 9c672283c7e..5afa8732c0a 100644 --- a/app/services/projects/hashed_storage/migrate_repository_service.rb +++ b/app/services/projects/hashed_storage/migrate_repository_service.rb @@ -15,7 +15,7 @@ module Projects result = move_repository(old_disk_path, new_disk_path) if move_wiki - result &&= move_repository("#{old_wiki_disk_path}", "#{new_disk_path}.wiki") + result &&= move_repository(old_wiki_disk_path, "#{new_disk_path}.wiki") end if result @@ -35,18 +35,6 @@ module Projects result end - - private - - def try_to_set_repository_read_only! - # Mitigate any push operation to start during migration - unless project.set_repository_read_only! - migration_error = "Target repository '#{old_disk_path}' cannot be made read-only as there is a git transfer in progress" - logger.error migration_error - - raise RepositoryMigrationError, migration_error - end - end end end end diff --git a/app/services/projects/hashed_storage/rollback_attachments_service.rb b/app/services/projects/hashed_storage/rollback_attachments_service.rb new file mode 100644 index 00000000000..6c370ac47e9 --- /dev/null +++ b/app/services/projects/hashed_storage/rollback_attachments_service.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Projects + module HashedStorage + class RollbackAttachmentsService < BaseAttachmentService + def initialize(project, logger: nil) + @project = project + @logger = logger || Rails.logger + @old_disk_path = project.disk_path + end + + def execute + origin = FileUploader.absolute_base_dir(project) + project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:repository] + target = FileUploader.absolute_base_dir(project) + + @new_disk_path = FileUploader.base_dir(project) + + result = move_folder!(origin, target) + + if result + project.save! + + yield if block_given? + else + # Rollback changes + project.rollback! + end + + result + end + end + end +end diff --git a/app/services/projects/hashed_storage/rollback_repository_service.rb b/app/services/projects/hashed_storage/rollback_repository_service.rb new file mode 100644 index 00000000000..b5c971c70a5 --- /dev/null +++ b/app/services/projects/hashed_storage/rollback_repository_service.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Projects + module HashedStorage + class RollbackRepositoryService < BaseRepositoryService + def execute + try_to_set_repository_read_only! + + @old_storage_version = project.storage_version + project.storage_version = nil + project.ensure_storage_path_exists + + @new_disk_path = project.disk_path + + result = move_repository(old_disk_path, new_disk_path) + + if move_wiki + result &&= move_repository(old_wiki_disk_path, "#{new_disk_path}.wiki") + end + + if result + project.write_repository_config + project.track_project_repository + else + rollback_folder_move + project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:repository] + end + + project.repository_read_only = false + project.save! + + if result && block_given? + yield + end + + result + end + end + end +end diff --git a/app/services/projects/hashed_storage/rollback_service.rb b/app/services/projects/hashed_storage/rollback_service.rb new file mode 100644 index 00000000000..25767f5de5e --- /dev/null +++ b/app/services/projects/hashed_storage/rollback_service.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Projects + module HashedStorage + class RollbackService < BaseService + attr_reader :logger, :old_disk_path + + def initialize(project, old_disk_path, logger: nil) + @project = project + @old_disk_path = old_disk_path + @logger = logger || Rails.logger + end + + def execute + # Rollback attachments from Hashed Storage to Legacy + if project.hashed_storage?(:attachments) + return false unless rollback_attachments + end + + # Rollback repository from Hashed Storage to Legacy + if project.hashed_storage?(:repository) + rollback_repository + end + end + + private + + def rollback_attachments + HashedStorage::RollbackAttachmentsService.new(project, logger: logger).execute + end + + def rollback_repository + HashedStorage::RollbackRepositoryService.new(project, old_disk_path, logger: logger).execute + end + end + end +end diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb index abd6d8de750..aedf79c86d7 100644 --- a/app/services/projects/operations/update_service.rb +++ b/app/services/projects/operations/update_service.rb @@ -12,7 +12,28 @@ module Projects private def project_update_params - params.slice(:error_tracking_setting_attributes) + error_tracking_params + end + + def error_tracking_params + settings = params[:error_tracking_setting_attributes] + return {} if settings.blank? + + api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from( + api_host: settings[:api_host], + project_slug: settings.dig(:project, :slug), + organization_slug: settings.dig(:project, :organization_slug) + ) + + { + error_tracking_setting_attributes: { + api_url: api_url, + token: settings[:token], + enabled: settings[:enabled], + project_name: settings.dig(:project, :name), + organization_name: settings.dig(:project, :organization_name) + } + } end end end diff --git a/app/services/push_event_payload_service.rb b/app/services/push_event_payload_service.rb index bb1259787af..fe366ac225b 100644 --- a/app/services/push_event_payload_service.rb +++ b/app/services/push_event_payload_service.rb @@ -46,7 +46,7 @@ class PushEventPayloadService def commit_title commit = @push_data.fetch(:commits).last - return nil unless commit && commit[:message] + return unless commit && commit[:message] raw_msg = commit[:message] diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 5c58caee8cd..131efb8925e 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -7,6 +7,11 @@ module QuickActions attr_reader :issuable + # Counts how many commands have been executed. + # Used to display relevant feedback on UI when a note + # with only commands has been processed. + attr_accessor :commands_executed_count + SHRUG = '¯\\_(ツ)_/¯'.freeze TABLEFLIP = '(╯°□°)╯︵ ┻━┻'.freeze diff --git a/app/services/suggestions/apply_service.rb b/app/services/suggestions/apply_service.rb index 1f720fc835f..f778c5aa5f5 100644 --- a/app/services/suggestions/apply_service.rb +++ b/app/services/suggestions/apply_service.rb @@ -15,7 +15,13 @@ module Suggestions return error('The file has been changed') end - params = file_update_params(suggestion) + diff_file = suggestion.note.latest_diff_file + + unless diff_file + return error('The file was not found') + end + + params = file_update_params(suggestion, diff_file) result = ::Files::UpdateService.new(suggestion.project, @current_user, params).execute if result[:status] == :success @@ -38,8 +44,8 @@ module Suggestions suggestion.position.head_sha == suggestion.noteable.source_branch_sha end - def file_update_params(suggestion) - blob = suggestion.diff_file.new_blob + def file_update_params(suggestion, diff_file) + blob = diff_file.new_blob file_path = suggestion.file_path branch_name = suggestion.branch file_content = new_file_content(suggestion, blob) diff --git a/app/services/suggestions/create_service.rb b/app/services/suggestions/create_service.rb index 77e958cbe0c..c7ac2452c53 100644 --- a/app/services/suggestions/create_service.rb +++ b/app/services/suggestions/create_service.rb @@ -9,6 +9,10 @@ module Suggestions def execute return unless @note.supports_suggestion? + diff_file = @note.latest_diff_file + + return unless diff_file + suggestions = Banzai::SuggestionsParser.parse(@note.note) # For single line suggestion we're only looking forward to @@ -20,7 +24,7 @@ module Suggestions rows = suggestions.map.with_index do |suggestion, index| - from_content = changing_lines(comment_line, comment_line) + from_content = changing_lines(diff_file, comment_line, comment_line) # The parsed suggestion doesn't have information about the correct # ending characters (we may have a line break, or not), so we take @@ -44,8 +48,8 @@ module Suggestions private - def changing_lines(from_line, to_line) - @note.diff_file.new_blob_lines_between(from_line, to_line).join + def changing_lines(diff_file, from_line, to_line) + diff_file.new_blob_lines_between(from_line, to_line).join end def line_break_chars(line) diff --git a/app/services/upload_service.rb b/app/services/upload_service.rb index 41ca95b3b6f..403944557a2 100644 --- a/app/services/upload_service.rb +++ b/app/services/upload_service.rb @@ -6,7 +6,7 @@ class UploadService end def execute - return nil unless @file && @file.size <= max_attachment_size + return unless @file && @file.size <= max_attachment_size uploader = @uploader_class.new(@model, nil, @uploader_context) uploader.store!(@file) diff --git a/app/services/validate_new_branch_service.rb b/app/services/validate_new_branch_service.rb index c19e2ec2043..3f4a59e5cee 100644 --- a/app/services/validate_new_branch_service.rb +++ b/app/services/validate_new_branch_service.rb @@ -3,14 +3,14 @@ require_relative 'base_service' class ValidateNewBranchService < BaseService - def execute(branch_name) + def execute(branch_name, force: false) valid_branch = Gitlab::GitRefValidator.validate(branch_name) unless valid_branch return error('Branch name is invalid') end - if project.repository.branch_exists?(branch_name) + if project.repository.branch_exists?(branch_name) && !force return error('Branch already exists') end diff --git a/app/uploaders/file_mover.rb b/app/uploaders/file_mover.rb index a7f8615e9ba..236b7ed2b3d 100644 --- a/app/uploaders/file_mover.rb +++ b/app/uploaders/file_mover.rb @@ -11,6 +11,8 @@ class FileMover end def execute + return unless valid? + move if update_markdown @@ -21,6 +23,12 @@ class FileMover private + def valid? + Pathname.new(temp_file_path).realpath.to_path.start_with?( + (Pathname(temp_file_uploader.root) + temp_file_uploader.base_dir).to_path + ) + end + def move FileUtils.mkdir_p(File.dirname(file_path)) FileUtils.move(temp_file_path, file_path) diff --git a/app/validators/sha_validator.rb b/app/validators/sha_validator.rb new file mode 100644 index 00000000000..085fca4d65d --- /dev/null +++ b/app/validators/sha_validator.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class ShaValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return if value.blank? || value.match(/\A\h{40}\z/) + + record.errors.add(attribute, 'is not a valid SHA') + end +end diff --git a/app/views/admin/appearances/_system_header_footer_form.html.haml b/app/views/admin/appearances/_system_header_footer_form.html.haml index ca9d6adebeb..4301ebd05af 100644 --- a/app/views/admin/appearances/_system_header_footer_form.html.haml +++ b/app/views/admin/appearances/_system_header_footer_form.html.haml @@ -13,6 +13,15 @@ .form-group = form.label :footer_message, _('Footer message'), class: 'col-form-label label-bold' = form.text_area :footer_message, placeholder: _('State your message to activate'), class: "form-control js-autosize" + .form-group + .form-check + = form.check_box :email_header_and_footer_enabled, class: 'form-check-input' + = form.label :email_header_and_footer_enabled, class: 'label-bold' do + = _('Enable header and footer in emails') + + .hint + = _('Add header and footer to emails. Please note that color settings will only be applied within the application interface') + .form-group.js-toggle-colors-container %button.btn.btn-link.js-toggle-colors-link{ type: 'button' } = _('Customize colors') diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml index 81380587fd2..2e23b748edb 100644 --- a/app/views/admin/runners/index.html.haml +++ b/app/views/admin/runners/index.html.haml @@ -92,6 +92,25 @@ = button_tag class: %w[btn btn-link] do = runner_type.titleize + #js-dropdown-admin-runner-type.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + - Ci::Runner::AVAILABLE_TYPES.each do |runner_type| + %li.filter-dropdown-item{ data: { value: runner_type } } + = button_tag class: %w[btn btn-link] do + = runner_type.titleize + + #js-dropdown-runner-tag.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + %li.filter-dropdown-item{ data: { value: 'none' } } + %button.btn.btn-link + = _('No Tag') + %li.divider.droplab-item-ignore + %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } + %li.filter-dropdown-item + %button.btn.btn-link.js-data-value + %span.dropdown-light-content + {{name}} + = button_tag class: %w[clear-search hidden] do = icon('times') .filter-dropdown-container diff --git a/app/views/ci/status/_icon.html.haml b/app/views/ci/status/_icon.html.haml new file mode 100644 index 00000000000..f38bdb2e5ed --- /dev/null +++ b/app/views/ci/status/_icon.html.haml @@ -0,0 +1,16 @@ +- status = local_assigns.fetch(:status) +- size = local_assigns.fetch(:size, 16) +- type = local_assigns.fetch(:type, 'pipeline') +- tooltip_placement = local_assigns.fetch(:tooltip_placement, "left") +- path = local_assigns.fetch(:path, status.has_details? ? status.details_path : nil) +- css_classes = "ci-status-link ci-status-icon ci-status-icon-#{status.group} has-tooltip" +- title = s_("PipelineStatusTooltip|Pipeline: %{ci_status}") % {ci_status: status.label} +- if type == 'commit' + - title = s_("PipelineStatusTooltip|Commit: %{ci_status}") % {ci_status: status.label} + +- if path + = link_to path, class: css_classes, title: title, data: { placement: tooltip_placement } do + = sprite_icon(status.icon, size: size) +- else + %span{ class: css_classes, title: title, data: { placement: tooltip_placement } } + = sprite_icon(status.icon, size: size) diff --git a/app/views/clusters/clusters/show.html.haml b/app/views/clusters/clusters/show.html.haml index 1ef76ef801e..7d381c6d4a6 100644 --- a/app/views/clusters/clusters/show.html.haml +++ b/app/views/clusters/clusters/show.html.haml @@ -15,6 +15,7 @@ install_runner_path: clusterable.install_applications_cluster_path(@cluster, :runner), install_jupyter_path: clusterable.install_applications_cluster_path(@cluster, :jupyter), install_knative_path: clusterable.install_applications_cluster_path(@cluster, :knative), + update_knative_path: clusterable.update_applications_cluster_path(@cluster, :knative), toggle_status: @cluster.enabled? ? 'true': 'false', has_rbac: @cluster.platform_kubernetes_rbac? ? 'true': 'false', cluster_type: @cluster.cluster_type, diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 39d0f620283..2f635757902 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -25,6 +25,8 @@ .settings-content = render 'groups/settings/permissions' += render_if_exists 'groups/insights', expanded: expanded + %section.settings.no-animate#js-badge-settings{ class: ('expanded' if expanded) } .settings-header %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only{ role: 'button' } diff --git a/app/views/layouts/_mailer.html.haml b/app/views/layouts/_mailer.html.haml index 26fd34347ec..e13490ed410 100644 --- a/app/views/layouts/_mailer.html.haml +++ b/app/views/layouts/_mailer.html.haml @@ -52,6 +52,7 @@ %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:#6b4fbb;height:4px;font-size:4px;line-height:4px;" } %tr.header %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } + = html_header_message = header_logo %tr %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;" } @@ -72,3 +73,6 @@ = _("You're receiving this email because of your account on %{host}. %{manage_notifications_link} · %{help_link}").html_safe % { host: Gitlab.config.gitlab.host, manage_notifications_link: manage_notifications_link, help_link: help_link } = yield :additional_footer + %tr + %td{ style: "font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;padding:25px 0;font-size:13px;line-height:1.6;color:#5c5c5c;" } + = html_footer_message diff --git a/app/views/layouts/empty_mailer.html.haml b/app/views/layouts/empty_mailer.html.haml new file mode 100644 index 00000000000..a25dcefd445 --- /dev/null +++ b/app/views/layouts/empty_mailer.html.haml @@ -0,0 +1,5 @@ += html_header_message + += yield + += html_footer_message diff --git a/app/views/layouts/empty_mailer.text.erb b/app/views/layouts/empty_mailer.text.erb new file mode 100644 index 00000000000..6ab0dbead07 --- /dev/null +++ b/app/views/layouts/empty_mailer.text.erb @@ -0,0 +1,5 @@ +<%= text_header_message %> + +<%= yield -%> + +<%= text_footer_message %> diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb index 8e11174f8d7..f8032f3262b 100644 --- a/app/views/layouts/mailer.text.erb +++ b/app/views/layouts/mailer.text.erb @@ -1,4 +1,8 @@ +<%= text_header_message %> + <%= yield -%> -- <%# signature marker %> <%= _("You're receiving this email because of your account on %{host}.") % { host: Gitlab.config.gitlab.host } %> + +<%= text_footer_message %> diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml index 1c3e05e07f4..8dff12c1b7f 100644 --- a/app/views/layouts/notify.html.haml +++ b/app/views/layouts/notify.html.haml @@ -7,6 +7,7 @@ = yield :head %body .content + = html_header_message = yield .footer{ style: "margin-top: 10px;" } %p @@ -30,3 +31,4 @@ adjust your notification settings. = email_action @target_url + = html_footer_message diff --git a/app/views/layouts/notify.text.erb b/app/views/layouts/notify.text.erb index 9dc490efa9a..248916fba63 100644 --- a/app/views/layouts/notify.text.erb +++ b/app/views/layouts/notify.text.erb @@ -1,3 +1,5 @@ +<%= text_header_message %> + <%= yield -%> -- <%# signature marker %> @@ -10,3 +12,5 @@ <% end -%> <%= "You're receiving this email because #{notification_reason_text(@reason)}." %> + +<%= text_footer_message -%> diff --git a/app/views/notify/issue_moved_email.html.haml b/app/views/notify/issue_moved_email.html.haml index 472c31e9a5e..b766cb1a523 100644 --- a/app/views/notify/issue_moved_email.html.haml +++ b/app/views/notify/issue_moved_email.html.haml @@ -1,6 +1,9 @@ %p Issue was moved to another project. -%p - New issue: - = link_to project_issue_url(@new_project, @new_issue) do - = @new_issue.title +- if @can_access_project + %p + New issue: + = link_to project_issue_url(@new_project, @new_issue) do + = @new_issue.title +- else + You don't have access to the project. diff --git a/app/views/notify/issue_moved_email.text.erb b/app/views/notify/issue_moved_email.text.erb index 66ede43635b..985e689aa9d 100644 --- a/app/views/notify/issue_moved_email.text.erb +++ b/app/views/notify/issue_moved_email.text.erb @@ -1,4 +1,8 @@ Issue was moved to another project. +<% if @can_access_project %> New issue location: <%= project_issue_url(@new_project, @new_issue) %> +<% else %> +You don't have access to the project. +<% end %> diff --git a/app/views/profiles/active_sessions/_active_session.html.haml b/app/views/profiles/active_sessions/_active_session.html.haml index 23ef31a0c85..2bf514d72a5 100644 --- a/app/views/profiles/active_sessions/_active_session.html.haml +++ b/app/views/profiles/active_sessions/_active_session.html.haml @@ -23,9 +23,3 @@ %strong Signed in on = l(active_session.created_at, format: :short) - - - unless is_current_session - .float-right - = link_to profile_active_session_path(active_session.session_id), data: { confirm: 'Are you sure? The device will be signed out of GitLab.' }, method: :delete, class: "btn btn-danger prepend-left-10" do - %span.sr-only Revoke - Revoke diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml index bba303c906c..1d7287410ea 100644 --- a/app/views/projects/_home_panel.html.haml +++ b/app/views/projects/_home_panel.html.haml @@ -1,5 +1,6 @@ - empty_repo = @project.empty_repo? - show_auto_devops_callout = show_auto_devops_callout?(@project) +- max_project_topic_length = 15 .project-home-panel{ class: ("empty-project" if empty_repo) } .row.append-bottom-8 .home-panel-title-row.col-md-12.col-lg-6.d-flex @@ -19,15 +20,21 @@ %span.access-request-links.prepend-left-8 = render 'shared/members/access_request_links', source: @project - if @project.tag_list.present? - %span.home-panel-topic-list.d-inline-flex.prepend-left-8.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_topics? ? @project.tag_list.join(', ') : nil } + %span.home-panel-topic-list.d-inline-flex.prepend-left-8 = sprite_icon('tag', size: 16, css_class: 'icon append-right-4') - @project.topics_to_show.each do |topic| - %a{ class: 'badge badge-pill badge-secondary append-right-5 str-truncated-30', href: explore_projects_path(tag: topic) } - = topic.titleize + - project_topics_classes = "badge badge-pill badge-secondary append-right-5" + - explore_project_topic_path = explore_projects_path(tag: topic) + - if topic.length > max_project_topic_length + %a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path } + = topic.titleize + - else + %a{ class: project_topics_classes, href: explore_project_topic_path } + = topic.titleize - if @project.has_extra_topics? - .text-nowrap + .text-nowrap.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_topics? ? @project.topics_not_shown.join(', ') : nil } = _("+ %{count} more") % { count: @project.count_of_extra_topics_not_shown } diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml index 03ba1104507..830cfa80d58 100644 --- a/app/views/projects/_md_preview.html.haml +++ b/app/views/projects/_md_preview.html.haml @@ -12,10 +12,10 @@ %ul.nav.nav-tabs.nav-links.clearfix %li.md-header-tab.active %button.js-md-write-button{ tabindex: -1 } - Write + = _("Write") %li.md-header-tab %button.js-md-preview-button{ tabindex: -1 } - Preview + = _("Preview") %li.md-header-toolbar.active = render 'projects/blob/markdown_buttons', show_fullscreen_button: true diff --git a/app/views/projects/_merge_request_merge_settings.html.haml b/app/views/projects/_merge_request_merge_settings.html.haml index f178c94e008..6ac2e06afa5 100644 --- a/app/views/projects/_merge_request_merge_settings.html.haml +++ b/app/views/projects/_merge_request_merge_settings.html.haml @@ -9,6 +9,7 @@ %span.descr Pipelines need to be configured to enable this feature. = link_to icon('question-circle'), help_page_path('user/project/merge_requests/merge_when_pipeline_succeeds', anchor: 'only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds'), target: '_blank' + = render_if_exists 'projects/merge_pipelines_settings', form: form .form-check = form.check_box :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-input' = form.label :only_allow_merge_if_all_discussions_are_resolved, class: 'form-check-label' do diff --git a/app/views/projects/blob/_markdown_buttons.html.haml b/app/views/projects/blob/_markdown_buttons.html.haml index 1d6acd86108..28d1ff97825 100644 --- a/app/views/projects/blob/_markdown_buttons.html.haml +++ b/app/views/projects/blob/_markdown_buttons.html.haml @@ -1,13 +1,13 @@ .md-header-toolbar.active - = markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: s_("MarkdownToolbar|Add bold text") }) - = markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: s_("MarkdownToolbar|Add italic text") }) - = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: s_("MarkdownToolbar|Insert a quote") }) - = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: s_("MarkdownToolbar|Insert code") }) - = markdown_toolbar_button({ icon: "link", data: { "md-tag" => "[{text}](url)", "md-select" => "url" }, title: s_("MarkdownToolbar|Add a link") }) - = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a bullet list") }) - = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a numbered list") }) - = markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a task list") }) - = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: s_("MarkdownToolbar|Add a table") }) + = markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: _("Add bold text") }) + = markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: _("Add italic text") }) + = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") }) + = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") }) + = markdown_toolbar_button({ icon: "link", data: { "md-tag" => "[{text}](url)", "md-select" => "url" }, title: _("Add a link") }) + = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "* ", "md-prepend" => true }, title: _("Add a bullet list") }) + = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") }) + = markdown_toolbar_button({ icon: "task-done", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: _("Add a task list") }) + = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") }) - if show_fullscreen_button - %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: s_("MarkdownToolbar|Go full screen"), data: { container: "body" } } + %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } } = sprite_icon("screen-full") diff --git a/app/views/projects/blob/viewers/_dependency_manager.html.haml b/app/views/projects/blob/viewers/_dependency_manager.html.haml index 87aa7c1dbf8..5970d41fdab 100644 --- a/app/views/projects/blob/viewers/_dependency_manager.html.haml +++ b/app/views/projects/blob/viewers/_dependency_manager.html.haml @@ -3,9 +3,4 @@ This project manages its dependencies using %strong= viewer.manager_name - - if viewer.package_name - and defines a #{viewer.package_type} named - %strong< - = link_to_if viewer.package_url.present?, viewer.package_name, viewer.package_url, target: '_blank', rel: 'noopener noreferrer' - = link_to 'Learn more', viewer.manager_url, target: '_blank', rel: 'noopener noreferrer' diff --git a/app/views/projects/buttons/_clone.html.haml b/app/views/projects/buttons/_clone.html.haml index 159d9e44e17..09f05b30433 100644 --- a/app/views/projects/buttons/_clone.html.haml +++ b/app/views/projects/buttons/_clone.html.haml @@ -7,7 +7,7 @@ = sprite_icon("arrow-down", css_class: "icon") %ul.p-3.dropdown-menu.dropdown-menu-right.dropdown-menu-large.dropdown-menu-selectable.clone-options-dropdown.qa-clone-options - if ssh_enabled? - %li.pb-2 + %li %label.label-bold = _('Clone with SSH') .input-group @@ -16,7 +16,7 @@ = clipboard_button(target: '#ssh_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard") = render_if_exists 'projects/buttons/geo' - if http_enabled? - %li + %li.pt-2 %label.label-bold = _('Clone with %{http_label}') % { http_label: gitlab_config.protocol.upcase } .input-group @@ -24,5 +24,6 @@ .input-group-append = clipboard_button(target: '#http_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard") = render_if_exists 'projects/buttons/geo' + = render_if_exists 'projects/buttons/kerberos_clone_field' = render_if_exists 'shared/geo_info_modal', project: project diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml index bdf021fd87f..59f0afd59e6 100644 --- a/app/views/projects/cycle_analytics/show.html.haml +++ b/app/views/projects/cycle_analytics/show.html.haml @@ -10,7 +10,7 @@ .wrapper{ "v-show" => "!isLoading && !hasError" } .card .card-header - {{ __('Pipeline Health') }} + {{ __('Recent Project Activity') }} .content-block .container-fluid .row diff --git a/app/views/projects/deployments/_actions.haml b/app/views/projects/deployments/_actions.haml index f4c91377ecb..e45c5be76de 100644 --- a/app/views/projects/deployments/_actions.haml +++ b/app/views/projects/deployments/_actions.haml @@ -11,4 +11,4 @@ - next unless can?(current_user, :update_build, action) %li = link_to [:play, @project.namespace.becomes(Namespace), @project, action], method: :post, rel: 'nofollow', class: 'btn' do - %span= action.name.humanize + %span= action.name diff --git a/app/views/projects/deployments/_confirm_rollback_modal.html.haml b/app/views/projects/deployments/_confirm_rollback_modal.html.haml new file mode 100644 index 00000000000..ff40e404e5f --- /dev/null +++ b/app/views/projects/deployments/_confirm_rollback_modal.html.haml @@ -0,0 +1,23 @@ +- commit_sha = link_to deployment.short_sha, project_commit_path(@project, deployment.sha), class: "commit-sha has-tooltip", title: h(deployment.commit_title) +.modal.ws-normal.fade{ tabindex: -1, id: "confirm-rollback-modal-#{deployment.id}" } + .modal-dialog + .modal-content + .modal-header + %h4.modal-title.d-flex.mw-100 + - if deployment.last? + = s_("Environments|Re-deploy environment %{environment_name}?") % {environment_name: @environment.name} + - else + = s_("Environments|Rollback environment %{environment_name}?") % {environment_name: @environment.name} + .modal-body + - if deployment.last? + %p= s_('Environments|This action will relaunch the job for commit %{commit_id}, putting the environment in a previous version. Are you sure you want to continue?').html_safe % {commit_id: commit_sha} + - else + %p + = s_('Environments|This action will run the job defined by staging for commit %{commit_id}, putting the environment in a previous version. You can revert it by re-deploying the latest version of your application. Are you sure you want to continue?').html_safe % {commit_id: commit_sha} + .modal-footer + = button_tag _('Cancel'), type: 'button', class: 'btn btn-cancel', data: { dismiss: 'modal' } + = link_to [:retry, @project.namespace.becomes(Namespace), @project, deployment.deployable], method: :post, class: 'btn btn-danger' do + - if deployment.last? + = s_('Environments|Re-deploy') + - else + = s_('Environments|Rollback') diff --git a/app/views/projects/deployments/_rollback.haml b/app/views/projects/deployments/_rollback.haml index 1bd538a08ff..d6bf8d564de 100644 --- a/app/views/projects/deployments/_rollback.haml +++ b/app/views/projects/deployments/_rollback.haml @@ -1,7 +1,8 @@ - if can?(current_user, :create_deployment, deployment) - tooltip = deployment.last? ? s_('Environments|Re-deploy to environment') : s_('Environments|Rollback environment') - = link_to [:retry, @project.namespace.becomes(Namespace), @project, deployment.deployable], method: :post, class: 'btn btn-build has-tooltip', title: tooltip do + = button_tag class: 'btn btn-default btn-build has-tooltip', type: 'button', data: { toggle: 'modal', target: "#confirm-rollback-modal-#{deployment.id}" }, title: tooltip do - if deployment.last? = sprite_icon('repeat') - else = sprite_icon('redo') + = render 'projects/deployments/confirm_rollback_modal', deployment: deployment diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 1a489bfa275..a6a8ca489a9 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -1,17 +1,15 @@ -- breadcrumb_title "General Settings" -- page_title "General" +- breadcrumb_title _("General Settings") +- page_title _("General") - @content_class = "limit-container-width" unless fluid_layout - expanded = Rails.env.test? .project-edit-container %section.settings.general-settings.no-animate#js-general-project-settings{ class: ('expanded' if expanded) } .settings-header - %h4 - General project - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? 'Collapse' : 'Expand' - %p - Update your project name, description, avatar, and other general settings. + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Naming, tags, avatar') + %button.btn.js-settings-toggle{ type: 'button' }= expanded ? _('Collapse') : _('Expand') + %p= _('Update your project name, tags, description and avatar.') + .settings-content .project-edit-errors = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit-project" }, authenticity_token: true do |f| @@ -63,12 +61,10 @@ %section.settings.sharing-permissions.no-animate#js-shared-permissions{ class: ('expanded' if expanded) } .settings-header - %h4 - Permissions - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? 'Collapse' : 'Expand' - %p - Enable or disable certain project features and choose access levels. + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Visibility, project features, permissions') + %button.btn.js-settings-toggle{ type: 'button' }= expanded ? _('Collapse') : _('Expand') + %p= _('Choose visibility level, enable/disable project features (issues, repository, wiki, snippets) and set permissions.') + .settings-content = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "sharing-permissions-form" }, authenticity_token: true do |f| %input{ name: 'update_section', type: 'hidden', value: 'js-shared-permissions' } @@ -81,12 +77,10 @@ %section.qa-merge-request-settings.settings.merge-requests-feature.no-animate#js-merge-request-settings{ class: [('expanded' if expanded), ('hidden' if @project.project_feature.send(:merge_requests_access_level) == 0)] } .settings-header - %h4 - Merge request - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? 'Collapse' : 'Expand' - %p - Customize your merge request restrictions. + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Merge requests') + %button.btn.js-settings-toggle{ type: 'button' }= expanded ? _('Collapse') : _('Expand') + %p= _('Choose your merge method, set up a default merge request description template.') + .settings-content = render_if_exists 'shared/promotions/promote_mr_features' @@ -97,11 +91,10 @@ = render_if_exists 'projects/merge_request_approvals_settings', expanded: expanded - = render_if_exists 'projects/service_desk_settings' %section.settings.no-animate{ class: ('expanded' if expanded) } .settings-header - %h4 + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only = s_('ProjectSettings|Badges') %button.btn.js-settings-toggle{ type: 'button' } = expanded ? 'Collapse' : 'Expand' @@ -111,16 +104,15 @@ .settings-content = render 'shared/badges/badge_settings' + = render_if_exists 'projects/service_desk_settings' = render 'export', project: @project %section.qa-advanced-settings.settings.advanced-settings.no-animate#js-project-advanced-settings{ class: ('expanded' if expanded) } .settings-header - %h4 - Advanced - %button.btn.js-settings-toggle{ type: 'button' } - = expanded ? 'Collapse' : 'Expand' - %p - Perform advanced options such as housekeeping, archiving, renaming, transferring, or removing your project. + %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Advanced') + %button.btn.js-settings-toggle{ type: 'button' }= expanded ? _('Collapse') : _('Expand') + %p= _('Housekeeping, export, path, transfer, remove, archive.') + .settings-content .sub-section %h4 Housekeeping diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml index 310e339ac8d..6a66c2e57cc 100644 --- a/app/views/projects/issues/_merge_requests.html.haml +++ b/app/views/projects/issues/_merge_requests.html.haml @@ -27,7 +27,7 @@ = merge_request.to_reference %span.mr-ci-status.flex-md-grow-1.justify-content-end.d-flex.ml-md-2 - if merge_request.can_read_pipeline? - = render_pipeline_status(merge_request.head_pipeline, tooltip_placement: 'bottom') + = render 'ci/status/icon', status: merge_request.head_pipeline.detailed_status(current_user), tooltip_placement: 'bottom' - elsif has_any_head_pipeline = icon('blank fw') diff --git a/app/views/projects/issues/_related_branches.html.haml b/app/views/projects/issues/_related_branches.html.haml index ffdd96870ef..6da4956a036 100644 --- a/app/views/projects/issues/_related_branches.html.haml +++ b/app/views/projects/issues/_related_branches.html.haml @@ -8,7 +8,7 @@ - pipeline = @project.pipeline_for(branch, target.sha) if target - if can?(current_user, :read_pipeline, pipeline) %span.related-branch-ci-status - = render_pipeline_status(pipeline) + = render 'ci/status/icon', status: pipeline.detailed_status(current_user) %span.related-branch-info %strong = link_to branch, project_compare_path(@project, from: @project.default_branch, to: branch), class: "ref-name" diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml index 90916191d97..b8e0b66e277 100644 --- a/app/views/projects/merge_requests/_merge_request.html.haml +++ b/app/views/projects/merge_requests/_merge_request.html.haml @@ -48,7 +48,7 @@ CLOSED - if can?(current_user, :read_pipeline, merge_request.head_pipeline) %li.issuable-pipeline-status.d-none.d-sm-inline-block - = render_pipeline_status(merge_request.head_pipeline) + = render 'ci/status/icon', status: merge_request.head_pipeline.detailed_status(current_user) - if merge_request.open? && merge_request.broken? %li.issuable-pipeline-broken.d-none.d-sm-inline-block = link_to merge_request_path(merge_request), class: "has-tooltip", title: _('Cannot be merged automatically') do diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index 21b105e6f80..c031815200b 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -57,7 +57,7 @@ %td - if mirror.last_error.present? .badge.mirror-error-badge{ data: { toggle: 'tooltip', html: 'true' }, title: html_escape(mirror.last_error.try(:strip)) }= _('Error') - %td.mirror-action-buttons + %td .btn-group.mirror-actions-group.pull-right{ role: 'group' } - if mirror.ssh_key_auth? = clipboard_button(text: mirror.ssh_public_key, class: 'btn btn-default', title: _('Copy SSH public key')) diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml index 9c2efd6aa35..55adeb345ab 100644 --- a/app/views/projects/pipelines/_info.html.haml +++ b/app/views/projects/pipelines/_info.html.haml @@ -48,7 +48,7 @@ content: "<a class='autodevops-link' href='#{popover_content_url}' target='_blank' rel='noopener noreferrer nofollow'>#{popover_content_text}</a>", } } Auto DevOps - - if @pipeline.merge_request? + - if @pipeline.merge_request_event? %span.js-pipeline-url-mergerequest.badge.badge-info.has-tooltip{ title: "This pipeline is run in a merge request context" } merge request - if @pipeline.stuck? diff --git a/app/views/projects/protected_branches/shared/_index.html.haml b/app/views/projects/protected_branches/shared/_index.html.haml index 539b184e5c2..4997770321e 100644 --- a/app/views/projects/protected_branches/shared/_index.html.haml +++ b/app/views/projects/protected_branches/shared/_index.html.haml @@ -12,7 +12,7 @@ %p By default, protected branches are designed to: %ul - %li prevent their creation, if not already created, from everybody except Maintainers + %li prevent their creation, if not already created, from everybody except users who are allowed to merge %li prevent pushes from everybody except Maintainers %li prevent <strong>anyone</strong> from force pushing to the branch %li prevent <strong>anyone</strong> from deleting the branch diff --git a/app/views/projects/settings/operations/_error_tracking.html.haml b/app/views/projects/settings/operations/_error_tracking.html.haml index 4911e8d3770..6b15331db01 100644 --- a/app/views/projects/settings/operations/_error_tracking.html.haml +++ b/app/views/projects/settings/operations/_error_tracking.html.haml @@ -8,23 +8,11 @@ = _('Error Tracking') %p = _('To link Sentry to GitLab, enter your Sentry URL and Auth Token.') + = link_to _('More information'), help_page_path('user/project/operations/error_tracking'), target: '_blank', rel: 'noopener noreferrer' .settings-content - = form_for @project, url: project_settings_operations_path(@project), method: :patch do |f| - = form_errors(@project) - .form-group - = f.fields_for :error_tracking_setting_attributes, setting do |form| - .form-check.form-group - = form.check_box :enabled, class: 'form-check-input' - = form.label :enabled, _('Active'), class: 'form-check-label' - .form-group - = form.label :api_url, _('Sentry API URL'), class: 'label-bold' - = form.url_field :api_url, class: 'form-control', placeholder: _('http://<sentry-host>/api/0/projects/{organization_slug}/{project_slug}/') - %p.form-text.text-muted - = _('Enter your Sentry API URL') - .form-group - = form.label :token, _('Auth Token'), class: 'label-bold' - = form.text_field :token, class: 'form-control' - %p.form-text.text-muted - = _('Find and manage Auth Tokens in your Sentry account settings page.') - - = f.submit _('Save changes'), class: 'btn btn-success' + .js-error-tracking-form{ data: { list_projects_endpoint: list_projects_project_error_tracking_index_path(@project, format: :json), + operations_settings_endpoint: project_settings_operations_path(@project), + project: error_tracking_setting_project_json, + api_host: setting.api_host, + enabled: setting.enabled.to_json, + token: setting.token } } diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index feeaf799f51..8ee1407d9d9 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -23,7 +23,7 @@ = link_to edit_project_tag_release_path(@project, @tag.name), class: 'btn btn-edit controls-item has-tooltip', title: s_('TagsPage|Edit release notes') do = icon("pencil") = link_to project_tree_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: s_('TagsPage|Browse files') do - = icon('files-o') + = sprite_icon('folder-open') = link_to project_commits_path(@project, @tag.name), class: 'btn controls-item has-tooltip', title: s_('TagsPage|Browse commits') do = icon('history') .btn-container.controls-item diff --git a/app/views/shared/_mobile_clone_panel.html.haml b/app/views/shared/_mobile_clone_panel.html.haml index 6e2527bd1a1..1e6b6f7c79b 100644 --- a/app/views/shared/_mobile_clone_panel.html.haml +++ b/app/views/shared/_mobile_clone_panel.html.haml @@ -13,3 +13,4 @@ - if http_enabled? %li = dropdown_item_with_description(http_copy_label, project.http_url_to_repo, href: project.http_url_to_repo, data: { clone_type: 'http' }) + = render_if_exists 'shared/mobile_kerberos_clone' diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml index 913c065e188..eb7808573b9 100644 --- a/app/views/shared/deploy_keys/_form.html.haml +++ b/app/views/shared/deploy_keys/_form.html.haml @@ -15,7 +15,7 @@ %p.light Paste a machine public key here. Read more about how to generate it = link_to 'here', help_page_path('ssh/README') - = form.text_area :key, class: 'form-control thin_area', rows: 5 + = form.text_area :key, class: 'form-control thin-area', rows: 5 - else = form.label :fingerprint, class: 'col-form-label col-sm-2' .col-sm-10 diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index 40b8374848e..e75f0a184ea 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -32,7 +32,7 @@ = milestone_progress_bar(milestone) = link_to pluralize(milestone.total_issues_count(current_user), 'Issue'), issues_path · - = link_to pluralize(milestone.merge_requests.size, 'Merge Request'), merge_requests_path + = link_to pluralize(milestone.merge_requests_visible_to_user(current_user).size, 'Merge Request'), merge_requests_path .float-lg-right.light #{milestone.percent_complete(current_user)}% complete .col-sm-2 .milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml index 55460acab8f..b877f66c71e 100644 --- a/app/views/shared/milestones/_tabs.html.haml +++ b/app/views/shared/milestones/_tabs.html.haml @@ -12,7 +12,7 @@ %li.nav-item = link_to '#tab-merge-requests', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do Merge Requests - %span.badge.badge-pill= milestone.merge_requests.size + %span.badge.badge-pill= milestone.merge_requests_visible_to_user(current_user).size - else %li.nav-item = link_to '#tab-merge-requests', class: 'nav-link active', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do @@ -21,11 +21,11 @@ %li.nav-item = link_to '#tab-participants', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do Participants - %span.badge.badge-pill= milestone.participants.count + %span.badge.badge-pill= milestone.issue_participants_visible_by_user(current_user).count %li.nav-item = link_to '#tab-labels', class: 'nav-link', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do Labels - %span.badge.badge-pill= milestone.labels.count + %span.badge.badge-pill= milestone.issue_labels_visible_by_user(current_user).count - issues = milestone.sorted_issues(current_user) - show_project_name = local_assigns.fetch(:show_project_name, false) diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index f1a87faa7ac..d2b1be29eb9 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -85,7 +85,8 @@ = sprite_icon('issues', size: 14, css_class: 'append-right-4') = number_with_delimiter(project.open_issues_count) - if pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project) + - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref) %span.icon-wrapper.pipeline-status - = render_project_pipeline_status(project.pipeline_status, tooltip_placement: 'top') + = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), type: 'commit', tooltip_placement: 'top', path: pipeline_path .updated-note %span Updated #{updated_tooltip} diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 337f39b2091..b2d88567e0e 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -23,6 +23,7 @@ - cronjob:prune_web_hook_logs - gcp_cluster:cluster_install_app +- gcp_cluster:cluster_patch_app - gcp_cluster:cluster_upgrade_app - gcp_cluster:cluster_provision - gcp_cluster:cluster_wait_for_app_installation @@ -47,6 +48,9 @@ - github_importer:github_import_stage_import_repository - hashed_storage:hashed_storage_migrator +- hashed_storage:hashed_storage_rollbacker +- hashed_storage:hashed_storage_project_migrate +- hashed_storage:hashed_storage_project_rollback - mail_scheduler:mail_scheduler_issue_due - mail_scheduler:mail_scheduler_notification_service @@ -126,7 +130,6 @@ - project_cache - project_destroy - project_export -- project_migrate_hashed_storage - project_service - propagate_service_template - reactive_caching diff --git a/app/workers/cluster_patch_app_worker.rb b/app/workers/cluster_patch_app_worker.rb new file mode 100644 index 00000000000..0549e81ed05 --- /dev/null +++ b/app/workers/cluster_patch_app_worker.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class ClusterPatchAppWorker + include ApplicationWorker + include ClusterQueue + include ClusterApplications + + def perform(app_name, app_id) + find_application(app_name, app_id) do |app| + Clusters::Applications::PatchService.new(app).execute + end + end +end diff --git a/app/workers/hashed_storage/base_worker.rb b/app/workers/hashed_storage/base_worker.rb new file mode 100644 index 00000000000..816e0504db6 --- /dev/null +++ b/app/workers/hashed_storage/base_worker.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module HashedStorage + class BaseWorker + include ExclusiveLeaseGuard + + LEASE_TIMEOUT = 30.seconds.to_i + LEASE_KEY_SEGMENT = 'project_migrate_hashed_storage_worker'.freeze + + protected + + def lease_key + # we share the same lease key for both migration and rollback so they don't run simultaneously + "#{LEASE_KEY_SEGMENT}:#{project_id}" + end + + def lease_timeout + LEASE_TIMEOUT + end + end +end diff --git a/app/workers/hashed_storage/project_migrate_worker.rb b/app/workers/hashed_storage/project_migrate_worker.rb new file mode 100644 index 00000000000..f00a459a097 --- /dev/null +++ b/app/workers/hashed_storage/project_migrate_worker.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module HashedStorage + class ProjectMigrateWorker < BaseWorker + include ApplicationWorker + + queue_namespace :hashed_storage + + attr_reader :project_id + + # rubocop: disable CodeReuse/ActiveRecord + def perform(project_id, old_disk_path = nil) + @project_id = project_id # we need to set this in order to create the lease_key + + try_obtain_lease do + project = Project.without_deleted.find_by(id: project_id) + break unless project + + old_disk_path ||= project.disk_path + + ::Projects::HashedStorage::MigrationService.new(project, old_disk_path, logger: logger).execute + end + end + # rubocop: enable CodeReuse/ActiveRecord + end +end diff --git a/app/workers/hashed_storage/project_rollback_worker.rb b/app/workers/hashed_storage/project_rollback_worker.rb new file mode 100644 index 00000000000..55e1d7ab23e --- /dev/null +++ b/app/workers/hashed_storage/project_rollback_worker.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module HashedStorage + class ProjectRollbackWorker < BaseWorker + include ApplicationWorker + + queue_namespace :hashed_storage + + attr_reader :project_id + + # rubocop: disable CodeReuse/ActiveRecord + def perform(project_id, old_disk_path = nil) + @project_id = project_id # we need to set this in order to create the lease_key + + try_obtain_lease do + project = Project.without_deleted.find_by(id: project_id) + break unless project + + old_disk_path ||= project.disk_path + + ::Projects::HashedStorage::RollbackService.new(project, old_disk_path, logger: logger).execute + end + end + # rubocop: enable CodeReuse/ActiveRecord + end +end diff --git a/app/workers/hashed_storage/rollbacker_worker.rb b/app/workers/hashed_storage/rollbacker_worker.rb new file mode 100644 index 00000000000..a4da8443787 --- /dev/null +++ b/app/workers/hashed_storage/rollbacker_worker.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module HashedStorage + class RollbackerWorker + include ApplicationWorker + + queue_namespace :hashed_storage + + # @param [Integer] start initial ID of the batch + # @param [Integer] finish last ID of the batch + def perform(start, finish) + migrator = Gitlab::HashedStorage::Migrator.new + migrator.bulk_rollback(start: start, finish: finish) + end + end +end diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb index c2fbfd2b3a5..0ddad43b8d5 100644 --- a/app/workers/pipeline_metrics_worker.rb +++ b/app/workers/pipeline_metrics_worker.rb @@ -30,6 +30,6 @@ class PipelineMetricsWorker # rubocop: enable CodeReuse/ActiveRecord def merge_requests(pipeline) - pipeline.merge_requests.map(&:id) + pipeline.merge_requests_as_head_pipeline.map(&:id) end end diff --git a/app/workers/project_migrate_hashed_storage_worker.rb b/app/workers/project_migrate_hashed_storage_worker.rb deleted file mode 100644 index 1c8f313e6e9..00000000000 --- a/app/workers/project_migrate_hashed_storage_worker.rb +++ /dev/null @@ -1,43 +0,0 @@ -# frozen_string_literal: true - -class ProjectMigrateHashedStorageWorker - include ApplicationWorker - - LEASE_TIMEOUT = 30.seconds.to_i - LEASE_KEY_SEGMENT = 'project_migrate_hashed_storage_worker'.freeze - - # rubocop: disable CodeReuse/ActiveRecord - def perform(project_id, old_disk_path = nil) - uuid = lease_for(project_id).try_obtain - - if uuid - project = Project.find_by(id: project_id) - return if project.nil? || project.pending_delete? - - old_disk_path ||= project.disk_path - - ::Projects::HashedStorage::MigrationService.new(project, old_disk_path, logger: logger).execute - else - return false - end - - ensure - cancel_lease_for(project_id, uuid) if uuid - end - # rubocop: enable CodeReuse/ActiveRecord - - def lease_for(project_id) - Gitlab::ExclusiveLease.new(lease_key(project_id), timeout: LEASE_TIMEOUT) - end - - private - - def lease_key(project_id) - # we share the same lease key for both migration and rollback so they don't run simultaneously - "#{LEASE_KEY_SEGMENT}:#{project_id}" - end - - def cancel_lease_for(project_id, uuid) - Gitlab::ExclusiveLease.cancel(lease_key(project_id), uuid) - end -end |