aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/proguard.flags5
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_ics_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_active_ics.9.png)bin462 -> 462 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_klp_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_active_klp.9.png)bin463 -> 463 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.pngbin0 -> 1014 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin0 -> 1031 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.pngbin506 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.pngbin657 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.pngbin1048 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.pngbin972 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.pngbin1082 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.pngbin1440 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.pngbin505 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.pngbin301 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.pngbin835 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_holo_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png)bin463 -> 463 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_holo_light.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png)bin474 -> 474 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off_holo_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png)bin578 -> 578 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_off_lxx_dark.9.pngbin0 -> 161 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_ics_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_ics.9.png)bin587 -> 587 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_klp_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_klp.9.png)bin639 -> 639 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_normal_on_lxx_dark.9.pngbin0 -> 162 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_ics_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_ics.9.png)bin553 -> 553 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_ics_light.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_light_pressed_ics.9.png)bin547 -> 547 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_klp_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_klp.9.png)bin537 -> 537 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_klp_light.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_light_pressed_klp.9.png)bin517 -> 517 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_off_ics_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_ics.9.png)bin668 -> 668 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_off_klp_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_klp.9.png)bin655 -> 655 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_off_lxx_dark.9.pngbin0 -> 160 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_on_ics_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_ics.9.png)bin707 -> 707 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_on_klp_dark.9.png (renamed from java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_klp.9.png)bin670 -> 670 bytes
-rw-r--r--java/res/drawable-hdpi/btn_keyboard_key_pressed_on_lxx_dark.9.pngbin0 -> 162 bytes
-rw-r--r--java/res/drawable-hdpi/btn_suggestion_pressed.9.pngbin1234 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/emoji_category_tab_selected_ics.9.pngbin0 -> 137 bytes
-rw-r--r--java/res/drawable-hdpi/emoji_category_tab_selected_klp.9.pngbin0 -> 134 bytes
-rw-r--r--java/res/drawable-hdpi/emoji_category_tab_unselected_holo_dark.9.png (renamed from java/res/drawable-hdpi/tab_unselected.9.png)bin150 -> 150 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_emoticons_activated_holo_dark.pngbin0 -> 1138 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_emoticons_normal_holo_dark.pngbin0 -> 990 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_nature_activated_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_nature_light_activated.png)bin1850 -> 1850 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_nature_normal_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_nature_light_normal.png)bin1800 -> 1800 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_objects_activated_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_objects_light_activated.png)bin1744 -> 1744 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_objects_normal_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_objects_light_normal.png)bin1581 -> 1581 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_people_activated_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_people_light_activated.png)bin1767 -> 1767 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_people_normal_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_people_light_normal.png)bin1820 -> 1820 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_places_activated_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_places_light_activated.png)bin1418 -> 1418 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_places_normal_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_places_light_normal.png)bin1341 -> 1341 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_recents_activated_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_recent_light_activated.png)bin1667 -> 1667 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_recents_normal_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_recent_light_normal.png)bin1703 -> 1703 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_symbols_activated_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png)bin1087 -> 1087 bytes
-rw-r--r--java/res/drawable-hdpi/ic_emoji_symbols_normal_holo_dark.png (renamed from java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png)bin1053 -> 1053 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin0 -> 557 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin0 -> 687 bytes
-rw-r--r--java/res/drawable-hdpi/keyboard_popup_panel_background_lxx_dark.9.pngbin0 -> 871 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_delete_lxx_dark.pngbin0 -> 14841 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_done_lxx_dark.pngbin0 -> 14700 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_go_lxx_dark.pngbin0 -> 14660 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_language_switch_lxx_dark.pngbin0 -> 14956 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.pngbin778 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_next_lxx_dark.pngbin0 -> 655 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_previous_lxx_dark.pngbin0 -> 654 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_return_lxx_dark.pngbin0 -> 649 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_search_lxx_dark.pngbin0 -> 14900 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_send_lxx_dark.pngbin0 -> 906 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_settings_lxx_dark.pngbin0 -> 14913 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_locked_lxx_dark.pngbin0 -> 810 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_shift_lxx_dark.pngbin0 -> 901 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_smiley_lxx_dark.pngbin0 -> 14888 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.pngbin322 -> 0 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.pngbin0 -> 303 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_lxx_dark.pngbin0 -> 14761 bytes
-rw-r--r--java/res/drawable-hdpi/sym_keyboard_voice_off_lxx_dark.pngbin0 -> 14896 bytes
-rw-r--r--java/res/drawable-hdpi/tab_selected.9.pngbin145 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_ics_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_active_ics.9.png)bin345 -> 345 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_klp_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_active_klp.9.png)bin355 -> 355 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.pngbin0 -> 655 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin0 -> 684 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.pngbin458 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.pngbin588 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.pngbin960 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.pngbin849 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.pngbin957 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.pngbin1293 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.pngbin454 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.pngbin258 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.pngbin717 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_holo_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png)bin355 -> 355 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_holo_light.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png)bin339 -> 339 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_off_holo_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png)bin428 -> 428 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_off_lxx_dark.9.pngbin0 -> 143 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on_ics_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_ics.9.png)bin411 -> 411 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on_klp_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_klp.9.png)bin453 -> 453 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_normal_on_lxx_dark.9.pngbin0 -> 138 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_ics_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_ics.9.png)bin394 -> 394 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_ics_light.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_light_pressed_ics.9.png)bin381 -> 381 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_klp_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_klp.9.png)bin380 -> 380 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_klp_light.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_light_pressed_klp.9.png)bin368 -> 368 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_off_ics_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_ics.9.png)bin505 -> 505 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_off_klp_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_klp.9.png)bin468 -> 468 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_off_lxx_dark.9.pngbin0 -> 127 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_on_ics_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_ics.9.png)bin489 -> 489 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_on_klp_dark.9.png (renamed from java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_klp.9.png)bin458 -> 458 bytes
-rw-r--r--java/res/drawable-mdpi/btn_keyboard_key_pressed_on_lxx_dark.9.pngbin0 -> 144 bytes
-rw-r--r--java/res/drawable-mdpi/btn_suggestion_pressed.9.pngbin11006 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/emoji_category_tab_selected_ics.9.pngbin0 -> 137 bytes
-rw-r--r--java/res/drawable-mdpi/emoji_category_tab_selected_klp.9.pngbin0 -> 132 bytes
-rw-r--r--java/res/drawable-mdpi/emoji_category_tab_unselected_holo_dark.9.png (renamed from java/res/drawable-mdpi/tab_unselected.9.png)bin138 -> 138 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_emoticons_activated_holo_dark.pngbin0 -> 873 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_emoticons_normal_holo_dark.pngbin0 -> 713 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_nature_activated_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_nature_light_activated.png)bin1213 -> 1213 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_nature_normal_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_nature_light_normal.png)bin1130 -> 1130 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_objects_activated_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_objects_light_activated.png)bin1193 -> 1193 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_objects_normal_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_objects_light_normal.png)bin1092 -> 1092 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_people_activated_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_people_light_activated.png)bin1170 -> 1170 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_people_normal_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_people_light_normal.png)bin1132 -> 1132 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_places_activated_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_places_light_activated.png)bin1032 -> 1032 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_places_normal_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_places_light_normal.png)bin963 -> 963 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_recents_activated_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_recent_light_activated.png)bin1105 -> 1105 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_recents_normal_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_recent_light_normal.png)bin1106 -> 1106 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_symbols_activated_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png)bin805 -> 805 bytes
-rw-r--r--java/res/drawable-mdpi/ic_emoji_symbols_normal_holo_dark.png (renamed from java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png)bin775 -> 775 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin0 -> 361 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin0 -> 398 bytes
-rw-r--r--java/res/drawable-mdpi/keyboard_popup_panel_background_lxx_dark.9.pngbin0 -> 589 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_delete_lxx_dark.pngbin0 -> 14721 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_done_lxx_dark.pngbin0 -> 14643 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_go_lxx_dark.pngbin0 -> 14618 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_language_switch_lxx_dark.pngbin0 -> 14786 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.pngbin590 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_next_lxx_dark.pngbin0 -> 552 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_previous_lxx_dark.pngbin0 -> 560 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_return_lxx_dark.pngbin0 -> 536 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_search_lxx_dark.pngbin0 -> 14704 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_send_lxx_dark.pngbin0 -> 713 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_settings_lxx_dark.pngbin0 -> 14781 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_locked_lxx_dark.pngbin0 -> 663 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_shift_lxx_dark.pngbin0 -> 708 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_smiley_lxx_dark.pngbin0 -> 14720 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.pngbin201 -> 0 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.pngbin0 -> 244 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_lxx_dark.pngbin0 -> 14690 bytes
-rw-r--r--java/res/drawable-mdpi/sym_keyboard_voice_off_lxx_dark.pngbin0 -> 14768 bytes
-rw-r--r--java/res/drawable-mdpi/tab_selected.9.pngbin140 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_ics_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_active_ics.9.png)bin601 -> 601 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_klp_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_active_klp.9.png)bin589 -> 589 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.pngbin0 -> 1364 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin0 -> 1441 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.pngbin571 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.pngbin727 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.pngbin1110 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.pngbin1007 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.pngbin1128 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.pngbin1486 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.pngbin548 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.pngbin359 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.pngbin860 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_holo_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png)bin589 -> 589 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_holo_light.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png)bin594 -> 594 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_off_holo_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png)bin732 -> 732 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_off_lxx_dark.9.pngbin0 -> 282 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_on_ics_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_ics.9.png)bin745 -> 745 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_on_klp_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_klp.9.png)bin787 -> 787 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_normal_on_lxx_dark.9.pngbin0 -> 295 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_ics_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_ics.9.png)bin737 -> 737 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_ics_light.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_ics.9.png)bin668 -> 668 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_klp_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_klp.9.png)bin657 -> 657 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_klp_light.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_klp.9.png)bin634 -> 634 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_ics_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_ics.9.png)bin953 -> 953 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_klp_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_klp.9.png)bin848 -> 848 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.pngbin0 -> 276 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_ics_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_ics.9.png)bin945 -> 945 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_klp_dark.9.png (renamed from java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_klp.9.png)bin867 -> 867 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.pngbin0 -> 295 bytes
-rw-r--r--java/res/drawable-xhdpi/btn_suggestion_pressed.9.pngbin1266 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/emoji_category_tab_selected_ics.9.pngbin0 -> 138 bytes
-rw-r--r--java/res/drawable-xhdpi/emoji_category_tab_selected_klp.9.pngbin0 -> 135 bytes
-rw-r--r--java/res/drawable-xhdpi/emoji_category_tab_unselected_holo_dark.9.png (renamed from java/res/drawable-xhdpi/tab_unselected.9.png)bin155 -> 155 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_emoticons_activated_holo_dark.pngbin0 -> 1317 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_emoticons_normal_holo_dark.pngbin0 -> 1213 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_nature_activated_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png)bin2437 -> 2437 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_nature_normal_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png)bin2371 -> 2371 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_objects_activated_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png)bin2319 -> 2319 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_objects_normal_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png)bin2074 -> 2074 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_people_activated_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_people_light_activated.png)bin2519 -> 2519 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_people_normal_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_people_light_normal.png)bin2526 -> 2526 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_places_activated_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_places_light_activated.png)bin1828 -> 1828 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_places_normal_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_places_light_normal.png)bin1667 -> 1667 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_recents_activated_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png)bin2459 -> 2459 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_recents_normal_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png)bin2346 -> 2346 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_symbols_activated_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png)bin1457 -> 1457 bytes
-rw-r--r--java/res/drawable-xhdpi/ic_emoji_symbols_normal_holo_dark.png (renamed from java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png)bin1267 -> 1267 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin0 -> 765 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin0 -> 835 bytes
-rw-r--r--java/res/drawable-xhdpi/keyboard_popup_panel_background_lxx_dark.9.pngbin0 -> 1246 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_delete_lxx_dark.pngbin0 -> 14911 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_done_lxx_dark.pngbin0 -> 14750 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_go_lxx_dark.pngbin0 -> 14718 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_language_switch_lxx_dark.pngbin0 -> 15109 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.pngbin942 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_next_lxx_dark.pngbin0 -> 708 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_previous_lxx_dark.pngbin0 -> 716 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_return_lxx_dark.pngbin0 -> 663 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_search_lxx_dark.pngbin0 -> 14966 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_send_lxx_dark.pngbin0 -> 1024 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_settings_lxx_dark.pngbin0 -> 15050 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_locked_lxx_dark.pngbin0 -> 985 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_shift_lxx_dark.pngbin0 -> 1156 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_smiley_lxx_dark.pngbin0 -> 14966 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.pngbin381 -> 0 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.pngbin0 -> 393 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_lxx_dark.pngbin0 -> 14878 bytes
-rw-r--r--java/res/drawable-xhdpi/sym_keyboard_voice_off_lxx_dark.pngbin0 -> 15029 bytes
-rw-r--r--java/res/drawable-xhdpi/tab_selected.9.pngbin148 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_ics_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_ics.9.png)bin1805 -> 1805 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_klp_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_klp.9.png)bin1718 -> 1718 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.pngbin0 -> 2477 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.pngbin0 -> 2635 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_holo_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png)bin1718 -> 1718 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_holo_light.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png)bin1787 -> 1787 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_holo_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png)bin1905 -> 1905 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.pngbin0 -> 171 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_ics_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_ics.9.png)bin2039 -> 2039 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_klp_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_klp.9.png)bin1998 -> 1998 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.pngbin0 -> 158 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_ics_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_ics.9.png)bin1863 -> 1863 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_ics_light.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_ics.9.png)bin1840 -> 1840 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_klp_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_klp.9.png)bin1861 -> 1861 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_klp_light.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_klp.9.png)bin1799 -> 1799 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_ics_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_ics.9.png)bin2196 -> 2196 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_klp_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_klp.9.png)bin2073 -> 2073 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.pngbin0 -> 165 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_ics_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_ics.9.png)bin2210 -> 2210 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_klp_dark.9.png (renamed from java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_klp.9.png)bin2091 -> 2091 bytes
-rw-r--r--java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.pngbin0 -> 173 bytes
-rw-r--r--java/res/drawable-xxhdpi/emoji_category_tab_selected_ics.9.pngbin0 -> 113 bytes
-rw-r--r--java/res/drawable-xxhdpi/emoji_category_tab_selected_klp.9.pngbin0 -> 110 bytes
-rw-r--r--java/res/drawable-xxhdpi/emoji_category_tab_unselected_holo_dark.9.png (renamed from java/res/drawable-xxhdpi/tab_unselected.9.png)bin1048 -> 1048 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_emoticons_activated_holo_dark.pngbin0 -> 1383 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_emoticons_normal_holo_dark.pngbin0 -> 1096 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_nature_activated_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png)bin3150 -> 3150 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_nature_normal_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png)bin2999 -> 2999 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_objects_activated_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png)bin2831 -> 2831 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_objects_normal_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png)bin2656 -> 2656 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_people_activated_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png)bin3118 -> 3118 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_people_normal_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png)bin3097 -> 3097 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_places_activated_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png)bin2256 -> 2256 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_places_normal_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png)bin2169 -> 2169 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_recents_activated_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png)bin3152 -> 3152 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_recents_normal_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png)bin2943 -> 2943 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_symbols_activated_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png)bin1939 -> 1939 bytes
-rw-r--r--java/res/drawable-xxhdpi/ic_emoji_symbols_normal_holo_dark.png (renamed from java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png)bin1784 -> 1784 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.pngbin0 -> 1187 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.pngbin0 -> 1358 bytes
-rw-r--r--java/res/drawable-xxhdpi/keyboard_popup_panel_background_lxx_dark.9.pngbin0 -> 2732 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_delete_lxx_dark.pngbin0 -> 15113 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_done_lxx_dark.pngbin0 -> 14819 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_go_lxx_dark.pngbin0 -> 14788 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_language_switch_lxx_dark.pngbin0 -> 15436 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.pngbin1566 -> 0 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_next_lxx_dark.pngbin0 -> 977 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_previous_lxx_dark.pngbin0 -> 987 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_return_lxx_dark.pngbin0 -> 840 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_search_lxx_dark.pngbin0 -> 15158 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_send_lxx_dark.pngbin0 -> 1442 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_settings_lxx_dark.pngbin0 -> 15329 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_locked_lxx_dark.pngbin0 -> 1359 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_shift_lxx_dark.pngbin0 -> 1563 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_smiley_lxx_dark.pngbin0 -> 15210 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.pngbin0 -> 609 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_lxx_dark.pngbin0 -> 15114 bytes
-rw-r--r--java/res/drawable-xxhdpi/sym_keyboard_voice_off_lxx_dark.pngbin0 -> 15261 bytes
-rw-r--r--java/res/drawable-xxhdpi/tab_selected.9.pngbin1030 -> 0 bytes
-rw-r--r--java/res/drawable/btn_keyboard_key_functional_ics.xml4
-rw-r--r--java/res/drawable/btn_keyboard_key_functional_klp.xml4
-rw-r--r--java/res/drawable/btn_keyboard_key_functional_lxx_dark.xml22
-rw-r--r--java/res/drawable/btn_keyboard_key_ics.xml24
-rw-r--r--java/res/drawable/btn_keyboard_key_klp.xml24
-rw-r--r--java/res/drawable/btn_keyboard_key_lxx_dark.xml42
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_ics.xml2
-rw-r--r--java/res/drawable/btn_keyboard_key_popup_klp.xml2
-rw-r--r--java/res/drawable/btn_keyboard_spacebar_ics.xml4
-rw-r--r--java/res/drawable/btn_keyboard_spacebar_klp.xml4
-rw-r--r--java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml21
-rw-r--r--java/res/drawable/btn_suggestion_lxx_dark.xml (renamed from java/res/drawable/transparent.xml)15
-rw-r--r--java/res/drawable/ic_emoji_emoticons_holo_dark.xml32
-rw-r--r--java/res/drawable/ic_emoji_nature_holo_dark.xml (renamed from java/res/color/emoji_tab_label_color_holo.xml)8
-rw-r--r--java/res/drawable/ic_emoji_objects_holo_dark.xml (renamed from java/res/drawable/ic_emoji_nature_light.xml)9
-rw-r--r--java/res/drawable/ic_emoji_people_holo_dark.xml (renamed from java/res/drawable/ic_emoji_objects_light.xml)8
-rw-r--r--java/res/drawable/ic_emoji_places_holo_dark.xml (renamed from java/res/drawable/ic_emoji_people_light.xml)8
-rw-r--r--java/res/drawable/ic_emoji_places_light.xml32
-rw-r--r--java/res/drawable/ic_emoji_recent_light.xml32
-rw-r--r--java/res/drawable/ic_emoji_recents_holo_dark.xml32
-rw-r--r--java/res/drawable/ic_emoji_symbols_holo_dark.xml32
-rw-r--r--java/res/drawable/ic_emoji_symbols_light.xml32
-rw-r--r--java/res/drawable/keyboard_key_feedback_lxx_dark.xml36
-rw-r--r--java/res/layout/emoji_keyboard_page.xml2
-rw-r--r--java/res/layout/emoji_keyboard_tab_icon.xml4
-rw-r--r--java/res/layout/emoji_palettes_view.xml54
-rw-r--r--java/res/layout/input_view.xml2
-rw-r--r--java/res/layout/research_feedback_activity.xml31
-rw-r--r--java/res/layout/research_feedback_fragment_layout.xml115
-rw-r--r--java/res/layout/research_feedback_layout.xml50
-rw-r--r--java/res/layout/suggestion_divider.xml10
-rw-r--r--java/res/layout/suggestions_strip.xml32
-rw-r--r--java/res/raw/main_en.dictbin1070464 -> 1070470 bytes
-rw-r--r--java/res/raw/main_es.dictbin1138908 -> 1376670 bytes
-rw-r--r--java/res/raw/main_fr.dictbin1329188 -> 1328940 bytes
-rw-r--r--java/res/values-af/strings-action-keys.xml2
-rw-r--r--java/res/values-af/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-af/strings.xml6
-rw-r--r--java/res/values-am/strings-action-keys.xml2
-rw-r--r--java/res/values-am/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-am/strings.xml6
-rw-r--r--java/res/values-ar/strings-action-keys.xml2
-rw-r--r--java/res/values-ar/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ar/strings.xml6
-rw-r--r--java/res/values-az-rAZ/strings-action-keys.xml2
-rw-r--r--java/res/values-az-rAZ/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-az-rAZ/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-az-rAZ/strings.xml6
-rw-r--r--java/res/values-bg/strings-action-keys.xml2
-rw-r--r--java/res/values-bg/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-bg/strings.xml6
-rw-r--r--java/res/values-ca/strings-action-keys.xml2
-rw-r--r--java/res/values-ca/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ca/strings.xml6
-rw-r--r--java/res/values-cs/strings-action-keys.xml2
-rw-r--r--java/res/values-cs/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-cs/strings.xml6
-rw-r--r--java/res/values-da/strings-action-keys.xml2
-rw-r--r--java/res/values-da/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-da/strings.xml6
-rw-r--r--java/res/values-de/strings-action-keys.xml2
-rw-r--r--java/res/values-de/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-de/strings.xml6
-rw-r--r--java/res/values-el/strings-action-keys.xml2
-rw-r--r--java/res/values-el/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-el/strings.xml6
-rw-r--r--java/res/values-en-rGB/strings-action-keys.xml2
-rw-r--r--java/res/values-en-rGB/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-en-rGB/strings.xml6
-rw-r--r--java/res/values-en-rIN/strings-action-keys.xml2
-rw-r--r--java/res/values-en-rIN/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-en-rIN/strings.xml6
-rw-r--r--java/res/values-es-rUS/strings-action-keys.xml2
-rw-r--r--java/res/values-es-rUS/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-es-rUS/strings.xml6
-rw-r--r--java/res/values-es/strings-action-keys.xml2
-rw-r--r--java/res/values-es/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-es/strings.xml6
-rw-r--r--java/res/values-et-rEE/strings-action-keys.xml2
-rw-r--r--java/res/values-et-rEE/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-et-rEE/strings.xml6
-rw-r--r--java/res/values-fa/strings-action-keys.xml2
-rw-r--r--java/res/values-fa/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-fa/strings.xml6
-rw-r--r--java/res/values-fi/strings-action-keys.xml2
-rw-r--r--java/res/values-fi/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-fi/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-fi/strings.xml6
-rw-r--r--java/res/values-fr-rCA/strings-action-keys.xml2
-rw-r--r--java/res/values-fr-rCA/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-fr-rCA/strings.xml6
-rw-r--r--java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml2
-rw-r--r--java/res/values-fr/strings-action-keys.xml2
-rw-r--r--java/res/values-fr/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-fr/strings.xml6
-rw-r--r--java/res/values-hi/strings-action-keys.xml2
-rw-r--r--java/res/values-hi/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-hi/strings.xml6
-rw-r--r--java/res/values-hr/strings-action-keys.xml2
-rw-r--r--java/res/values-hr/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-hr/strings.xml6
-rw-r--r--java/res/values-hu/strings-action-keys.xml2
-rw-r--r--java/res/values-hu/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-hu/strings.xml6
-rw-r--r--java/res/values-hy-rAM/strings-action-keys.xml2
-rw-r--r--java/res/values-hy-rAM/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-hy-rAM/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-hy-rAM/strings.xml6
-rw-r--r--java/res/values-in/strings-action-keys.xml2
-rw-r--r--java/res/values-in/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-in/strings.xml6
-rw-r--r--java/res/values-is/strings.xml4
-rw-r--r--java/res/values-it/strings-action-keys.xml2
-rw-r--r--java/res/values-it/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-it/strings.xml6
-rw-r--r--java/res/values-iw/strings-action-keys.xml2
-rw-r--r--java/res/values-iw/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-iw/strings.xml6
-rw-r--r--java/res/values-ja/strings-action-keys.xml2
-rw-r--r--java/res/values-ja/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ja/strings.xml6
-rw-r--r--java/res/values-ka-rGE/strings-action-keys.xml2
-rw-r--r--java/res/values-ka-rGE/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-ka-rGE/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ka-rGE/strings.xml6
-rw-r--r--java/res/values-kk/strings-talkback-descriptions.xml3
-rw-r--r--java/res/values-kk/strings.xml4
-rw-r--r--java/res/values-km-rKH/strings-action-keys.xml2
-rw-r--r--java/res/values-km-rKH/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-km-rKH/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-km-rKH/strings.xml24
-rw-r--r--java/res/values-ko/strings-action-keys.xml2
-rw-r--r--java/res/values-ko/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ko/strings.xml6
-rw-r--r--java/res/values-ky/strings.xml3
-rw-r--r--java/res/values-land/config.xml2
-rw-r--r--java/res/values-lo-rLA/strings-action-keys.xml2
-rw-r--r--java/res/values-lo-rLA/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-lo-rLA/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-lo-rLA/strings.xml6
-rw-r--r--java/res/values-lt/strings-action-keys.xml2
-rw-r--r--java/res/values-lt/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-lt/strings.xml6
-rw-r--r--java/res/values-lv/strings-action-keys.xml2
-rw-r--r--java/res/values-lv/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-lv/strings.xml6
-rw-r--r--java/res/values-mk/strings.xml4
-rw-r--r--java/res/values-mn-rMN/strings-action-keys.xml2
-rw-r--r--java/res/values-mn-rMN/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-mn-rMN/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-mn-rMN/strings.xml6
-rw-r--r--java/res/values-ms-rMY/strings-action-keys.xml2
-rw-r--r--java/res/values-ms-rMY/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-ms-rMY/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ms-rMY/strings.xml6
-rw-r--r--java/res/values-nb/strings-action-keys.xml2
-rw-r--r--java/res/values-nb/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-nb/strings.xml6
-rw-r--r--java/res/values-ne-rNP/strings-action-keys.xml2
-rw-r--r--java/res/values-ne-rNP/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-ne-rNP/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ne-rNP/strings.xml6
-rw-r--r--java/res/values-nl/strings-action-keys.xml2
-rw-r--r--java/res/values-nl/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-nl/strings.xml6
-rw-r--r--java/res/values-pl/strings-action-keys.xml2
-rw-r--r--java/res/values-pl/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-pl/strings.xml6
-rw-r--r--java/res/values-pt-rPT/strings-action-keys.xml2
-rw-r--r--java/res/values-pt-rPT/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-pt-rPT/strings.xml6
-rw-r--r--java/res/values-pt/strings-action-keys.xml2
-rw-r--r--java/res/values-pt/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-pt/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-pt/strings.xml6
-rw-r--r--java/res/values-rm/strings.xml4
-rw-r--r--java/res/values-ro/strings-action-keys.xml2
-rw-r--r--java/res/values-ro/strings-emoji-descriptions.xml851
-rw-r--r--java/res/values-ro/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ro/strings.xml6
-rw-r--r--java/res/values-ru/strings-action-keys.xml2
-rw-r--r--java/res/values-ru/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-ru/strings.xml6
-rw-r--r--java/res/values-sk/strings-action-keys.xml2
-rw-r--r--java/res/values-sk/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-sk/strings.xml6
-rw-r--r--java/res/values-sl/strings-action-keys.xml2
-rw-r--r--java/res/values-sl/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-sl/strings.xml6
-rw-r--r--java/res/values-sr/strings-action-keys.xml2
-rw-r--r--java/res/values-sr/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-sr/strings.xml6
-rw-r--r--java/res/values-sv/strings-action-keys.xml2
-rw-r--r--java/res/values-sv/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-sv/strings.xml6
-rw-r--r--java/res/values-sw/strings-action-keys.xml2
-rw-r--r--java/res/values-sw/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-sw/strings.xml6
-rw-r--r--java/res/values-sw600dp-land/config.xml4
-rw-r--r--java/res/values-sw600dp/config.xml5
-rw-r--r--java/res/values-sw768dp-land/config.xml4
-rw-r--r--java/res/values-sw768dp/config.xml5
-rw-r--r--java/res/values-th/strings-action-keys.xml2
-rw-r--r--java/res/values-th/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-th/strings.xml6
-rw-r--r--java/res/values-tl/strings-action-keys.xml2
-rw-r--r--java/res/values-tl/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-tl/strings.xml6
-rw-r--r--java/res/values-tr/strings-action-keys.xml2
-rw-r--r--java/res/values-tr/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-tr/strings.xml6
-rw-r--r--java/res/values-uk/strings-action-keys.xml2
-rw-r--r--java/res/values-uk/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-uk/strings.xml6
-rw-r--r--java/res/values-v20/platform-theme.xml4
-rw-r--r--java/res/values-vi/strings-action-keys.xml2
-rw-r--r--java/res/values-vi/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-vi/strings.xml6
-rw-r--r--java/res/values-zh-rCN/strings-action-keys.xml2
-rw-r--r--java/res/values-zh-rCN/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-zh-rCN/strings.xml6
-rw-r--r--java/res/values-zh-rHK/strings-action-keys.xml2
-rw-r--r--java/res/values-zh-rHK/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-zh-rHK/strings.xml6
-rw-r--r--java/res/values-zh-rTW/strings-action-keys.xml2
-rw-r--r--java/res/values-zh-rTW/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-zh-rTW/strings.xml6
-rw-r--r--java/res/values-zu/strings-action-keys.xml2
-rw-r--r--java/res/values-zu/strings-talkback-descriptions.xml29
-rw-r--r--java/res/values-zu/strings.xml6
-rw-r--r--java/res/values/attrs.xml45
-rw-r--r--java/res/values/colors.xml23
-rw-r--r--java/res/values/config-common.xml6
-rw-r--r--java/res/values/config.xml3
-rw-r--r--java/res/values/donottranslate-config-spacing-and-punctuations.xml2
-rw-r--r--java/res/values/donottranslate.xml13
-rw-r--r--java/res/values/keyboard-icons-holo.xml3
-rw-r--r--java/res/values/keyboard-icons-lxx-dark.xml47
-rw-r--r--java/res/values/keyboard-themes.xml34
-rw-r--r--java/res/values/research_strings.xml41
-rw-r--r--java/res/values/strings-action-keys.xml2
-rw-r--r--java/res/values/strings-emoji-descriptions.xml1671
-rw-r--r--java/res/values/strings-letter-descriptions.xml384
-rw-r--r--java/res/values/strings-production.xml (renamed from java/res/values/urls.xml)6
-rw-r--r--java/res/values/strings-talkback-descriptions.xml38
-rw-r--r--java/res/values/strings.xml83
-rw-r--r--java/res/values/themes-common.xml19
-rw-r--r--java/res/values/themes-ics.xml33
-rw-r--r--java/res/values/themes-klp.xml33
-rw-r--r--java/res/values/themes-lxx-dark.xml145
-rw-r--r--java/res/xml-sw600dp/key_comma.xml (renamed from java/res/xml-sw600dp/key_shortcut.xml)36
-rw-r--r--java/res/xml-sw600dp/key_period.xml (renamed from java/res/xml-sw600dp/keys_comma_period.xml)11
-rw-r--r--java/res/xml-sw600dp/key_settings.xml (renamed from java/res/layout/emoji_keyboard_tab_label.xml)24
-rw-r--r--java/res/xml-sw600dp/key_styles_common.xml8
-rw-r--r--java/res/xml-sw600dp/key_styles_enter.xml61
-rw-r--r--java/res/xml-sw600dp/row_dvorak4.xml16
-rw-r--r--java/res/xml-sw600dp/row_pcqwerty5.xml2
-rw-r--r--java/res/xml-sw600dp/row_qwerty4.xml11
-rw-r--r--java/res/xml-sw600dp/rows_marathi.xml54
-rw-r--r--java/res/xml-v16/keystyle_devanagari_sign_anusvara.xml9
-rw-r--r--java/res/xml-v16/keystyle_devanagari_sign_virama.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_e.xml14
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_o.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml8
-rw-r--r--java/res/xml-v16/keystyle_devanagari_vowel_sign_vocalic_r.xml10
-rw-r--r--java/res/xml/kbd_marathi.xml (renamed from java/res/xml/keys_comma_period_symbols.xml)14
-rw-r--r--java/res/xml/key_f1.xml23
-rw-r--r--java/res/xml/key_styles_common.xml13
-rw-r--r--java/res/xml/key_styles_enter.xml61
-rw-r--r--java/res/xml/key_styles_less_greater.xml (renamed from java/res/xml/keys_less_greater.xml)14
-rw-r--r--java/res/xml/key_styles_number.xml3
-rw-r--r--java/res/xml/key_styles_settings.xml (renamed from java/res/xml/key_styles_f1.xml)6
-rw-r--r--java/res/xml/keyboard_layout_set_marathi.xml42
-rw-r--r--java/res/xml/keystyle_devanagari_sign_anusvara.xml10
-rw-r--r--java/res/xml/keystyle_devanagari_sign_virama.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_aa.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_ai.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_au.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml15
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_e.xml10
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_i.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_ii.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_o.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_u.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_uu.xml8
-rw-r--r--java/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml11
-rw-r--r--java/res/xml/method.xml19
-rw-r--r--java/res/xml/prefs.xml12
-rw-r--r--java/res/xml/prefs_for_debug.xml27
-rw-r--r--java/res/xml/row_dvorak4.xml3
-rw-r--r--java/res/xml/row_pcqwerty5.xml7
-rw-r--r--java/res/xml/row_symbols4.xml12
-rw-r--r--java/res/xml/row_symbols_shift4.xml15
-rw-r--r--java/res/xml/rowkeys_marathi1.xml123
-rw-r--r--java/res/xml/rowkeys_marathi2.xml100
-rw-r--r--java/res/xml/rowkeys_marathi3.xml83
-rw-r--r--java/res/xml/rows_marathi.xml49
-rw-r--r--java/res/xml/rows_number_normal.xml10
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java67
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java4
-rw-r--r--java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java454
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java193
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java333
-rw-r--r--java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java (renamed from java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java)35
-rw-r--r--java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java303
-rw-r--r--java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java114
-rw-r--r--java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java37
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java5
-rw-r--r--java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java4
-rw-r--r--java/src/com/android/inputmethod/compat/ViewCompatUtils.java21
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/ActionBatch.java15
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java6
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java18
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java13
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java43
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java5
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/MetadataParser.java6
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java10
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/WordListMetadata.java13
-rw-r--r--java/src/com/android/inputmethod/event/CombinerChain.java50
-rw-r--r--java/src/com/android/inputmethod/event/MyanmarReordering.java258
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java974
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java88
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java39
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java47
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardTheme.java143
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java124
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java206
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java99
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java41
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java (renamed from java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java)14
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java353
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java (renamed from java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java)26
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java (renamed from java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java)24
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java (renamed from java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java)46
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java149
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java560
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java7
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java27
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java25
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java7
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java567
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeysCache.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java4
-rw-r--r--java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java55
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java234
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java22
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java5
-rw-r--r--java/src/com/android/inputmethod/latin/Constants.java27
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java103
-rw-r--r--java/src/com/android/inputmethod/latin/Dictionary.java44
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryCollection.java41
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java (renamed from java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java)412
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java3
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java200
-rw-r--r--java/src/com/android/inputmethod/latin/InputAttributes.java37
-rw-r--r--java/src/com/android/inputmethod/latin/InputView.java20
-rw-r--r--java/src/com/android/inputmethod/latin/LastComposedWord.java8
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java299
-rw-r--r--java/src/com/android/inputmethod/latin/LatinImeLogger.java74
-rw-r--r--java/src/com/android/inputmethod/latin/PrevWordsInfo.java62
-rw-r--r--java/src/com/android/inputmethod/latin/PunctuationSuggestions.java4
-rw-r--r--java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java32
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputConnection.java107
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodManager.java5
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java12
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java75
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java56
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java101
-rw-r--r--java/src/com/android/inputmethod/latin/WordComposer.java110
-rw-r--r--java/src/com/android/inputmethod/latin/WordListInfo.java4
-rw-r--r--java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java3
-rw-r--r--java/src/com/android/inputmethod/latin/define/ProductionFlag.java10
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java402
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java11
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/WordProperty.java9
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/AccountUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java59
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java28
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java1
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java37
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java19
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java9
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java29
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java52
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java9
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java88
-rw-r--r--java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java7
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java13
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsFragment.java58
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java58
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java7
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java6
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java6
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java3
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java10
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java76
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java52
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java6
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java10
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java185
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java13
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java13
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java30
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java40
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java32
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java63
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java6
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java4
-rw-r--r--java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java3
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java9
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java43
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CollectionUtils.java76
-rw-r--r--java/src/com/android/inputmethod/latin/utils/CsvUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilter.java58
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatches.java129
-rw-r--r--java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java59
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java36
-rw-r--r--java/src/com/android/inputmethod/latin/utils/FragmentUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java13
-rw-r--r--java/src/com/android/inputmethod/latin/utils/JsonUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java67
-rw-r--r--java/src/com/android/inputmethod/latin/utils/LatinImeLoggerUtils.java77
-rw-r--r--java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/LocaleUtils.java2
-rw-r--r--java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java122
-rw-r--r--java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java34
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ResourceUtils.java7
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StatsUtils.java29
-rw-r--r--java/src/com/android/inputmethod/latin/utils/StringUtils.java30
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java17
-rw-r--r--java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java3
-rw-r--r--java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java4
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java293
-rw-r--r--java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java137
-rw-r--r--java/src/com/android/inputmethod/research/BootBroadcastReceiver.java34
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackActivity.java38
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackFragment.java131
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackLayout.java62
-rw-r--r--java/src/com/android/inputmethod/research/FeedbackLog.java32
-rw-r--r--java/src/com/android/inputmethod/research/FixedLogBuffer.java174
-rw-r--r--java/src/com/android/inputmethod/research/JsonUtils.java162
-rw-r--r--java/src/com/android/inputmethod/research/LogBuffer.java73
-rw-r--r--java/src/com/android/inputmethod/research/LogStatement.java225
-rw-r--r--java/src/com/android/inputmethod/research/LogUnit.java496
-rw-r--r--java/src/com/android/inputmethod/research/LoggingUtils.java38
-rw-r--r--java/src/com/android/inputmethod/research/MainLogBuffer.java287
-rw-r--r--java/src/com/android/inputmethod/research/MotionEventReader.java326
-rw-r--r--java/src/com/android/inputmethod/research/Replayer.java150
-rw-r--r--java/src/com/android/inputmethod/research/ReplayerService.java65
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLog.java298
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogDirectory.java113
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java1885
-rw-r--r--java/src/com/android/inputmethod/research/ResearchSettings.java72
-rw-r--r--java/src/com/android/inputmethod/research/Statistics.java279
-rw-r--r--java/src/com/android/inputmethod/research/Uploader.java171
-rw-r--r--java/src/com/android/inputmethod/research/UploaderService.java88
-rw-r--r--java/src/com/android/inputmethod/research/ui/SplashScreen.java111
754 files changed, 20487 insertions, 11351 deletions
diff --git a/java/proguard.flags b/java/proguard.flags
index f7b7f2898..35b3ac3d3 100644
--- a/java/proguard.flags
+++ b/java/proguard.flags
@@ -17,7 +17,8 @@
# Keep classes that are used as a parameter type of methods that are also marked as keep
# to preserve changing those methods' signature.
--keep class com.android.inputmethod.latin.utils.LanguageModelParam
-keep class com.android.inputmethod.latin.AssetFileAddress
--keep class com.android.inputmethod.latin.makedict.ProbabilityInfo
-keep class com.android.inputmethod.latin.Dictionary
+-keep class com.android.inputmethod.latin.PrevWordsInfo
+-keep class com.android.inputmethod.latin.makedict.ProbabilityInfo
+-keep class com.android.inputmethod.latin.utils.LanguageModelParam
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_ics.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_ics_dark.9.png
index 9aa8db60e..9aa8db60e 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_ics.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_klp.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_klp_dark.9.png
index fa2cb8542..fa2cb8542 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_active_klp.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png
new file mode 100644
index 000000000..82e850c6b
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..e2b9e3d9c
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
deleted file mode 100644
index bc130cab6..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
deleted file mode 100644
index 43099899c..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
deleted file mode 100644
index 2d1acf22f..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
deleted file mode 100644
index af5ea6bd2..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
deleted file mode 100644
index 3e25a9817..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
deleted file mode 100644
index fc7ba2aeb..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
deleted file mode 100644
index 005c4e498..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
deleted file mode 100644
index 9a07acd91..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_popup_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
deleted file mode 100644
index be420a7af..000000000
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_holo_dark.9.png
index fa2cb8542..fa2cb8542 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_holo_light.9.png
index 6da273b09..6da273b09 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_holo_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_holo_dark.9.png
index b1af23b6c..b1af23b6c 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_off_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
new file mode 100644
index 000000000..2e6489cf5
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_ics.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_ics_dark.9.png
index 9f4587b4a..9f4587b4a 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_ics.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_klp.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_klp_dark.9.png
index 814e40235..814e40235 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_normal_on_klp.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_normal_on_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
new file mode 100644
index 000000000..0b1482281
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_ics.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_ics_dark.9.png
index 7ec33dd20..7ec33dd20 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_ics.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_ics.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_ics_light.9.png
index 5612c51a1..5612c51a1 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_ics.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_ics_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_klp.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_klp_dark.9.png
index 90abe3940..90abe3940 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_klp.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_klp.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_klp_light.9.png
index 6768241a7..6768241a7 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_light_pressed_klp.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_klp_light.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_ics.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
index 655bc01b1..655bc01b1 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_ics.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_klp.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
index 48eeb3f54..48eeb3f54 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_off_klp.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
new file mode 100644
index 000000000..4bf38fc35
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_ics.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
index 138e915d9..138e915d9 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_ics.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_klp.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
index 71e0683cd..71e0683cd 100644
--- a/java/res/drawable-hdpi/btn_keyboard_key_dark_pressed_on_klp.9.png
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
new file mode 100644
index 000000000..ea12c7776
--- /dev/null
+++ b/java/res/drawable-hdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/btn_suggestion_pressed.9.png b/java/res/drawable-hdpi/btn_suggestion_pressed.9.png
deleted file mode 100644
index 7acceaee7..000000000
--- a/java/res/drawable-hdpi/btn_suggestion_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/emoji_category_tab_selected_ics.9.png b/java/res/drawable-hdpi/emoji_category_tab_selected_ics.9.png
new file mode 100644
index 000000000..9138cef9c
--- /dev/null
+++ b/java/res/drawable-hdpi/emoji_category_tab_selected_ics.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/emoji_category_tab_selected_klp.9.png b/java/res/drawable-hdpi/emoji_category_tab_selected_klp.9.png
new file mode 100644
index 000000000..345d05e9d
--- /dev/null
+++ b/java/res/drawable-hdpi/emoji_category_tab_selected_klp.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/tab_unselected.9.png b/java/res/drawable-hdpi/emoji_category_tab_unselected_holo_dark.9.png
index bbcfb2c64..bbcfb2c64 100644
--- a/java/res/drawable-hdpi/tab_unselected.9.png
+++ b/java/res/drawable-hdpi/emoji_category_tab_unselected_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_emoticons_activated_holo_dark.png b/java/res/drawable-hdpi/ic_emoji_emoticons_activated_holo_dark.png
new file mode 100644
index 000000000..1c937c9ef
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_emoticons_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_emoticons_normal_holo_dark.png b/java/res/drawable-hdpi/ic_emoji_emoticons_normal_holo_dark.png
new file mode 100644
index 000000000..3508d242a
--- /dev/null
+++ b/java/res/drawable-hdpi/ic_emoji_emoticons_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-hdpi/ic_emoji_nature_activated_holo_dark.png
index 5525df2f7..5525df2f7 100644
--- a/java/res/drawable-hdpi/ic_emoji_nature_light_activated.png
+++ b/java/res/drawable-hdpi/ic_emoji_nature_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-hdpi/ic_emoji_nature_normal_holo_dark.png
index 34e16b9de..34e16b9de 100644
--- a/java/res/drawable-hdpi/ic_emoji_nature_light_normal.png
+++ b/java/res/drawable-hdpi/ic_emoji_nature_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-hdpi/ic_emoji_objects_activated_holo_dark.png
index c3c7ec1b8..c3c7ec1b8 100644
--- a/java/res/drawable-hdpi/ic_emoji_objects_light_activated.png
+++ b/java/res/drawable-hdpi/ic_emoji_objects_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-hdpi/ic_emoji_objects_normal_holo_dark.png
index f012d7707..f012d7707 100644
--- a/java/res/drawable-hdpi/ic_emoji_objects_light_normal.png
+++ b/java/res/drawable-hdpi/ic_emoji_objects_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_people_light_activated.png b/java/res/drawable-hdpi/ic_emoji_people_activated_holo_dark.png
index cfacbc2e7..cfacbc2e7 100644
--- a/java/res/drawable-hdpi/ic_emoji_people_light_activated.png
+++ b/java/res/drawable-hdpi/ic_emoji_people_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_people_light_normal.png b/java/res/drawable-hdpi/ic_emoji_people_normal_holo_dark.png
index c54dbc1f5..c54dbc1f5 100644
--- a/java/res/drawable-hdpi/ic_emoji_people_light_normal.png
+++ b/java/res/drawable-hdpi/ic_emoji_people_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_places_light_activated.png b/java/res/drawable-hdpi/ic_emoji_places_activated_holo_dark.png
index 959dfdfd5..959dfdfd5 100644
--- a/java/res/drawable-hdpi/ic_emoji_places_light_activated.png
+++ b/java/res/drawable-hdpi/ic_emoji_places_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_places_light_normal.png b/java/res/drawable-hdpi/ic_emoji_places_normal_holo_dark.png
index fc0d9711d..fc0d9711d 100644
--- a/java/res/drawable-hdpi/ic_emoji_places_light_normal.png
+++ b/java/res/drawable-hdpi/ic_emoji_places_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-hdpi/ic_emoji_recents_activated_holo_dark.png
index de570a185..de570a185 100644
--- a/java/res/drawable-hdpi/ic_emoji_recent_light_activated.png
+++ b/java/res/drawable-hdpi/ic_emoji_recents_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-hdpi/ic_emoji_recents_normal_holo_dark.png
index b2562088d..b2562088d 100644
--- a/java/res/drawable-hdpi/ic_emoji_recent_light_normal.png
+++ b/java/res/drawable-hdpi/ic_emoji_recents_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-hdpi/ic_emoji_symbols_activated_holo_dark.png
index af1fd27ec..af1fd27ec 100644
--- a/java/res/drawable-hdpi/ic_emoji_symbols_light_activated.png
+++ b/java/res/drawable-hdpi/ic_emoji_symbols_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-hdpi/ic_emoji_symbols_normal_holo_dark.png
index 02b84d51b..02b84d51b 100644
--- a/java/res/drawable-hdpi/ic_emoji_symbols_light_normal.png
+++ b/java/res/drawable-hdpi/ic_emoji_symbols_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png
new file mode 100644
index 000000000..9d6514bdd
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
new file mode 100644
index 000000000..8ad54f69d
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/keyboard_popup_panel_background_lxx_dark.9.png b/java/res/drawable-hdpi/keyboard_popup_panel_background_lxx_dark.9.png
new file mode 100644
index 000000000..f9dd3b8b1
--- /dev/null
+++ b/java/res/drawable-hdpi/keyboard_popup_panel_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_delete_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_delete_lxx_dark.png
new file mode 100644
index 000000000..5f5eb3fe7
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_delete_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_done_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_done_lxx_dark.png
new file mode 100644
index 000000000..f81130d1a
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_done_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_go_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_go_lxx_dark.png
new file mode 100644
index 000000000..516a7f1c7
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_go_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_language_switch_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_language_switch_lxx_dark.png
new file mode 100644
index 000000000..edf9a20de
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_language_switch_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png
deleted file mode 100644
index 3c5469403..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_mic_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_next_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_next_lxx_dark.png
new file mode 100644
index 000000000..8a88a90d7
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_next_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_previous_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_previous_lxx_dark.png
new file mode 100644
index 000000000..ee804abce
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_previous_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_return_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_return_lxx_dark.png
new file mode 100644
index 000000000..6ab33a76d
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_return_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_search_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_search_lxx_dark.png
new file mode 100644
index 000000000..de117d35b
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_search_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_send_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_send_lxx_dark.png
new file mode 100644
index 000000000..52feef04c
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_send_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_settings_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_settings_lxx_dark.png
new file mode 100644
index 000000000..f2613023f
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_settings_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_locked_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_locked_lxx_dark.png
new file mode 100644
index 000000000..ef6b19efe
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_locked_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_shift_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_shift_lxx_dark.png
new file mode 100644
index 000000000..cb03e55a8
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_shift_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_smiley_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_smiley_lxx_dark.png
new file mode 100644
index 000000000..3999d1e2d
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_smiley_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.png b/java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.png
deleted file mode 100644
index 34a1ebde2..000000000
--- a/java/res/drawable-hdpi/sym_keyboard_space_led_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.png
new file mode 100644
index 000000000..f344deeec
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_spacebar_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_lxx_dark.png
new file mode 100644
index 000000000..6b68c8af5
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/sym_keyboard_voice_off_lxx_dark.png b/java/res/drawable-hdpi/sym_keyboard_voice_off_lxx_dark.png
new file mode 100644
index 000000000..e67697b3f
--- /dev/null
+++ b/java/res/drawable-hdpi/sym_keyboard_voice_off_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-hdpi/tab_selected.9.png b/java/res/drawable-hdpi/tab_selected.9.png
deleted file mode 100644
index 84e63df17..000000000
--- a/java/res/drawable-hdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_ics.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_ics_dark.9.png
index e810c7789..e810c7789 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_ics.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_klp.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_klp_dark.9.png
index 8e9a34957..8e9a34957 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_active_klp.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png
new file mode 100644
index 000000000..281b5d3bc
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..eb1564353
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
deleted file mode 100644
index 49329f094..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
deleted file mode 100644
index 46e9db092..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
deleted file mode 100644
index ee60e4864..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
deleted file mode 100644
index c6876f76e..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
deleted file mode 100644
index 1f8f318d1..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
deleted file mode 100644
index 2bb7b64f4..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
deleted file mode 100644
index f5ce40cf6..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
deleted file mode 100644
index ca73b9249..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_popup_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
deleted file mode 100644
index 73f2006d4..000000000
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_holo_dark.9.png
index 8e9a34957..8e9a34957 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_holo_light.9.png
index 2915588bf..2915588bf 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_holo_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_holo_dark.9.png
index 58a316fba..58a316fba 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_off_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
new file mode 100644
index 000000000..9f244f2e9
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_ics.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_ics_dark.9.png
index f3fc64114..f3fc64114 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_ics.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_klp.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_klp_dark.9.png
index b7b2dca43..b7b2dca43 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_normal_on_klp.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_normal_on_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
new file mode 100644
index 000000000..c5b3fbbd7
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_ics.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_ics_dark.9.png
index 8f340d355..8f340d355 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_ics.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_ics.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_ics_light.9.png
index c39dd4a94..c39dd4a94 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_ics.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_ics_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_klp.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_klp_dark.9.png
index 4a92b80dd..4a92b80dd 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_klp.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_klp.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_klp_light.9.png
index 049385984..049385984 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_light_pressed_klp.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_klp_light.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_ics.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
index 53ea5f894..53ea5f894 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_ics.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_klp.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
index 72125a065..72125a065 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_off_klp.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
new file mode 100644
index 000000000..66824cf8e
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_ics.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
index 69c84e7ec..69c84e7ec 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_ics.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_klp.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
index 82413d4cc..82413d4cc 100644
--- a/java/res/drawable-mdpi/btn_keyboard_key_dark_pressed_on_klp.9.png
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
new file mode 100644
index 000000000..527dfd014
--- /dev/null
+++ b/java/res/drawable-mdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/btn_suggestion_pressed.9.png b/java/res/drawable-mdpi/btn_suggestion_pressed.9.png
deleted file mode 100644
index 02b4e9a53..000000000
--- a/java/res/drawable-mdpi/btn_suggestion_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/emoji_category_tab_selected_ics.9.png b/java/res/drawable-mdpi/emoji_category_tab_selected_ics.9.png
new file mode 100644
index 000000000..1731b46ad
--- /dev/null
+++ b/java/res/drawable-mdpi/emoji_category_tab_selected_ics.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/emoji_category_tab_selected_klp.9.png b/java/res/drawable-mdpi/emoji_category_tab_selected_klp.9.png
new file mode 100644
index 000000000..6354b997a
--- /dev/null
+++ b/java/res/drawable-mdpi/emoji_category_tab_selected_klp.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/tab_unselected.9.png b/java/res/drawable-mdpi/emoji_category_tab_unselected_holo_dark.9.png
index bb45ab960..bb45ab960 100644
--- a/java/res/drawable-mdpi/tab_unselected.9.png
+++ b/java/res/drawable-mdpi/emoji_category_tab_unselected_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_emoticons_activated_holo_dark.png b/java/res/drawable-mdpi/ic_emoji_emoticons_activated_holo_dark.png
new file mode 100644
index 000000000..c7394e1b0
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_emoticons_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_emoticons_normal_holo_dark.png b/java/res/drawable-mdpi/ic_emoji_emoticons_normal_holo_dark.png
new file mode 100644
index 000000000..eb4dab4c7
--- /dev/null
+++ b/java/res/drawable-mdpi/ic_emoji_emoticons_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-mdpi/ic_emoji_nature_activated_holo_dark.png
index d4c8d8da8..d4c8d8da8 100644
--- a/java/res/drawable-mdpi/ic_emoji_nature_light_activated.png
+++ b/java/res/drawable-mdpi/ic_emoji_nature_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-mdpi/ic_emoji_nature_normal_holo_dark.png
index 1555aa7a9..1555aa7a9 100644
--- a/java/res/drawable-mdpi/ic_emoji_nature_light_normal.png
+++ b/java/res/drawable-mdpi/ic_emoji_nature_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-mdpi/ic_emoji_objects_activated_holo_dark.png
index 081dc66c2..081dc66c2 100644
--- a/java/res/drawable-mdpi/ic_emoji_objects_light_activated.png
+++ b/java/res/drawable-mdpi/ic_emoji_objects_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-mdpi/ic_emoji_objects_normal_holo_dark.png
index 58e6f6e75..58e6f6e75 100644
--- a/java/res/drawable-mdpi/ic_emoji_objects_light_normal.png
+++ b/java/res/drawable-mdpi/ic_emoji_objects_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_people_light_activated.png b/java/res/drawable-mdpi/ic_emoji_people_activated_holo_dark.png
index 067ad5496..067ad5496 100644
--- a/java/res/drawable-mdpi/ic_emoji_people_light_activated.png
+++ b/java/res/drawable-mdpi/ic_emoji_people_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_people_light_normal.png b/java/res/drawable-mdpi/ic_emoji_people_normal_holo_dark.png
index d835d4ec7..d835d4ec7 100644
--- a/java/res/drawable-mdpi/ic_emoji_people_light_normal.png
+++ b/java/res/drawable-mdpi/ic_emoji_people_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_places_light_activated.png b/java/res/drawable-mdpi/ic_emoji_places_activated_holo_dark.png
index 1aecec598..1aecec598 100644
--- a/java/res/drawable-mdpi/ic_emoji_places_light_activated.png
+++ b/java/res/drawable-mdpi/ic_emoji_places_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_places_light_normal.png b/java/res/drawable-mdpi/ic_emoji_places_normal_holo_dark.png
index c70e484e1..c70e484e1 100644
--- a/java/res/drawable-mdpi/ic_emoji_places_light_normal.png
+++ b/java/res/drawable-mdpi/ic_emoji_places_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-mdpi/ic_emoji_recents_activated_holo_dark.png
index 8009e932f..8009e932f 100644
--- a/java/res/drawable-mdpi/ic_emoji_recent_light_activated.png
+++ b/java/res/drawable-mdpi/ic_emoji_recents_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-mdpi/ic_emoji_recents_normal_holo_dark.png
index c2e598dfb..c2e598dfb 100644
--- a/java/res/drawable-mdpi/ic_emoji_recent_light_normal.png
+++ b/java/res/drawable-mdpi/ic_emoji_recents_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-mdpi/ic_emoji_symbols_activated_holo_dark.png
index caea87191..caea87191 100644
--- a/java/res/drawable-mdpi/ic_emoji_symbols_light_activated.png
+++ b/java/res/drawable-mdpi/ic_emoji_symbols_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-mdpi/ic_emoji_symbols_normal_holo_dark.png
index 0edada626..0edada626 100644
--- a/java/res/drawable-mdpi/ic_emoji_symbols_light_normal.png
+++ b/java/res/drawable-mdpi/ic_emoji_symbols_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png
new file mode 100644
index 000000000..d3200921a
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
new file mode 100644
index 000000000..60a36333e
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/keyboard_popup_panel_background_lxx_dark.9.png b/java/res/drawable-mdpi/keyboard_popup_panel_background_lxx_dark.9.png
new file mode 100644
index 000000000..896505518
--- /dev/null
+++ b/java/res/drawable-mdpi/keyboard_popup_panel_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_delete_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_delete_lxx_dark.png
new file mode 100644
index 000000000..2d3ac9749
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_delete_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_done_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_done_lxx_dark.png
new file mode 100644
index 000000000..8a63c116a
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_done_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_go_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_go_lxx_dark.png
new file mode 100644
index 000000000..89051722a
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_go_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_language_switch_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_language_switch_lxx_dark.png
new file mode 100644
index 000000000..a90bf757c
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_language_switch_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png
deleted file mode 100644
index 5e58866a7..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_mic_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_next_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_next_lxx_dark.png
new file mode 100644
index 000000000..414cb0d58
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_next_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_previous_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_previous_lxx_dark.png
new file mode 100644
index 000000000..40655ca3b
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_previous_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_return_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_return_lxx_dark.png
new file mode 100644
index 000000000..d060c89f6
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_return_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_search_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_search_lxx_dark.png
new file mode 100644
index 000000000..722d40258
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_search_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_send_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_send_lxx_dark.png
new file mode 100644
index 000000000..29dd9defc
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_send_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_settings_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_settings_lxx_dark.png
new file mode 100644
index 000000000..dea7addfe
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_settings_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_locked_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_locked_lxx_dark.png
new file mode 100644
index 000000000..c70084339
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_locked_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_shift_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_shift_lxx_dark.png
new file mode 100644
index 000000000..c10066e81
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_shift_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_smiley_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_smiley_lxx_dark.png
new file mode 100644
index 000000000..8276d992c
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_smiley_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.png b/java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.png
deleted file mode 100644
index abd8b742e..000000000
--- a/java/res/drawable-mdpi/sym_keyboard_space_led_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.png
new file mode 100644
index 000000000..ed32cf652
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_spacebar_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_lxx_dark.png
new file mode 100644
index 000000000..5661f6b33
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/sym_keyboard_voice_off_lxx_dark.png b/java/res/drawable-mdpi/sym_keyboard_voice_off_lxx_dark.png
new file mode 100644
index 000000000..5182f1e8f
--- /dev/null
+++ b/java/res/drawable-mdpi/sym_keyboard_voice_off_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-mdpi/tab_selected.9.png b/java/res/drawable-mdpi/tab_selected.9.png
deleted file mode 100644
index 4b00f350a..000000000
--- a/java/res/drawable-mdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_ics.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_ics_dark.9.png
index d990c0258..d990c0258 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_ics.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_klp.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_klp_dark.9.png
index a2f6ac0e2..a2f6ac0e2 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_active_klp.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png
new file mode 100644
index 000000000..0f6a3e1e0
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..44c84f1f8
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png
deleted file mode 100644
index d0090a305..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png
deleted file mode 100644
index 2baf7d90c..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png
deleted file mode 100644
index 6812f9e8f..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png
deleted file mode 100644
index a932249a8..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png
deleted file mode 100644
index 16416f000..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png
deleted file mode 100644
index 3ca93fdb3..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png
deleted file mode 100644
index aa4f44fdd..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png
deleted file mode 100644
index 4539255c2..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_popup_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png
deleted file mode 100644
index 568392444..000000000
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_holo_dark.9.png
index a2f6ac0e2..a2f6ac0e2 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_holo_light.9.png
index 0ef4a4b5f..0ef4a4b5f 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_holo_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_holo_dark.9.png
index 2f00fc623..2f00fc623 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
new file mode 100644
index 000000000..98c085b15
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_ics.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_ics_dark.9.png
index ab8fb2e86..ab8fb2e86 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_ics.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_klp.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_klp_dark.9.png
index 20251a000..20251a000 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_normal_on_klp.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
new file mode 100644
index 000000000..f0c132869
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_ics.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_ics_dark.9.png
index 3871689ef..3871689ef 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_ics.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_ics.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_ics_light.9.png
index c23a4b225..c23a4b225 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_ics.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_ics_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_klp.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_klp_dark.9.png
index 84d173967..84d173967 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_klp.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_klp.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_klp_light.9.png
index f770962c3..f770962c3 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_light_pressed_klp.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_klp_light.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_ics.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
index 912506368..912506368 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_ics.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_klp.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
index ee4490eac..ee4490eac 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_off_klp.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
new file mode 100644
index 000000000..a2b17ba50
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_ics.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
index 35ce67fdc..35ce67fdc 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_ics.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_klp.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
index e8124776c..e8124776c 100644
--- a/java/res/drawable-xhdpi/btn_keyboard_key_dark_pressed_on_klp.9.png
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
new file mode 100644
index 000000000..99ff0affb
--- /dev/null
+++ b/java/res/drawable-xhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/btn_suggestion_pressed.9.png b/java/res/drawable-xhdpi/btn_suggestion_pressed.9.png
deleted file mode 100644
index 41e126a73..000000000
--- a/java/res/drawable-xhdpi/btn_suggestion_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/emoji_category_tab_selected_ics.9.png b/java/res/drawable-xhdpi/emoji_category_tab_selected_ics.9.png
new file mode 100644
index 000000000..11bc966b0
--- /dev/null
+++ b/java/res/drawable-xhdpi/emoji_category_tab_selected_ics.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/emoji_category_tab_selected_klp.9.png b/java/res/drawable-xhdpi/emoji_category_tab_selected_klp.9.png
new file mode 100644
index 000000000..5e8549bdd
--- /dev/null
+++ b/java/res/drawable-xhdpi/emoji_category_tab_selected_klp.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/tab_unselected.9.png b/java/res/drawable-xhdpi/emoji_category_tab_unselected_holo_dark.9.png
index 8cede8d5e..8cede8d5e 100644
--- a/java/res/drawable-xhdpi/tab_unselected.9.png
+++ b/java/res/drawable-xhdpi/emoji_category_tab_unselected_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_emoticons_activated_holo_dark.png b/java/res/drawable-xhdpi/ic_emoji_emoticons_activated_holo_dark.png
new file mode 100644
index 000000000..997c9b700
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_emoticons_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_emoticons_normal_holo_dark.png b/java/res/drawable-xhdpi/ic_emoji_emoticons_normal_holo_dark.png
new file mode 100644
index 000000000..23a519c5d
--- /dev/null
+++ b/java/res/drawable-xhdpi/ic_emoji_emoticons_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_nature_activated_holo_dark.png
index 3e6744343..3e6744343 100644
--- a/java/res/drawable-xhdpi/ic_emoji_nature_light_activated.png
+++ b/java/res/drawable-xhdpi/ic_emoji_nature_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_nature_normal_holo_dark.png
index 5344a9ee9..5344a9ee9 100644
--- a/java/res/drawable-xhdpi/ic_emoji_nature_light_normal.png
+++ b/java/res/drawable-xhdpi/ic_emoji_nature_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_objects_activated_holo_dark.png
index 75695d43d..75695d43d 100644
--- a/java/res/drawable-xhdpi/ic_emoji_objects_light_activated.png
+++ b/java/res/drawable-xhdpi/ic_emoji_objects_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_objects_normal_holo_dark.png
index 2adb186e6..2adb186e6 100644
--- a/java/res/drawable-xhdpi/ic_emoji_objects_light_normal.png
+++ b/java/res/drawable-xhdpi/ic_emoji_objects_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_people_activated_holo_dark.png
index e6baa2e59..e6baa2e59 100644
--- a/java/res/drawable-xhdpi/ic_emoji_people_light_activated.png
+++ b/java/res/drawable-xhdpi/ic_emoji_people_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_people_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_people_normal_holo_dark.png
index c26aa4efb..c26aa4efb 100644
--- a/java/res/drawable-xhdpi/ic_emoji_people_light_normal.png
+++ b/java/res/drawable-xhdpi/ic_emoji_people_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_places_activated_holo_dark.png
index eaa3b86cf..eaa3b86cf 100644
--- a/java/res/drawable-xhdpi/ic_emoji_places_light_activated.png
+++ b/java/res/drawable-xhdpi/ic_emoji_places_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_places_normal_holo_dark.png
index d6e1eaa35..d6e1eaa35 100644
--- a/java/res/drawable-xhdpi/ic_emoji_places_light_normal.png
+++ b/java/res/drawable-xhdpi/ic_emoji_places_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_recents_activated_holo_dark.png
index 06003b82d..06003b82d 100644
--- a/java/res/drawable-xhdpi/ic_emoji_recent_light_activated.png
+++ b/java/res/drawable-xhdpi/ic_emoji_recents_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_recents_normal_holo_dark.png
index da2effedb..da2effedb 100644
--- a/java/res/drawable-xhdpi/ic_emoji_recent_light_normal.png
+++ b/java/res/drawable-xhdpi/ic_emoji_recents_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-xhdpi/ic_emoji_symbols_activated_holo_dark.png
index 438fde2b4..438fde2b4 100644
--- a/java/res/drawable-xhdpi/ic_emoji_symbols_light_activated.png
+++ b/java/res/drawable-xhdpi/ic_emoji_symbols_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-xhdpi/ic_emoji_symbols_normal_holo_dark.png
index 757863233..757863233 100644
--- a/java/res/drawable-xhdpi/ic_emoji_symbols_light_normal.png
+++ b/java/res/drawable-xhdpi/ic_emoji_symbols_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png
new file mode 100644
index 000000000..d40afebd8
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
new file mode 100644
index 000000000..d1a2f7599
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/keyboard_popup_panel_background_lxx_dark.9.png b/java/res/drawable-xhdpi/keyboard_popup_panel_background_lxx_dark.9.png
new file mode 100644
index 000000000..36df715b6
--- /dev/null
+++ b/java/res/drawable-xhdpi/keyboard_popup_panel_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_delete_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_delete_lxx_dark.png
new file mode 100644
index 000000000..7c9f34f12
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_delete_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_done_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_done_lxx_dark.png
new file mode 100644
index 000000000..f25e3dfd9
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_done_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_go_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_go_lxx_dark.png
new file mode 100644
index 000000000..6cd43cf8a
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_go_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_language_switch_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_language_switch_lxx_dark.png
new file mode 100644
index 000000000..f964346c1
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_language_switch_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png
deleted file mode 100644
index 566ba1fcd..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_mic_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_next_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_next_lxx_dark.png
new file mode 100644
index 000000000..8b5b0b4de
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_next_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_previous_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_previous_lxx_dark.png
new file mode 100644
index 000000000..9bc4fc81e
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_previous_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_return_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_return_lxx_dark.png
new file mode 100644
index 000000000..5d6e6cbf9
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_return_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_search_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_search_lxx_dark.png
new file mode 100644
index 000000000..28a4bd329
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_search_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_send_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_send_lxx_dark.png
new file mode 100644
index 000000000..4360a4ea1
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_send_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_settings_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_settings_lxx_dark.png
new file mode 100644
index 000000000..8c83d9fb6
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_settings_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_locked_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_lxx_dark.png
new file mode 100644
index 000000000..e329cbc8f
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_locked_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_shift_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_shift_lxx_dark.png
new file mode 100644
index 000000000..19acffaeb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_shift_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_smiley_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_smiley_lxx_dark.png
new file mode 100644
index 000000000..78923fadb
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_smiley_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.png b/java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.png
deleted file mode 100644
index ba4e9ec49..000000000
--- a/java/res/drawable-xhdpi/sym_keyboard_space_led_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.png
new file mode 100644
index 000000000..71234e570
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_spacebar_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_lxx_dark.png
new file mode 100644
index 000000000..4e9631e7b
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/sym_keyboard_voice_off_lxx_dark.png b/java/res/drawable-xhdpi/sym_keyboard_voice_off_lxx_dark.png
new file mode 100644
index 000000000..66c0e3c56
--- /dev/null
+++ b/java/res/drawable-xhdpi/sym_keyboard_voice_off_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xhdpi/tab_selected.9.png b/java/res/drawable-xhdpi/tab_selected.9.png
deleted file mode 100644
index 95e5f4341..000000000
--- a/java/res/drawable-xhdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_ics.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_ics_dark.9.png
index 680421eaf..680421eaf 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_ics.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_klp.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_klp_dark.9.png
index 17f0a7a58..17f0a7a58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_active_klp.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png
new file mode 100644
index 000000000..dc67c6f19
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
new file mode 100644
index 000000000..2e12dd1d4
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_active_pressed_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_holo_dark.9.png
index 17f0a7a58..17f0a7a58 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_holo_light.9.png
index 4ddfdcb6c..4ddfdcb6c 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_normal_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_holo_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_holo_dark.9.png
index b0e815eb2..b0e815eb2 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_off_holo.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
new file mode 100644
index 000000000..4ec5864c1
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_ics.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_ics_dark.9.png
index 40f5011c0..40f5011c0 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_ics.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_klp.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_klp_dark.9.png
index 97f96258e..97f96258e 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_normal_on_klp.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
new file mode 100644
index 000000000..6b5c0c0a4
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_normal_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_ics.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_ics_dark.9.png
index 6ff6319d3..6ff6319d3 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_ics.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_ics.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_ics_light.9.png
index 3c17c5eec..3c17c5eec 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_ics.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_ics_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_klp.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_klp_dark.9.png
index dfb16a76b..dfb16a76b 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_klp.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_klp.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_klp_light.9.png
index 17144b673..17144b673 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_light_pressed_klp.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_klp_light.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_ics.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
index 818ea70fd..818ea70fd 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_ics.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_klp.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
index bf1d34686..bf1d34686 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_off_klp.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
new file mode 100644
index 000000000..6fd8eedd3
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_off_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_ics.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
index a476d2a9e..a476d2a9e 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_ics.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_ics_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_klp.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
index 962277165..962277165 100644
--- a/java/res/drawable-xxhdpi/btn_keyboard_key_dark_pressed_on_klp.9.png
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_klp_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
new file mode 100644
index 000000000..91322882f
--- /dev/null
+++ b/java/res/drawable-xxhdpi/btn_keyboard_key_pressed_on_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/emoji_category_tab_selected_ics.9.png b/java/res/drawable-xxhdpi/emoji_category_tab_selected_ics.9.png
new file mode 100644
index 000000000..b13ee2b6a
--- /dev/null
+++ b/java/res/drawable-xxhdpi/emoji_category_tab_selected_ics.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/emoji_category_tab_selected_klp.9.png b/java/res/drawable-xxhdpi/emoji_category_tab_selected_klp.9.png
new file mode 100644
index 000000000..c81e651dd
--- /dev/null
+++ b/java/res/drawable-xxhdpi/emoji_category_tab_selected_klp.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/tab_unselected.9.png b/java/res/drawable-xxhdpi/emoji_category_tab_unselected_holo_dark.9.png
index 389188695..389188695 100644
--- a/java/res/drawable-xxhdpi/tab_unselected.9.png
+++ b/java/res/drawable-xxhdpi/emoji_category_tab_unselected_holo_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_emoticons_activated_holo_dark.png b/java/res/drawable-xxhdpi/ic_emoji_emoticons_activated_holo_dark.png
new file mode 100644
index 000000000..a217269cb
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_emoticons_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_emoticons_normal_holo_dark.png b/java/res/drawable-xxhdpi/ic_emoji_emoticons_normal_holo_dark.png
new file mode 100644
index 000000000..dfa43cd5b
--- /dev/null
+++ b/java/res/drawable-xxhdpi/ic_emoji_emoticons_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_nature_activated_holo_dark.png
index 470fd695c..470fd695c 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_nature_light_activated.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_nature_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_nature_normal_holo_dark.png
index a7fde0ec5..a7fde0ec5 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_nature_light_normal.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_nature_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_objects_activated_holo_dark.png
index c582b704a..c582b704a 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_objects_light_activated.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_objects_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_objects_normal_holo_dark.png
index acc95d725..acc95d725 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_objects_light_normal.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_objects_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_people_activated_holo_dark.png
index 5973ac355..5973ac355 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_people_light_activated.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_people_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_people_normal_holo_dark.png
index 22e06f808..22e06f808 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_people_light_normal.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_people_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_places_activated_holo_dark.png
index 690e95fd5..690e95fd5 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_places_light_activated.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_places_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_places_normal_holo_dark.png
index ced4b08cf..ced4b08cf 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_places_light_normal.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_places_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_recents_activated_holo_dark.png
index 25e847ef3..25e847ef3 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_recent_light_activated.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_recents_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_recents_normal_holo_dark.png
index c86368d73..c86368d73 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_recent_light_normal.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_recents_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png b/java/res/drawable-xxhdpi/ic_emoji_symbols_activated_holo_dark.png
index 29dfc7118..29dfc7118 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_activated.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_symbols_activated_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png b/java/res/drawable-xxhdpi/ic_emoji_symbols_normal_holo_dark.png
index 0570567cf..0570567cf 100644
--- a/java/res/drawable-xxhdpi/ic_emoji_symbols_light_normal.png
+++ b/java/res/drawable-xxhdpi/ic_emoji_symbols_normal_holo_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
new file mode 100644
index 000000000..f7814917d
--- /dev/null
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
new file mode 100644
index 000000000..a79499f24
--- /dev/null
+++ b/java/res/drawable-xxhdpi/keyboard_key_feedback_more_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/keyboard_popup_panel_background_lxx_dark.9.png b/java/res/drawable-xxhdpi/keyboard_popup_panel_background_lxx_dark.9.png
new file mode 100644
index 000000000..91d5d7f90
--- /dev/null
+++ b/java/res/drawable-xxhdpi/keyboard_popup_panel_background_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_delete_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_delete_lxx_dark.png
new file mode 100644
index 000000000..dd95be61e
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_delete_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_done_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_done_lxx_dark.png
new file mode 100644
index 000000000..ccd270e78
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_done_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_go_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_go_lxx_dark.png
new file mode 100644
index 000000000..0617c15e3
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_go_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_language_switch_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_lxx_dark.png
new file mode 100644
index 000000000..fc85e512d
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_language_switch_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png
deleted file mode 100644
index f55af308c..000000000
--- a/java/res/drawable-xxhdpi/sym_keyboard_mic_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_next_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_next_lxx_dark.png
new file mode 100644
index 000000000..1e2819b73
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_next_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_previous_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_previous_lxx_dark.png
new file mode 100644
index 000000000..bae6cb1fa
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_previous_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_return_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_return_lxx_dark.png
new file mode 100644
index 000000000..8c34d1160
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_return_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_search_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_search_lxx_dark.png
new file mode 100644
index 000000000..a32b6c5d9
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_search_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_send_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_send_lxx_dark.png
new file mode 100644
index 000000000..21a9e0909
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_send_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_settings_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_settings_lxx_dark.png
new file mode 100644
index 000000000..d513ad9e6
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_settings_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_lxx_dark.png
new file mode 100644
index 000000000..316903ef8
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_locked_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_shift_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_shift_lxx_dark.png
new file mode 100644
index 000000000..ddfc1a90d
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_shift_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_smiley_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_smiley_lxx_dark.png
new file mode 100644
index 000000000..a4df3bb0e
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_smiley_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.png b/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.png
new file mode 100644
index 000000000..01075ebf3
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_spacebar_lxx_dark.9.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_lxx_dark.png
new file mode 100644
index 000000000..a36724cac
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/sym_keyboard_voice_off_lxx_dark.png b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_lxx_dark.png
new file mode 100644
index 000000000..2706dca57
--- /dev/null
+++ b/java/res/drawable-xxhdpi/sym_keyboard_voice_off_lxx_dark.png
Binary files differ
diff --git a/java/res/drawable-xxhdpi/tab_selected.9.png b/java/res/drawable-xxhdpi/tab_selected.9.png
deleted file mode 100644
index e5efc5828..000000000
--- a/java/res/drawable-xxhdpi/tab_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/java/res/drawable/btn_keyboard_key_functional_ics.xml b/java/res/drawable/btn_keyboard_key_functional_ics.xml
index 847ca72f4..846bccc49 100644
--- a/java/res/drawable/btn_keyboard_key_functional_ics.xml
+++ b/java/res/drawable/btn_keyboard_key_functional_ics.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Functional keys. -->
<item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_ics" />
- <item android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_ics_dark" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_holo_dark" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_functional_klp.xml b/java/res/drawable/btn_keyboard_key_functional_klp.xml
index 0e17ed234..7b444f7c5 100644
--- a/java/res/drawable/btn_keyboard_key_functional_klp.xml
+++ b/java/res/drawable/btn_keyboard_key_functional_klp.xml
@@ -17,6 +17,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Functional keys. -->
<item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_klp" />
- <item android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_klp_dark" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_holo_dark" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_functional_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_functional_lxx_dark.xml
new file mode 100644
index 000000000..fd1dbb9f0
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_functional_lxx_dark.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Functional keys. -->
+ <item android:state_pressed="true"
+ android:drawable="@color/key_background_pressed_lxx_dark" />
+ <item android:drawable="@color/key_background_lxx_dark" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_ics.xml b/java/res/drawable/btn_keyboard_key_ics.xml
index 259bb9ba5..0bb098d23 100644
--- a/java/res/drawable/btn_keyboard_key_ics.xml
+++ b/java/res/drawable/btn_keyboard_key_ics.xml
@@ -15,34 +15,28 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Functional keys. -->
- <item android:state_single="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_ics" />
- <item android:state_single="true"
- android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
-
<!-- Action keys. -->
<item android:state_active="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_ics" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_ics_dark" />
<item android:state_active="true"
- android:drawable="@drawable/btn_keyboard_key_dark_active_ics" />
+ android:drawable="@drawable/btn_keyboard_key_active_ics_dark" />
<!-- Toggle keys. Use checkable/checked state. -->
<item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_on_ics" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_on_ics_dark" />
<item android:state_checkable="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_off_ics" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_off_ics_dark" />
<item android:state_checkable="true" android:state_checked="true"
- android:drawable="@drawable/btn_keyboard_key_dark_normal_on_ics" />
+ android:drawable="@drawable/btn_keyboard_key_normal_on_ics_dark" />
<item android:state_checkable="true"
- android:drawable="@drawable/btn_keyboard_key_dark_normal_off_holo" />
+ android:drawable="@drawable/btn_keyboard_key_normal_off_holo_dark" />
<!-- Empty background keys. -->
<item android:state_empty="true"
- android:drawable="@drawable/transparent" />
+ android:drawable="@android:color/transparent" />
<!-- Normal keys. -->
<item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_light_pressed_ics" />
- <item android:drawable="@drawable/btn_keyboard_key_light_normal_holo" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_ics_light" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_holo_light" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_klp.xml b/java/res/drawable/btn_keyboard_key_klp.xml
index 16b5fa00b..2a202a179 100644
--- a/java/res/drawable/btn_keyboard_key_klp.xml
+++ b/java/res/drawable/btn_keyboard_key_klp.xml
@@ -15,34 +15,28 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Functional keys. -->
- <item android:state_single="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_klp" />
- <item android:state_single="true"
- android:drawable="@drawable/btn_keyboard_key_dark_normal_holo" />
-
<!-- Action keys. -->
<item android:state_active="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_klp" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_klp_dark" />
<item android:state_active="true"
- android:drawable="@drawable/btn_keyboard_key_dark_active_klp" />
+ android:drawable="@drawable/btn_keyboard_key_active_klp_dark" />
<!-- Toggle keys. Use checkable/checked state. -->
<item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_on_klp" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_on_klp_dark" />
<item android:state_checkable="true" android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_dark_pressed_off_klp" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_off_klp_dark" />
<item android:state_checkable="true" android:state_checked="true"
- android:drawable="@drawable/btn_keyboard_key_dark_normal_on_klp" />
+ android:drawable="@drawable/btn_keyboard_key_normal_on_klp_dark" />
<item android:state_checkable="true"
- android:drawable="@drawable/btn_keyboard_key_dark_normal_off_holo" />
+ android:drawable="@drawable/btn_keyboard_key_normal_off_holo_dark" />
<!-- Empty background keys. -->
<item android:state_empty="true"
- android:drawable="@drawable/transparent" />
+ android:drawable="@android:color/transparent" />
<!-- Normal keys. -->
<item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_light_pressed_klp" />
- <item android:drawable="@drawable/btn_keyboard_key_light_normal_holo" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_klp_light" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_holo_light" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_lxx_dark.xml b/java/res/drawable/btn_keyboard_key_lxx_dark.xml
new file mode 100644
index 000000000..bb1789ae3
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_key_lxx_dark.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Action keys. -->
+ <item android:state_active="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_active_pressed_lxx_dark" />
+ <item android:state_active="true"
+ android:drawable="@drawable/btn_keyboard_key_active_lxx_dark" />
+
+ <!-- Toggle keys. Use checkable/checked state. -->
+ <item android:state_checkable="true" android:state_checked="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_pressed_on_lxx_dark" />
+ <item android:state_checkable="true" android:state_pressed="true"
+ android:drawable="@drawable/btn_keyboard_key_pressed_off_lxx_dark" />
+ <item android:state_checkable="true" android:state_checked="true"
+ android:drawable="@drawable/btn_keyboard_key_normal_on_lxx_dark" />
+ <item android:state_checkable="true"
+ android:drawable="@drawable/btn_keyboard_key_normal_off_lxx_dark" />
+
+ <!-- Empty background keys. -->
+ <item android:state_empty="true"
+ android:drawable="@color/key_background_lxx_dark" />
+
+ <!-- Normal keys. -->
+ <item android:state_pressed="true"
+ android:drawable="@color/key_background_pressed_lxx_dark" />
+ <item android:drawable="@color/key_background_lxx_dark" />
+</selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup_ics.xml b/java/res/drawable/btn_keyboard_key_popup_ics.xml
index 31b613176..17d646b8f 100644
--- a/java/res/drawable/btn_keyboard_key_popup_ics.xml
+++ b/java/res/drawable/btn_keyboard_key_popup_ics.xml
@@ -17,5 +17,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_popup_selected_ics" />
- <item android:drawable="@drawable/transparent" />
+ <item android:drawable="@android:color/transparent" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_key_popup_klp.xml b/java/res/drawable/btn_keyboard_key_popup_klp.xml
index 62cbca8ae..9dfc93ae8 100644
--- a/java/res/drawable/btn_keyboard_key_popup_klp.xml
+++ b/java/res/drawable/btn_keyboard_key_popup_klp.xml
@@ -17,5 +17,5 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/btn_keyboard_key_popup_selected_klp" />
- <item android:drawable="@drawable/transparent" />
+ <item android:drawable="@android:color/transparent" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_spacebar_ics.xml b/java/res/drawable/btn_keyboard_spacebar_ics.xml
index 4530ea079..229f7a965 100644
--- a/java/res/drawable/btn_keyboard_spacebar_ics.xml
+++ b/java/res/drawable/btn_keyboard_spacebar_ics.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_light_pressed_ics" />
- <item android:drawable="@drawable/btn_keyboard_key_light_normal_holo" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_ics_light" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_holo_light" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_spacebar_klp.xml b/java/res/drawable/btn_keyboard_spacebar_klp.xml
index 6b07a392f..9882f9a74 100644
--- a/java/res/drawable/btn_keyboard_spacebar_klp.xml
+++ b/java/res/drawable/btn_keyboard_spacebar_klp.xml
@@ -16,6 +16,6 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
- android:drawable="@drawable/btn_keyboard_key_light_pressed_klp" />
- <item android:drawable="@drawable/btn_keyboard_key_light_normal_holo" />
+ android:drawable="@drawable/btn_keyboard_key_pressed_klp_light" />
+ <item android:drawable="@drawable/btn_keyboard_key_normal_holo_light" />
</selector>
diff --git a/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml b/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml
new file mode 100644
index 000000000..5c595d9ed
--- /dev/null
+++ b/java/res/drawable/btn_keyboard_spacebar_lxx_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@color/key_background_pressed_lxx_dark" />
+ <item android:drawable="@color/key_background_lxx_dark" />
+</selector>
diff --git a/java/res/drawable/transparent.xml b/java/res/drawable/btn_suggestion_lxx_dark.xml
index 855cf2ad5..84a91209e 100644
--- a/java/res/drawable/transparent.xml
+++ b/java/res/drawable/btn_suggestion_lxx_dark.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2011, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,13 +18,10 @@
*/
-->
-<shape
+<selector
xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle"
>
- <solid
- android:color="@android:color/transparent" />
- <size
- android:width="50dp"
- android:height="40dp" />
-</shape>
+ <item
+ android:state_pressed="true"
+ android:drawable="@color/suggested_word_background_selected_lxx_dark" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_emoticons_holo_dark.xml b/java/res/drawable/ic_emoji_emoticons_holo_dark.xml
new file mode 100644
index 000000000..59e23499e
--- /dev/null
+++ b/java/res/drawable/ic_emoji_emoticons_holo_dark.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_emoticons_activated_holo_dark" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_emoticons_activated_holo_dark" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_emoticons_activated_holo_dark" />
+ <item android:drawable="@drawable/ic_emoji_emoticons_normal_holo_dark" />
+</selector>
diff --git a/java/res/color/emoji_tab_label_color_holo.xml b/java/res/drawable/ic_emoji_nature_holo_dark.xml
index 373e9314b..b94629580 100644
--- a/java/res/color/emoji_tab_label_color_holo.xml
+++ b/java/res/drawable/ic_emoji_nature_holo_dark.xml
@@ -21,13 +21,13 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
- android:color="@color/key_text_color_holo" />
+ android:drawable="@drawable/ic_emoji_nature_activated_holo_dark" />
<item
android:state_pressed="true"
- android:color="@color/key_text_color_holo" />
+ android:drawable="@drawable/ic_emoji_nature_activated_holo_dark" />
<item
android:state_selected="true"
- android:color="@color/key_text_color_holo" />
+ android:drawable="@drawable/ic_emoji_nature_activated_holo_dark" />
<item
- android:color="@color/key_text_inactivated_color_holo" />
+ android:drawable="@drawable/ic_emoji_nature_normal_holo_dark" />
</selector>
diff --git a/java/res/drawable/ic_emoji_nature_light.xml b/java/res/drawable/ic_emoji_objects_holo_dark.xml
index 543409e03..266e81e0b 100644
--- a/java/res/drawable/ic_emoji_nature_light.xml
+++ b/java/res/drawable/ic_emoji_objects_holo_dark.xml
@@ -21,13 +21,12 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
- android:drawable="@drawable/ic_emoji_nature_light_activated" />
+ android:drawable="@drawable/ic_emoji_objects_activated_holo_dark" />
<item
android:state_pressed="true"
- android:drawable="@drawable/ic_emoji_nature_light_activated" />
+ android:drawable="@drawable/ic_emoji_objects_activated_holo_dark" />
<item
android:state_selected="true"
- android:drawable="@drawable/ic_emoji_nature_light_activated" />
- <item
- android:drawable="@drawable/ic_emoji_nature_light_normal" />
+ android:drawable="@drawable/ic_emoji_objects_activated_holo_dark" />
+ <item android:drawable="@drawable/ic_emoji_objects_normal_holo_dark" />
</selector>
diff --git a/java/res/drawable/ic_emoji_objects_light.xml b/java/res/drawable/ic_emoji_people_holo_dark.xml
index 4096e695b..15955d261 100644
--- a/java/res/drawable/ic_emoji_objects_light.xml
+++ b/java/res/drawable/ic_emoji_people_holo_dark.xml
@@ -21,12 +21,12 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
- android:drawable="@drawable/ic_emoji_objects_light_activated" />
+ android:drawable="@drawable/ic_emoji_people_activated_holo_dark" />
<item
android:state_pressed="true"
- android:drawable="@drawable/ic_emoji_objects_light_activated" />
+ android:drawable="@drawable/ic_emoji_people_activated_holo_dark" />
<item
android:state_selected="true"
- android:drawable="@drawable/ic_emoji_objects_light_activated" />
- <item android:drawable="@drawable/ic_emoji_objects_light_normal" />
+ android:drawable="@drawable/ic_emoji_people_activated_holo_dark" />
+ <item android:drawable="@drawable/ic_emoji_people_normal_holo_dark" />
</selector>
diff --git a/java/res/drawable/ic_emoji_people_light.xml b/java/res/drawable/ic_emoji_places_holo_dark.xml
index ea9e406a4..260bbd843 100644
--- a/java/res/drawable/ic_emoji_people_light.xml
+++ b/java/res/drawable/ic_emoji_places_holo_dark.xml
@@ -21,12 +21,12 @@
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="true"
- android:drawable="@drawable/ic_emoji_people_light_activated" />
+ android:drawable="@drawable/ic_emoji_places_activated_holo_dark" />
<item
android:state_pressed="true"
- android:drawable="@drawable/ic_emoji_people_light_activated" />
+ android:drawable="@drawable/ic_emoji_places_activated_holo_dark" />
<item
android:state_selected="true"
- android:drawable="@drawable/ic_emoji_people_light_activated" />
- <item android:drawable="@drawable/ic_emoji_people_light_normal" />
+ android:drawable="@drawable/ic_emoji_places_activated_holo_dark" />
+ <item android:drawable="@drawable/ic_emoji_places_normal_holo_dark" />
</selector>
diff --git a/java/res/drawable/ic_emoji_places_light.xml b/java/res/drawable/ic_emoji_places_light.xml
deleted file mode 100644
index 312cad9c3..000000000
--- a/java/res/drawable/ic_emoji_places_light.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_focused="true"
- android:drawable="@drawable/ic_emoji_places_light_activated" />
- <item
- android:state_pressed="true"
- android:drawable="@drawable/ic_emoji_places_light_activated" />
- <item
- android:state_selected="true"
- android:drawable="@drawable/ic_emoji_places_light_activated" />
- <item android:drawable="@drawable/ic_emoji_places_light_normal" />
-</selector>
diff --git a/java/res/drawable/ic_emoji_recent_light.xml b/java/res/drawable/ic_emoji_recent_light.xml
deleted file mode 100644
index 8c2123f83..000000000
--- a/java/res/drawable/ic_emoji_recent_light.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_focused="true"
- android:drawable="@drawable/ic_emoji_recent_light_activated" />
- <item
- android:state_pressed="true"
- android:drawable="@drawable/ic_emoji_recent_light_activated" />
- <item
- android:state_selected="true"
- android:drawable="@drawable/ic_emoji_recent_light_activated" />
- <item android:drawable="@drawable/ic_emoji_recent_light_normal" />
-</selector>
diff --git a/java/res/drawable/ic_emoji_recents_holo_dark.xml b/java/res/drawable/ic_emoji_recents_holo_dark.xml
new file mode 100644
index 000000000..f14349f34
--- /dev/null
+++ b/java/res/drawable/ic_emoji_recents_holo_dark.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_recents_activated_holo_dark" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_recents_activated_holo_dark" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_recents_activated_holo_dark" />
+ <item android:drawable="@drawable/ic_emoji_recents_normal_holo_dark" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_symbols_holo_dark.xml b/java/res/drawable/ic_emoji_symbols_holo_dark.xml
new file mode 100644
index 000000000..831d6594b
--- /dev/null
+++ b/java/res/drawable/ic_emoji_symbols_holo_dark.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2013, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_focused="true"
+ android:drawable="@drawable/ic_emoji_symbols_activated_holo_dark" />
+ <item
+ android:state_pressed="true"
+ android:drawable="@drawable/ic_emoji_symbols_activated_holo_dark" />
+ <item
+ android:state_selected="true"
+ android:drawable="@drawable/ic_emoji_symbols_activated_holo_dark" />
+ <item android:drawable="@drawable/ic_emoji_symbols_normal_holo_dark" />
+</selector>
diff --git a/java/res/drawable/ic_emoji_symbols_light.xml b/java/res/drawable/ic_emoji_symbols_light.xml
deleted file mode 100644
index 79aaf0fc5..000000000
--- a/java/res/drawable/ic_emoji_symbols_light.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2013, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:state_focused="true"
- android:drawable="@drawable/ic_emoji_symbols_light_activated" />
- <item
- android:state_pressed="true"
- android:drawable="@drawable/ic_emoji_symbols_light_activated" />
- <item
- android:state_selected="true"
- android:drawable="@drawable/ic_emoji_symbols_light_activated" />
- <item android:drawable="@drawable/ic_emoji_symbols_light_normal" />
-</selector>
diff --git a/java/res/drawable/keyboard_key_feedback_lxx_dark.xml b/java/res/drawable/keyboard_key_feedback_lxx_dark.xml
new file mode 100644
index 000000000..ab1109bcc
--- /dev/null
+++ b/java/res/drawable/keyboard_key_feedback_lxx_dark.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- Left edge -->
+ <item latin:state_left_edge="true" latin:state_has_morekeys="true"
+ android:drawable="@drawable/keyboard_key_feedback_more_background_lxx_dark" />
+ <item latin:state_left_edge="true"
+ android:drawable="@drawable/keyboard_key_feedback_background_lxx_dark" />
+
+ <!-- Right edge -->
+ <item latin:state_right_edge="true" latin:state_has_morekeys="true"
+ android:drawable="@drawable/keyboard_key_feedback_more_background_lxx_dark" />
+ <item latin:state_right_edge="true"
+ android:drawable="@drawable/keyboard_key_feedback_background_lxx_dark" />
+
+ <item latin:state_has_morekeys="true"
+ android:drawable="@drawable/keyboard_key_feedback_more_background_lxx_dark" />
+ <item android:drawable="@drawable/keyboard_key_feedback_background_lxx_dark" />
+</selector>
diff --git a/java/res/layout/emoji_keyboard_page.xml b/java/res/layout/emoji_keyboard_page.xml
index 9afad366a..0d1086171 100644
--- a/java/res/layout/emoji_keyboard_page.xml
+++ b/java/res/layout/emoji_keyboard_page.xml
@@ -18,7 +18,7 @@
*/
-->
-<com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView
+<com.android.inputmethod.keyboard.emoji.EmojiPageKeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/emoji_keyboard_page"
android:layoutDirection="ltr"
diff --git a/java/res/layout/emoji_keyboard_tab_icon.xml b/java/res/layout/emoji_keyboard_tab_icon.xml
index 13bb41ca2..15f9c3a3e 100644
--- a/java/res/layout/emoji_keyboard_tab_icon.xml
+++ b/java/res/layout/emoji_keyboard_tab_icon.xml
@@ -19,6 +19,8 @@
-->
<!-- Note: contentDescription will be added programatically in {@link EmojiPalettesView}. -->
+<!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dip"
android:layout_weight="1.0"
@@ -26,4 +28,6 @@
android:gravity="center"
android:scaleType="center"
android:contentDescription="@null"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false"
/>
diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml
index 552a474b4..9ff090aad 100644
--- a/java/res/layout/emoji_palettes_view.xml
+++ b/java/res/layout/emoji_palettes_view.xml
@@ -18,7 +18,7 @@
*/
-->
-<com.android.inputmethod.keyboard.EmojiPalettesView
+<com.android.inputmethod.keyboard.emoji.EmojiPalettesView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/emoji_keyboard_view"
android:orientation="vertical"
@@ -41,11 +41,7 @@
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/tab_selected"
- android:divider="@null"
- android:tabStripEnabled="true"
- android:tabStripLeft="@drawable/tab_unselected"
- android:tabStripRight="@drawable/tab_unselected" />
+ android:divider="@null" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dip"
@@ -65,24 +61,26 @@
android:layout_width="2dip"
android:layout_height="match_parent"
android:background="@drawable/suggestions_strip_divider" />
+ <!-- TODO: Implement KeyView and replace this. -->
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<ImageButton
android:id="@+id/emoji_keyboard_delete"
android:layout_width="0dip"
android:layout_weight="12.5"
android:layout_height="match_parent"
- android:background="@color/emoji_key_background_color"
- android:src="@drawable/sym_keyboard_delete_holo_dark"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false"
android:contentDescription="@string/spoken_description_delete" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/emoji_keyboard_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <com.android.inputmethod.keyboard.EmojiCategoryPageIndicatorView
+ <com.android.inputmethod.keyboard.emoji.EmojiCategoryPageIndicatorView
android:id="@+id/emoji_category_page_id_view"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/emoji_category_page_id_view_background" />
+ android:layout_height="2dip" />
<LinearLayout
android:id="@+id/emoji_action_bar"
android:orientation="horizontal"
@@ -90,23 +88,47 @@
android:layout_height="0dip"
android:layout_weight="1"
>
+ <!-- TODO: Implement a KeyView and replace this. -->
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<TextView
android:id="@+id/emoji_keyboard_alphabet_left"
android:layout_width="0dip"
android:layout_weight="0.15"
android:gravity="center"
- android:layout_height="match_parent" />
- <ImageButton
+ android:layout_height="match_parent"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false" />
+ <!-- TODO: Implement KeyView and replace this. -->
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
+ <RelativeLayout
android:id="@+id/emoji_keyboard_space"
android:layout_width="0dip"
android:layout_weight="0.70"
android:layout_height="match_parent"
- android:contentDescription="@string/spoken_description_space"/>
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false"
+ android:contentDescription="@string/spoken_description_space">
+ <!-- WORKAROUND: Show the spacebar icon as a bacground of this View. -->
+ <View
+ android:id="@+id/emoji_keyboard_space_icon"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="12dp"
+ android:layout_marginRight="12dp"
+ android:layout_centerInParent="true" />
+ </RelativeLayout>
+ <!-- TODO: Implement KeyView and replace this. -->
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<TextView
android:id="@+id/emoji_keyboard_alphabet_right"
android:layout_width="0dip"
android:layout_weight="0.15"
android:gravity="center"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false" />
</LinearLayout>
-</com.android.inputmethod.keyboard.EmojiPalettesView>
+</com.android.inputmethod.keyboard.emoji.EmojiPalettesView>
diff --git a/java/res/layout/input_view.xml b/java/res/layout/input_view.xml
index ed387e5b2..ff0b403d1 100644
--- a/java/res/layout/input_view.xml
+++ b/java/res/layout/input_view.xml
@@ -43,8 +43,6 @@
android:layout_width="match_parent"
android:layout_height="@dimen/config_suggestions_strip_height"
android:gravity="center_vertical"
- android:paddingRight="@dimen/config_suggestions_strip_horizontal_padding"
- android:paddingLeft="@dimen/config_suggestions_strip_horizontal_padding"
style="?attr/suggestionStripViewStyle" />
<!-- To ensure that key preview popup is correctly placed when the current system locale is
diff --git a/java/res/layout/research_feedback_activity.xml b/java/res/layout/research_feedback_activity.xml
deleted file mode 100644
index a6b8b8a43..000000000
--- a/java/res/layout/research_feedback_activity.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.inputmethod.research.FeedbackLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:id="@+id/research_feedback_layout"
->
-
- <fragment
- android:id="@+id/research_feedback_fragment"
- android:name="com.android.inputmethod.research.FeedbackFragment"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- />
-</com.android.inputmethod.research.FeedbackLayout>
diff --git a/java/res/layout/research_feedback_fragment_layout.xml b/java/res/layout/research_feedback_fragment_layout.xml
deleted file mode 100644
index fb5c27815..000000000
--- a/java/res/layout/research_feedback_fragment_layout.xml
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Adapted from frameworks/base/core/res/res/layout/alert_dialog_holo.xml. We
- want a dialog, but it must be its own activity so we can launch the soft
- keyboard on it. A regular dialog will not work since it would be launched from
- the IME. -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginStart="8dip"
- android:layout_marginEnd="8dip"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- <View android:layout_width="match_parent"
- android:layout_height="2dip"
- android:visibility="gone"
- android:background="@android:color/holo_blue_light" />
- <TextView
- style="?android:attr/windowTitleStyle"
- android:singleLine="true"
- android:ellipsize="end"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:minHeight="64dip"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:gravity="center_vertical|left"
- android:text="@string/research_feedback_dialog_title" />
- <View
- android:layout_width="match_parent"
- android:layout_height="2dip"
- android:background="@android:color/holo_blue_light" />
- </LinearLayout>
-
- <EditText
- android:id="@+id/research_feedback_contents"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="fill_horizontal|center_vertical"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:layout_marginBottom="8dip"
- android:layout_marginTop="8dip"
- android:minLines="2"
- android:scrollbars="vertical"
- android:hint="@string/research_feedback_hint"
- android:inputType="textMultiLine|textCapSentences">
- <requestFocus />
- </EditText>
- <CheckBox
- android:id="@+id/research_feedback_include_account_name"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:layout_marginBottom="8dip"
- android:checked="false"
- android:text="@string/research_feedback_include_account_name_label" />
- <CheckBox
- android:id="@+id/research_feedback_include_recording_checkbox"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_marginLeft="16dip"
- android:layout_marginRight="16dip"
- android:layout_marginBottom="8dip"
- android:checked="false"
- android:text="@string/research_feedback_include_recording_label" />
- <LinearLayout
- style="?android:attr/buttonBarStyle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layoutDirection="locale"
- android:measureWithLargestChild="true">
- <Button
- android:id="@+id/research_feedback_cancel_button"
- android:layout_width="wrap_content"
- android:layout_gravity="left"
- android:layout_weight="1"
- android:maxLines="2"
- style="?android:attr/buttonBarButtonStyle"
- android:textSize="14sp"
- android:text="@string/research_feedback_cancel"
- android:layout_height="wrap_content" />
- <Button
- android:id="@+id/research_feedback_send_button"
- android:layout_width="wrap_content"
- android:layout_gravity="right"
- android:layout_weight="1"
- android:maxLines="2"
- style="?android:attr/buttonBarButtonStyle"
- android:textSize="14sp"
- android:text="@string/research_feedback_send"
- android:layout_height="wrap_content" />
- </LinearLayout>
- </LinearLayout>
-</ScrollView>
diff --git a/java/res/layout/research_feedback_layout.xml b/java/res/layout/research_feedback_layout.xml
deleted file mode 100644
index bacd19101..000000000
--- a/java/res/layout/research_feedback_layout.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical"
->
-
- <EditText
- android:id="@+id/research_feedback_contents"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="fill_horizontal|center_vertical"
- android:layout_marginLeft="8dip"
- android:layout_marginRight="8dip"
- android:layout_marginBottom="8dip"
- android:layout_marginTop="8dip"
- android:lines="2"
- android:hint="@string/research_feedback_hint"
- android:inputType="textMultiLine"
- android:imeOptions="flagNoFullscreen"
- android:focusable="true"
- >
- <requestFocus />
- </EditText>
-
- <CheckBox
- android:id="@+id/research_feedback_include_history"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_marginBottom="8dip"
- android:checked="true"
- android:text="@string/research_feedback_include_history_label"
- />
-</LinearLayout>
diff --git a/java/res/layout/suggestion_divider.xml b/java/res/layout/suggestion_divider.xml
index 149095147..563599d82 100644
--- a/java/res/layout/suggestion_divider.xml
+++ b/java/res/layout/suggestion_divider.xml
@@ -18,11 +18,17 @@
*/
-->
+<!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:padding="0dp"
+ android:gravity="center"
android:src="@drawable/suggestions_strip_divider"
android:contentDescription="@null"
- android:padding="0dp"
- android:gravity="center" />
+ android:clickable="false"
+ android:longClickable="false"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false" />
diff --git a/java/res/layout/suggestions_strip.xml b/java/res/layout/suggestions_strip.xml
index 0b614993b..489477990 100644
--- a/java/res/layout/suggestions_strip.xml
+++ b/java/res/layout/suggestions_strip.xml
@@ -20,17 +20,28 @@
<merge
xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<LinearLayout
android:id="@+id/suggestions_strip"
android:orientation="horizontal"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:layout_marginLeft="@dimen/config_suggestions_strip_horizontal_margin"
+ android:layout_marginRight="@dimen/config_suggestions_strip_horizontal_margin"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false" />
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<LinearLayout
android:id="@+id/add_to_dictionary_strip"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="invisible">
+ android:layout_marginLeft="@dimen/config_suggestions_strip_horizontal_margin"
+ android:layout_marginRight="@dimen/config_suggestions_strip_horizontal_margin"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false">
<TextView
android:id="@+id/word_to_save"
android:layout_width="match_parent"
@@ -45,11 +56,17 @@
android:textAlignment="viewStart"
style="?attr/suggestionWordStyle" />
</LinearLayout>
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<LinearLayout
android:id="@+id/important_notice_strip"
android:orientation="horizontal"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:layout_marginLeft="@dimen/config_suggestions_strip_horizontal_margin"
+ android:layout_marginRight="@dimen/config_suggestions_strip_horizontal_margin"
+ android:hapticFeedbackEnabled="false"
+ android:soundEffectsEnabled="false" >
<TextView
android:id="@+id/important_notice_title"
android:layout_width="match_parent"
@@ -58,4 +75,13 @@
android:textSize="16sp"
style="?attr/suggestionWordStyle" />
</LinearLayout>
+ <ImageButton
+ android:id="@+id/suggestions_strip_voice_key"
+ android:layout_width="@dimen/config_suggestions_strip_edge_key_width"
+ android:layout_height="fill_parent"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:contentDescription="@string/spoken_description_mic"
+ style="?attr/suggestionWordStyle" />
</merge>
diff --git a/java/res/raw/main_en.dict b/java/res/raw/main_en.dict
index 49adc9a19..d631d6fbc 100644
--- a/java/res/raw/main_en.dict
+++ b/java/res/raw/main_en.dict
Binary files differ
diff --git a/java/res/raw/main_es.dict b/java/res/raw/main_es.dict
index fe24cd624..83eefe4f6 100644
--- a/java/res/raw/main_es.dict
+++ b/java/res/raw/main_es.dict
Binary files differ
diff --git a/java/res/raw/main_fr.dict b/java/res/raw/main_fr.dict
index 94d1b9670..19532d9bf 100644
--- a/java/res/raw/main_fr.dict
+++ b/java/res/raw/main_fr.dict
Binary files differ
diff --git a/java/res/values-af/strings-action-keys.xml b/java/res/values-af/strings-action-keys.xml
index c5cd71ab7..bef175b16 100644
--- a/java/res/values-af/strings-action-keys.xml
+++ b/java/res/values-af/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Vorige"</string>
<string name="label_done_key" msgid="7564866296502630852">"Klaar"</string>
<string name="label_send_key" msgid="482252074224462163">"Stuur"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Laat wag"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Wag"</string>
</resources>
diff --git a/java/res/values-af/strings-talkback-descriptions.xml b/java/res/values-af/strings-talkback-descriptions.xml
index 3529e5a5d..09abb5f6c 100644
--- a/java/res/values-af/strings-talkback-descriptions.xml
+++ b/java/res/values-af/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Geen teks is ingevoer nie"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> korrigeer <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> na <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> voer outokorrigering uit"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Sleutelkode %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift aan (tik om te deaktiveer)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Kasslot aan (tik om te deaktiveer)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Meer simbole"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simbole"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Vee uit"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simbole"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letters"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Vorige"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift geaktiveer"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Bokas-slot geaktiveer"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift gedeaktiveer"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Simboolmodus"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Meersimbole-modus"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Lettermodus"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Foonmodus"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Foonsimbool-modus"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Plekke"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simbole"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emosiekone"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-af/strings.xml b/java/res/values-af/strings.xml
index ce7cb18fc..2d1653f28 100644
--- a/java/res/values-af/strings.xml
+++ b/java/res/values-af/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Invoeropsies"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Navorsing-loglêerbevele"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Soek kontakname op"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Speltoetser gebruik inskrywings uit jou kontaklys"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibreer met sleuteldruk"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Stel kontakname voor"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gebruik name van kontakte vir voorstelle en korreksies"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Gepersonaliseerde voorstelle"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dubbelspasie-punt"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubbeltik op spasiebalk voeg \'n punt in, gevolg deur \'n spasie"</string>
<string name="auto_cap" msgid="1719746674854628252">"Outohoofletters"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Invoertale"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Raak weer om te stoor"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Woordeboek beskikbaar"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Aktiveer gebruikerterugvoer"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Help om hierdie invoermetode-redigeerder te verbeter deur gebruikstatistiek en omvalverslae outomaties te stuur"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Sleutelbordtema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engels (VK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engels (VS)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktiveer"</string>
<string name="not_now" msgid="6172462888202790482">"Nie nou nie"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Dieselfde invoerstyl bestaan ​​reeds: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruikbaarheidstudie-modus"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Vertraging van sleutellangdruk"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Sleuteldruk se vibrasie-tydsduur"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Sleuteldruk se klankvolume"</string>
diff --git a/java/res/values-am/strings-action-keys.xml b/java/res/values-am/strings-action-keys.xml
index 1813a86d8..26e45135b 100644
--- a/java/res/values-am/strings-action-keys.xml
+++ b/java/res/values-am/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"ቀዳሚ"</string>
<string name="label_done_key" msgid="7564866296502630852">"ተደርጓል"</string>
<string name="label_send_key" msgid="482252074224462163">"ላክ"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"ቆም በል"</string>
<string name="label_wait_key" msgid="5891247853595466039">"ጠብቅ"</string>
</resources>
diff --git a/java/res/values-am/strings-talkback-descriptions.xml b/java/res/values-am/strings-talkback-descriptions.xml
index 2d6f0e56d..1b1da01e5 100644
--- a/java/res/values-am/strings-talkback-descriptions.xml
+++ b/java/res/values-am/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"ምንም ፅሁፍ አልገባም"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>ን ወደ <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> ያርመዋል"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> የራስ ሰር እርማት ያከናውናል"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"የቁልፍ ኮድ %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"ቀይር"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"መቀያየሪያ ቁልፍ በርቷል (ለማሰናከል መታ ያድርጉ)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"አብይ ፊደል ማድረጊያ ቁልፍ በርቷል (ለማሰናክል ነካ ያድርጉ)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"ተጨማሪ ምልክቶች"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"ምልክቶች"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"ሰርዝ"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"ምልክቶች"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"ደብዳቤዎች"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"ቀዳሚ"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"መቀያየሪያ ቁልፍ ነቅቷል"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"አብይ ፊደል ማድረጊያ ቁልፍ ነቅቷል"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"መቀያየሪያ ቁልፍ ተሰናክሏል"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"የምልክቶች ሁኔታ"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"የተጨማሪ ምልክቶች ሁነታ"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"የደብዳቤዎች ሁኔታ"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"የስልክ ሁኔታ"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"የስልክ ምልክቶች ሁኔታ"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"ቦታዎች"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"ምልክቶች"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"ስሜት ገላጭ አዶዎች"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-am/strings.xml b/java/res/values-am/strings.xml
index 32eed413b..f957d1111 100644
--- a/java/res/values-am/strings.xml
+++ b/java/res/values-am/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"ግቤት አማራጮች"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"የጥናት የምዝግብ ማስታወሻ ትዕዛዞች"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"የእውቅያ ስሞችን ተመልከት"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"ፊደል አራሚ ከእውቅያ ዝርዝርህ የገቡትን ይጠቀማል"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"በቁልፍመጫንጊዜ አንዝር"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"የዕውቂያ ስም ጠቁም"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"ከዕውቂያዎች ለጥቆማዎች እና ማስተካከያዎች ስሞች ተጠቀም"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"ግላዊ የጥቆማ አስተያየቶች"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"የድርብ-ክፍተት ነጥብ"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"የክፍተት አሞሌው ላይ ሁለቴ መታ ማድረግ አንድ ነጥብ እና ክፍተት አስከትሎ ያስገባል"</string>
<string name="auto_cap" msgid="1719746674854628252">"ራስ-ሰር አቢይ ማድረግ"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"ቋንቋዎች አግቤት"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"ለማስቀመጥ እንደገና ንካ"</string>
<string name="has_dictionary" msgid="6071847973466625007">"መዝገበ ቃላት አለ"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"የተጠቃሚ ግብረ ምላሽ አንቃ"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"አጠቃቀም ስታስቲክስ እና የብልሽት ሪፖርቶችን በራስ-ሰር በመላክ ይህን ግቤት ስልት አርታዒ እንዲሻሻል ያግዙ።"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"የቁልፍ ሰሌዳ ገጽታ"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"እንግሊዘኛ (የታላቋ ብሪታንያ)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"እንግሊዘኛ (ዩ.ኤስ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"አንቃ"</string>
<string name="not_now" msgid="6172462888202790482">"አሁን አልፈልግም"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"ተመሳሳዩ የግብዓት ቅጥ አስቀድሞ አለ፦ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"የተገልጋይነት ጥናት ሁነታ"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"የሰሌዳ ቁልፍ ጠቅታ በመጫን መዘግየት"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"የቁልፍ ጭነት ንዝረት ርዝመት"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"የቁልፍ ጭነት ድምጽ መጠን"</string>
diff --git a/java/res/values-ar/strings-action-keys.xml b/java/res/values-ar/strings-action-keys.xml
index 481b22f20..1ee4f7a2d 100644
--- a/java/res/values-ar/strings-action-keys.xml
+++ b/java/res/values-ar/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"سابق"</string>
<string name="label_done_key" msgid="7564866296502630852">"تم"</string>
<string name="label_send_key" msgid="482252074224462163">"إرسال"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"توقف"</string>
<string name="label_wait_key" msgid="5891247853595466039">"انتظر"</string>
</resources>
diff --git a/java/res/values-ar/strings-talkback-descriptions.xml b/java/res/values-ar/strings-talkback-descriptions.xml
index 9d2eab5ae..b39033a85 100644
--- a/java/res/values-ar/strings-talkback-descriptions.xml
+++ b/java/res/values-ar/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"لم يتم إدخال نص"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> لتصحيح <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> إلى <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> لإجراء التصحيح التلقائي"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"‏رمز المفتاح %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"‏Shift يعمل (انقر للتعطيل)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"‏Caps lock يعمل (انقر للتعطيل)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"المزيد من الرموز"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"رموز"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"حذف"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"رموز"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"أحرف"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"السابق"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"‏تم تمكين Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"‏تم تمكين Caps lock"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"‏تم تعطيل Shift"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"وضع الرموز"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"المزيد من وضع الرموز"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"وضع الأحرف"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"وضع الهاتف"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"وضع رموز الهاتف"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"أماكن"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"رموز"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"رموز تعبيرية"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ar/strings.xml b/java/res/values-ar/strings.xml
index 13aef2a67..111b5af51 100644
--- a/java/res/values-ar/strings.xml
+++ b/java/res/values-ar/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"خيارات الإرسال"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"أوامر سجلات البحث"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"بحث في أسماء جهات الاتصال"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"يستخدم المدقق الإملائي إدخالات من قائمة جهات الاتصال"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"اهتزاز عند ضغط مفتاح"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"اقتراح أسماء جهات الاتصال"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"استخدام الأسماء من جهات الاتصال للاقتراحات والتصحيحات"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"اقتراحات مخصصة"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"نقطة المسافة المزدوجة"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"يؤدي النقر نقرًا مزدوجًا على مفتاح المسافة إلى إدخال نقطة متبوعة بمسافة"</string>
<string name="auto_cap" msgid="1719746674854628252">"أحرف كبيرة تلقائيًا"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"لغات الإدخال"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"المس مرة أخرى للحفظ"</string>
<string name="has_dictionary" msgid="6071847973466625007">"القاموس متاح"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"تمكين ملاحظات المستخدم"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"المساعدة في تحسين محرر أسلوب الإدخال هذا من خلال إرسال إحصاءات الاستخدام وتقارير الأعطال تلقائيًا"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"مظهر لوحة المفاتيح"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"الإنجليزية (المملكة المتحدة)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"الإنجليزية (الولايات المتحدة)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"تمكين"</string>
<string name="not_now" msgid="6172462888202790482">"ليس الآن"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"نمط الإدخال ذاته موجود من قبل: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"وضع سهولة الاستخدام"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"تأخير الضغط الطويل للمفاتيح"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"مدة اهتزاز الضغط على المفاتيح"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"مستوى صوت الضغط على المفاتيح"</string>
diff --git a/java/res/values-az-rAZ/strings-action-keys.xml b/java/res/values-az-rAZ/strings-action-keys.xml
index 513712c40..7f982d686 100644
--- a/java/res/values-az-rAZ/strings-action-keys.xml
+++ b/java/res/values-az-rAZ/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Öncəki"</string>
<string name="label_done_key" msgid="7564866296502630852">"Hazırdır"</string>
<string name="label_send_key" msgid="482252074224462163">"Göndər"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauza"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Gözlə"</string>
</resources>
diff --git a/java/res/values-az-rAZ/strings-emoji-descriptions.xml b/java/res/values-az-rAZ/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..b6c259f73
--- /dev/null
+++ b/java/res/values-az-rAZ/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Müəllif hüququ nişanı"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Qeydiyyat nişanı"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"İki nida işarəsi"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Suallı nida işarəsi"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Ticarət nişanı"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"İnformasiya mənbəyi"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Sola-sağa ox"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Yuxarı-aşağı ox"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Şimal-qərb ox"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Şimal-şərq ox"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Cənub-şərq ox"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Cənub-qərb ox"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Qırmaqlı sola ox"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Qırmaqlı sağa ox"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"İzləyin"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Qum saatı"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Qara sağa ikiqat üçbucaq"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Qara sola ikiqat üçbucaq"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Qara yuxarı ikiqat üçbucaq"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Qara aşağı ikiqat üçbucaq"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Zəngli saat"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Axan qumlu qum saatı"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Çərçivəli böyük latın M hərfi"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Kiçik qara kvadrat"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Kiçik ağ kvadrat"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Qara sağa uçbucaq"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Qara sola üçbucaq"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Ağ orta kvadrat"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Qara orta kvadrat"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Ağ orta kiçik kvadrat"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Qara orta kiçik kvadrat"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Şüalı qara günəş"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Bulud"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Qara telefon"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Qeydli səsvermə qutusu"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Yağışlı çətir"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"İsti içki"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Yuxarı göstərən barmaq"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Ağ gülümsəyən sima"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Qoç"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Buğa"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Əkizlər"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Xərçəng"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Şir"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Qız"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Tərəzi"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Əqrəb"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Oxatan"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Oğlaq"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Dolça"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Balıqlar"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Qara nizə"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Qara xaç"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Qara ürək"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Qara romb"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"İsti bulaqlar"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Qara universal təkrar istifadə simvolu"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Təkərli kreslo"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Lövbər"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Xəbərdarlıq işarəsi"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Yüksək voltaj simvolu"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Orta ağ çevrə"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Orta qara çevrə"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Futbol topu"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Beysbol"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Qarsız qar adamı"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Bulud arxasında günəş"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"İlantutan"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Giriş qadağası"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Kilsə"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Fəvvarə"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Deşikdə bayraq"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Yeklənli qayıq"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Çadır"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Yanacaq nasosu"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Qara qayçı"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Ağ qalın qeyd nişanı"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Təyyarə"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Zərf"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Qaldırılmış yumruq"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Qaldırılmış əl"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Qələbə əli"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Karandaş"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Qara pero"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Qalın qeyd nişanı"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Qalın x vurma işarəsi"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Qığılcımlar"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Səkkiz guşəli ulduz"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Səkkiz guşəli qara ulduz"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Qar dənəsi"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Qığılcım"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Çarpaz nişan"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Mənfi kvadratlı çarpaz nişan"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Qara sual işarəsi ornamenti"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Ağ sual işarəsi ornamenti"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Ağ nida işarəsi ornamenti"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Qalın nida işarəsi"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Yüklü qara ürək"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Qalın toplama işarəsi"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Qalın çıxma işarəsi"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Qalın bölmə işarəsi"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Qara sağa ox"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Burulmuş halqa"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"İki dəfə burulmuş halqa"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Yuxarı sağa əyilən ox"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Aşağı sağa əyilən ox"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Qara sola ox"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Qara yuxarı ox"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Qara aşağı ox"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Qara böyük kvadrat"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Ağ böyük kvadrat"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Ağ orta ulduz"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Böyük qalın çevrə"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Dalğalı tire"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Qismən dəyişmə işarəsi"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Çevrəli təbrik ideoqramı"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Çevrəli sirr ideoqramı"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Mahconq plitəsi qırmızı əjdaha"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Kart oyunu qara coker"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"A qan növü"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"B qan növü"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"O qan növü"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Parkinq yeri"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"AB qan növü"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"Kvadrat CL"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Kvadrat kul"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Kvadrat azad"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"Kvadrat ID"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"Kvadrat yeni"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"Kvadrat N G"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"Kvadrat OK"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"Kvadrat SOS"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"Nidalı kvadrat"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"Kvadrat vs"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Burada kvadrat katakana"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Kvadrat katakana xidməti"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Ödənişsiz kvadrat ideoqram"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Rezerv edilmiş yer kvadrat ideoqram"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Kvadrat qadağa ideoqramı"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Kvadrat vakansiya ideoqramı"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Kvadrat qəbul ideoqramı"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Kvadrat tam məşğulluq ideoqramı"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Kvadrat ödənilmiş ideoqramı"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Aylıq kvadrat ideoqram"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Kvadrat tətbiq ideoqramı"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Kvadrat endirim ideoqramı"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Kvadrat biznes ideoqramı"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Çevrəli üstünlük ideoqramı"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Çevrəli qəbul ideoqramı"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Siklon"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Dumanlı"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Bağlı çətir"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Ulduzlu gecə"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Dağların arxasından doğan günəş"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Günəşin doğuşu"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Toranlıqda şəhər peyzajı"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Binaların arxasında günün batması"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Göy qurşağı"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Gecə vaxtı körpü"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Su dalğası"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Vulkan"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Samanyolu"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Avropa-Afrika Yer Qlobusu"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Amerika Yer Qlobusu"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Asiya-Avstraliya Yer Qlobusu"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Meridianlı qlobus"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Yeni ay simvolu"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Böyüyən aypara simvolu"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"İlk rüb ay simvolu"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Böyüyən yumru ay simvolu"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Tam ay simvolu"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Kiçilən yumru ay simvolu"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Son rüb ay simvolu"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Kiçilən aypara simvolu"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Aypara"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Simalı yeni ay"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Simalı ilk rüb ayı"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Simalı son rüb ayı"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Simalı tam ay"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Simalı günəş"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Parlaq ulduz"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Düşən ulduz"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Şabalıd"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Fidan"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Həmişəyaşıl ağac"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Yarpaqlı ağac"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Palma ağacı"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Kaktus"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Zanbaq"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Albalı çiçəyi"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Qızılgül"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Əməköməci"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Günəbaxan"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Çiçək"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Qarğıdalı qıçası"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Düyü qıçası"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Ot"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Dörd yarpaqlı yonca"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Ağcaqayın yarpağı"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Düşmüş yarpaq"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Xəzan yarpağı"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Göbələk"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Pomidor"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Badımcan"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Üzüm"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Yemiş"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Qarpız"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Mandarin"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Lemon"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Banan"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Ananas"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Qırmızı alma"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Yaşıl alma"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Armud"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Şaftalı"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Albalı"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Çiyələk"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Hamburger"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Pizza dilimi"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Sümüklü ət"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Quş ayağı"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Düyü krekeri"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Düyü küftəsi"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Bişmiş düyü"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Karri və düyü"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Buxarlanan kasa"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Spagetti"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Çörək"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Fransızsayağı kartof"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Qovrulmuş şirin kartof"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Danqo"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oden"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Suşi"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Qızardılmış krevet"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Burulğan dizaynlı balıq piroqu"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Yumşaq dondurma"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Buz deserti"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Dondurma"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Ponçik"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Kökə"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Şokolad batonu"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Konfet"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Nabat"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Bişmiş krem"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Bal dibçəyi"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Dənəvər peçenye"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Bento qutusu"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Qazan"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Yeməkbişirmə"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Çəngəl-bıçaq"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Qulpsuz fincan"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Sake şüşəsi və fincan"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Şərab şüşəsi"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Kokteyl şüşəsi"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Tropik içki"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Pivə parçı"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Cingildəyən pivə parçları"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Uşaq qidası üçün şüşə"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Lent"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Bükülmüş hədiyyə"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Doğum günü tortu"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Jack fənəri"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Milad yolkası"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Şaxta Baba"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Fişəng"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Benqal odu fişəngi"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Şar"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Parti fişəngi"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Konfetti topu"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Tanabata ağacı"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Çarpaz bayraqlar"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Küknar dekorasiyası"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Yapon kuklaları"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Karp strimer"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Külək uğultusu"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Aya tamaşa mərasimi"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Məktəb çantası"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Akademik papaq"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Karusel at"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Mənzərə çarxı"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Dalğalı yelləncək"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Qırmaq və balıq"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Mikrofon"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Film kamerası"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Kino"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Qulaqlıq"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Rəssam palitrası"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Sehrbaz papağı"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Sirk çadırı"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Bilet"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Çəkiliş lövhəsi"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Tətbiqi incəsənət"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Video oyun"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Birbaşa zərbə"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Oyun avtomatı"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Bilyard"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Zər oyunu"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Boulinq"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Güllü oyun kartları"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Musiqili qeyd"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Çoxsaylı musiqili qeyd"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Saksafon"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Gitara"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Musiqili klaviatura"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Truba"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Skripka"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Musiqi qiyməti"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Kəmərli qaçış köynəyi"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Tennis raketi və topu"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Xizək və xizək çəkməsi"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Basketbol və çənbər"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Dama-dama bayraq"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Snoubordçu"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Qaçışçı"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Sörfçü"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Kubok"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"At yarışması"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Amerikan futbolu"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Reqbi Futbolu"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Üzgüçü"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Ev tikintisi"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Bağçalı ev"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Ofis binası"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Yapon poçt ofisi"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Avropa poçt ofisi"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Hospital"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Bank"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Bankomat"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Otel"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Sevgi oteli"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Qarışıq mallar dükanı"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Məktəb"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Univermaq"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Zavod"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Izakaya fənəri"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Yapon qalası"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Avropa qalası"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Siçovul"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Siçan"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Öküz"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Su camışı"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"İnək"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Leopard"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Dovşan"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Pişik"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Əjdaha"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Timsah"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Balina"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"İlbiz"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"İlan"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"At"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Qoç"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Keçi"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Qoyun"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Meymun"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Xoruz"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Cücə"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"İt"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Donuz"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Qaban"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Fil"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Osminoq"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"İlbiz qabığı"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Böcək"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Qarışqa"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Bal arısı"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Parabüzən"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Balıq"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Tropik balıq"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Şar balığı"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Tısbağa"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Yumurtadan çıxan cücə"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Balaca cücə"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Önə baxan balaca cücə"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Quş"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Pinqvin"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Koala"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Pudel"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Bir hörgüclü dəvə"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"İki hörgüclü dəvə"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Delfin"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Siçan sifəti"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"İnək sifəti"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Pələng sifəti"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Dovşan sifəti"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Pişik sifəti"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Əjdaha sifəti"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Fontan vuran balina"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"At sifəti"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Meymun sifəti"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"İt sifəti"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Donuz sifəti"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Qurbağa sifəti"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Xomyak sifəti"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Canavar sifəti"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Ayı sifəti"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Panda sifəti"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Donuz burnu"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Pəncə izləri"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Gözlər"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Qulaq"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Burun"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Ağız"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Dil"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Yuxarı işarə edən ağ rəngli əl indeksi"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Aşağı işarə edən ağ rəngli əl indeksi"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Sola işarə edən ağ rəngli əl indeksi"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Sağa işarə edən ağ rəngli əl indeksi"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Yumruq işarəsi"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Yellənən əl işarəsi"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"Ok əl işarəsi"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Yuxarı baş barmaq işarəsi"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Aşağı baş barmaq işarəsi"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Çalan əllər işarəsi"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Açıq əllər işarəsi"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Tac"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Qadın papağı"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Eynək"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Qalstuk"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"Qısaqol köynək"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Cins"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Don"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Kimono"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Bikini"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Qadın geyimi"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Pulqabı"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Çanta"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Kisə"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Kişi ayaqqabısı"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"İdmançı ayaqqabısı"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Dikdaban ayaqqabı"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Qadın sandalı"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Qadın çəkməsi"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Ayaq izi"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Büst silueti"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Büst siluetləri"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Oğlan"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Qız"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Kişi"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Qadın"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Ailə"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Qadın və kişi əl-ələ tutur"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"İki kişi əl-ələ tutur"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"İki qadın əl-ələ tutur"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Polis içşisi"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Dövşanqulaq qadın"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Duvaqlı gəlin"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Sarı saçlı adam"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Qua pi maolu kişi"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Çalmalı kişi"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Yaşlı kişi"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Yaşlı qadın"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Uşaq"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Fəhlə"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Şahzadə"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Yapon oqru"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Yapon qoblini"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Ruh"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Uşaq mələk"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Yad planetli"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Yad planetli qulyabani"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"İmp"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Kəllə"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Qəbul bölməsi adamı"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Keşikçi"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Rəqqas"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Dodaq boyası"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Dırnaq boyası"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Üz masajı"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Saç düzümü"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Bərbərxana"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Şpris"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Həb"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Öpüş izi"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Sevgi məktubu"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Zəng"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Qiymətli daş"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Öpüş"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Buket"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Ürəkli cütlük"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Toy"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Ürək döyüntüsü"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Sınmış qəlb"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"İki ürək"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Parlaq ürək"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Böyüyən ürək"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Oxlu ürək"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Göy ürək"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Yaşıl ürək"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Sarı ürək"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Bənövşəyi ürək"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Lentli ürək"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Fırlanan ürək"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Ürək bəzəyi"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Nöqtəli brilliant"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Elektrik lampası"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Hirs simvolu"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Bomba"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Yuxu işarəsi"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Partlayış"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Tər işarəsi"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Damcı"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Tire simvolu"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Kakaşka"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Biseps əzələ"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Başgicəllənmə"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Nitq balonu"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Fikir balonu"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Ağ gül"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Yüz xal simvolu"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Pul kisəsi"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Valyuta mübadiləsi"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Ağır dollar işarəsi"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Kredit kartı"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Yen işarəli əskinaz"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Dollar nişanlı əskinaz"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Avro işarəli əskinaz"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Funt işarəli əskinaz"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Qanadlı pul"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Qalxan diaqram və yen işarəsi"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Oturacaq"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Şəxsi kompüter"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Portfel"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Mini disk"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Disket"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Optik disk"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Fayl qovluğu"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Açıq fayl qovluğu"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Qatlanmış səhifə"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Səhifə"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Təqvim"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Qoparılan təqvim"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Kart indeksi"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Qalxan diaqram"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Düşən diaqram"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Panel diaqramı"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Pano"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Basmadüymə"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Yumru basmadüymə"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Skrepka"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Düz xətkeş"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Üçbücaq xətkeş"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Əlfəcin tabları"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Qovluq"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Bloknot"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Bəzəkli bloknot"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Qapalı kitab"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Açıq kitab"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Yaşıl kitab"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Göy kitab"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Narıncı kitab"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Kitablar"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Ad kartı"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Tomar"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Memo"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Telefon qəbuledici"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Peycer"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Faks cihazı"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Peyk antennası"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Dinamik səsyüksəldici"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Səsyüksəldici"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Göndəriləcək sənəd siyirməsi"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Gələn sənəd siyirməsi"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Paket"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"E-poçt simvolu"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Gələn zərf"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Üstündə aşağı ox olan zərf"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Enmiş bayraqlı qapalı poçt qutusu"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Qalxmış bayraqlı qapalı poçt qutusu"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Qalxmış bayraqlı açıq poçt qutusu"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Enmiş bayraqlı açıq poçt qutusu"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Poçt qutusu"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Poçt buynuzu"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Qəzet"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Mobil telefon"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Solunda sağa oxlu mobil telefon"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Vibrasiya rejimi"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Sönmüş mobil telefon"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Mobil telefon qadağası"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Şəbəkə dalğası"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Kamera"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Videokamera"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Televiziya"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Radio"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Videokasset"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Sağa əyilmiş oxlar"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Saat əqrəbi istiqamətində sağa və sola açıq çevrəli oxlar"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Çevrəyə alınmış saat əqrəbi istiqamətində sağa və sola açıq çevrəli oxlar"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Saat əqrəbi istiqamətində aşağı və yuxarı açıq çevrəli oxlar"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Saat əqrəbi istiqaməti əksinə aşağı və yuxarı açıq çevrəli oxlar"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Alçaq parlaqlıq simvolu"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Yüksək parlaqlıq simvolu"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Ləğv edilmə xətli dinamik"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Dinamik"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Bir xətli dinamik"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Üç xətli dinamik"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Batareya"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Elektrik ştepseli"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Sola əyilmiş lupa"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Sağa əyilmiş lupa"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Dolma qələmli kilid"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Açarlı bağlı kilid"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Açar"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Kilid"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Açıq kilid"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Zəng"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Ləğv edilmiş zəng"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Əlfəcin"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Link simvolu"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Radio düyməsi"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Üzərində sola ox olan back simvolu"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"Üzərində sola ox olan end simvolu"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"Üzərində sola sağa ox olan nida işarəli on simvolu"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Üzərində sağa ox olan soon simvolu"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Üzərində yuxarı ox olan top simvolu"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"On səkkiz yaşdan aşağı qadağası"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Klaviş qapağı on"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Böyük latın hərfləri üçün daxiletmə simvolu"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Kiçik latın hərfləri üçün daxiletmə simvolu"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Rəqəmlər üçün daxiletmə simvolu"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Simvollar üçün daxiletmə simvolu"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Latın hərfləri üçün daxiletmə simvolu"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Alov"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Cib fənəri"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Qaz açarı"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Çəkic"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Bolt və qayka"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Hoço"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Tapança"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Mikroskop"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Teleskop"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Büllur kürə"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Ortasında nöqtə olan altı guşəli ulduz"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Başlayan üçün yapon simvolu"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Üçdişli emblem"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Qara kvadrat düyməsi"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Ağ kvadrat düyməsi"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Böyük qırmızı çevrə"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Böyük göy çevrə"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Böyük narıncı brilliant"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Böyük göy brilliant"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Kiçik narıncı brilliant"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Kiçik göy brilliant"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Yuxarı göstərən qırmızı üçbucaq"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Aşağı göstərən qırmızı üçbucaq"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Yuxarı göstərən kiçik qırmızı üçbucaq"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Aşağı göstərən kiçik qırmızı üçbucaq"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Saat bir"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Saat iki"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Saat üç"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Saat dörd"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Saat beş"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Saat altı"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Saat yeddi"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Saat səkkiz"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Saat doqquz"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Saat on"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Saat on bir"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Saat on iki"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Saat ikinin yarısı"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Saat üçün yarısı"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Saat dördün yarısı"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Saat beşin yarısı"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Saat altının yarısı"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Saat yeddinin yarısı"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Saat səkkizin yarısı"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Saat doqquzun yarısı"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Saat onun yarısı"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Saat on birin yarısı"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Saat on ikinin yarısı"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Saat birin yarısı"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Fudzi dağı"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Tokio qülləsi"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Azadlıq heykəli"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Yaponiya silueti"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Moyai"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Gülümsəyən gözlərlə sima"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Sevinc göz yaşları ilə sima"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Açıq ağızla gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Açıq ağızlı, gülən gözlərlə gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Açıq ağızlı, soyuq tərli gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Açıq ağızlı, qapalı gözlü gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Nimbalı gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Buynuzlu gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Göz vuran sima"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Gülən gözlərlə gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Dadlı yemək yeyən sima"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Azad sima"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Ürək formalı gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Gün eynəkli gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Oğruncasına gülümsəyən sima"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Neytral sima"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"İfadəsiz sima"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Bezmiş sima"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Soyuq tərli sima"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Fikirli sima"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Çaşqın sima"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Məəttəl sima"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Öpən sima"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Öpüş atan sima"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Gülən gözlərlə öpən sima"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Bağlı gözlərlə öpən sima"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Dil çıxaran sima"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Dil çıxaran və göz vuran sima"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Qapalı gözlərlə dil çıxaran sima"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Məyus sima"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Narahat sima"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Hirsli sima"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"İncimiş sima"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Ağlayan sima"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"İnadlı sima"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Triumf baxışlı sima"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Məyus, lakin azad sima"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Mısmırıqlı sima"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Ağrılı sima"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Qorxan sima"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Bezmiş sima"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Yuxulu sima"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Yorğun sima"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Qırışdırılmış sima"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Hönkür-hönkür ağlayan sima"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Açıq ağızlı sima"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Susmağa məcbur sima"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Açıq ağızlı soyuq tərli sima"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Qorxudan qışqıran sima"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Heyran sima"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Qızarmış sima"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Yatan sima"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Gicəllənən sima"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Ağızsız sima"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Tibbi maskalı sima"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Gülən gözlərlə oğrun gülümsəyən pişik siması"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Sevinc göz yaşları ilə pişik siması"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Açıq ağızlı gülümsəyən pişik siması"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Ürəkli gözlərlə gülümsəyən pişik siması"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"İkrahlı təbəssümlü pişik siması"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Bağlı gözlərlə öpən pişik siması"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"İncimiş pişik siması"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Ağlayan pişik siması"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Bezmiş pişik siması"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Qadağa jestl sima"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Ok jestli sima"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Baş əyən adam"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Gözünü tutmuş meymun"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Qulağını tutmuş meymun"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Ağzını tutmuş meymun"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Əlini qaldırmış xoşbəxt adam"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Mərasimdə əllərini qaldırmış adam"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Mısmırıqlı adam"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"İncimiş adam"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Əllərini birləşdirmiş adam"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Raket"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Helikopter"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Parovoz"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Dəmiryol maşını"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Sürətli qatar"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Gülləburun sürətli qatar"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Qatar"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metro"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Monorels"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Stansiya"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Tramvay"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Tramvay avtomobil"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Avtobus"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Gələn avtobus"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Trolleybus"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Avtobus dayanacağı"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Minibus"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulans"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Yanğınsöndürən maşın"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Polis maşını"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Gələn polis maşını"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Taksi"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Gələn taksi"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Avtomobil"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Gələn avtomobil"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Rahatlıq avtomobili"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Yükdaşıyan maşın"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Avtoqatar"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Traktor"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Monorels"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Dağ dəmir yolu"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Asma dəmiryol"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Dağ kabel yolu"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Asma kanat yolu"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Gəmi"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Avarlı qayıq"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Sürətli qayıq"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Horizontal svetofor"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Vertikal işıqfor"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Tikinti nişanı"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Yanar mayaklı polis maşınları"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Poçtda üçbucaq bayraq"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Qapı"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Giriş qadağası siqnalı"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Siqaret çəkmək simvolu"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Siqaret qadağası simvolu"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Zibili zibil yeşiyinə atmaq simvolu"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Zibilləmək qadağası simvolu"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"İçməli su simvolu"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Texniki su simvolu"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Velosiped"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Velosiped qadağası"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Velosipedçi"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Dağ velosipedçisi"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Piyada"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Piyada qadağası"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Yol keçən uşaqlar"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Kişi simvolu"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Qadın simvolu"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Dincəlmə otağı"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Uşaq simvolu"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Tualet"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"Unitaz"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Duş"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Hamam"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Vanna"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Pasport nəzarəti"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Gömrük"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Baqaj iddiası"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Qalmış baqaj"</string>
+</resources>
diff --git a/java/res/values-az-rAZ/strings-talkback-descriptions.xml b/java/res/values-az-rAZ/strings-talkback-descriptions.xml
index c5abc5cf5..8ba8a6e7d 100644
--- a/java/res/values-az-rAZ/strings-talkback-descriptions.xml
+++ b/java/res/values-az-rAZ/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Mətn daxil edilməyib"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> sözünü <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> sözü ilə əvəzləyərək düzəldir"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> avto-korreksiyanı həyata keçirir"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"%d açar kodu"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Sürüşdürmə"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Sürüşdürmə aktivdir (deaktiv etmək üçün klikləyin)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Böyük hərf kilidi aktivdir (deaktiv etmək üçün klikləyin)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Daha çox simvol"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Sürüşdürmə"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simvollar"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Sürüşdürmə"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Sil"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simvollar"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Hərflər"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Əvvəlki"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Sürüşdürmə aktivdir"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Böyük hərf kilidi aktivdir"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Sürüşdürmə deaktivdir"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Simvol rejimi"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Daha çox simvol rejimi"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Hərf rejimi"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefon rejimi"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefon simvol rejimi"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Yerlər"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simvollar"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikonlar"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-az-rAZ/strings.xml b/java/res/values-az-rAZ/strings.xml
index 5a40e9f14..bf3990d6e 100644
--- a/java/res/values-az-rAZ/strings.xml
+++ b/java/res/values-az-rAZ/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Daxiletmə seçimləri"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Araşdırma Jurnalı Əmrləri"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontakt adlarına baxın"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Orfoqrafik yoxlanış kontakt siyahınızdakı qeydlərdən istifadə edir"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrasiyalı klikləmə"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Kontakt adları təklif edin"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Təklif və korreksiya üçün Kontaktlardakı adlardan istifadə edin"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Fərdiləşmiş təkliflər"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"İkili boşluq periodu"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluqdakı iki klik boşluqdan sonra pauza daxil edir"</string>
<string name="auto_cap" msgid="1719746674854628252">"Avtomatik böyük hərfləşmə"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Daxiletmə dilləri"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Yadda saxlamaq üçün yenidən toxunun"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Lüğət mövcuddur"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"İstifadəçi əks əlaqəsini aktiv et"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"İstifadə statistikası və xəta haqqında hesabatları avtomatik göndərməklə daxiletmə metodu redaktəsini təkmilləşdirməyə kömək edin."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klaviatura teması"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"İngilis (BK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"İngilis (ABŞ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktiv et"</string>
<string name="not_now" msgid="6172462888202790482">"İndi yox"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Eyni daxiletmə üslubu artıq mövcuddur: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Rahat işləmə rejimi"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Klavişi uzun müddət basmada gecikmə"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrasiyalı klikləmə müddəti"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Səsli klikləmə səsi"</string>
diff --git a/java/res/values-bg/strings-action-keys.xml b/java/res/values-bg/strings-action-keys.xml
index 13374a29c..3d295bba4 100644
--- a/java/res/values-bg/strings-action-keys.xml
+++ b/java/res/values-bg/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Назад"</string>
<string name="label_done_key" msgid="7564866296502630852">"Готово"</string>
<string name="label_send_key" msgid="482252074224462163">"Изпр."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Пауза"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Изчакв."</string>
</resources>
diff --git a/java/res/values-bg/strings-talkback-descriptions.xml b/java/res/values-bg/strings-talkback-descriptions.xml
index c944c579f..edd74b52c 100644
--- a/java/res/values-bg/strings-talkback-descriptions.xml
+++ b/java/res/values-bg/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Няма въведен текст"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"„<xliff:g id="KEY_NAME">%1$s</xliff:g>“ коригира „<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>“ на „<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>“"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"„<xliff:g id="KEY_NAME">%1$s</xliff:g>“ изпълнява автоматично коригиране"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Код на клавишa %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"„Shift“ е включен (докоснете за деактивиране)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"„Caps lock“ е включен (докоснете за деактивиране)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Още символи"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Символи"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Delete"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Символи"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Букви"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Назад"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"„Shift“ е активиран"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"„Caps Lock“ е активиран"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"„Shift“ е деактивиран"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Режим за символи"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Режим с още символи"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Режим за букви"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Режим за телефонни номера"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Режим за символи на телефона"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Места"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Символи"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Емотикони"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-bg/strings.xml b/java/res/values-bg/strings.xml
index 562e71b4f..96c3a9560 100644
--- a/java/res/values-bg/strings.xml
+++ b/java/res/values-bg/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Опции за въвеждане"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Команди за рег. файл за проучвания"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Търсене на имена"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"За проверка на правописа се ползват записи от списъка с контакти"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Да вибрира при натискане на клавиш"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Предложения за контакти"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Използване на имена от „Контакти“ за предложения и поправки"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Персонализ. предложения"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Точка чрез двоен интервал"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Двукр. докосване на клав. за интервал вмъква точка, следвана от интервал"</string>
<string name="auto_cap" msgid="1719746674854628252">"Автоматично поставяне на главни букви"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Езици за въвеждане"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Докоснете отново, за да запазите"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Има достъп до речник"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Активиране на отзивите от потребителите"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Помогнете за подобряването на този редактор за въвеждане чрез автоматично изпращане на статистически данни за употребата и сигнали за сривове"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема на клавиатурата"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"английски (Великобритания)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"английски (САЩ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Активиране"</string>
<string name="not_now" msgid="6172462888202790482">"Не сега"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Същият стил на въвеждане вече съществува: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за изучаване на използваемостта"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Забавяне при продълж. натискане"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Продълж. на вибриране при натискане"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Сила на звука при натиск. на клавиш"</string>
diff --git a/java/res/values-ca/strings-action-keys.xml b/java/res/values-ca/strings-action-keys.xml
index 9dcf219cc..5dcf4a337 100644
--- a/java/res/values-ca/strings-action-keys.xml
+++ b/java/res/values-ca/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Ant."</string>
<string name="label_done_key" msgid="7564866296502630852">"Fet"</string>
<string name="label_send_key" msgid="482252074224462163">"Envia"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Atura"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Esp."</string>
</resources>
diff --git a/java/res/values-ca/strings-talkback-descriptions.xml b/java/res/values-ca/strings-talkback-descriptions.xml
index 389200b43..5bbf65571 100644
--- a/java/res/values-ca/strings-talkback-descriptions.xml
+++ b/java/res/values-ca/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"No s\'ha introduït cap text."</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corregeix <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> per <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> executa la correcció automàtica."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Clau de codi %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Maj"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Maj activat (toca per desactivar)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Bloq Maj activat (toca per desactivar)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Més símbols"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Maj"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Símbols"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Maj"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Suprimeix"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Símbols"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Lletres"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Maj activat"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Bloq Maj activat"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Maj desactivat"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Mode de símbols"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Mode de més símbols"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Mode de lletres"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Mode de telèfon"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Mode de símbols de telèfon"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Llocs"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Símbols"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticones"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ca/strings.xml b/java/res/values-ca/strings.xml
index e946ba78b..3c7e09237 100644
--- a/java/res/values-ca/strings.xml
+++ b/java/res/values-ca/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opcions d\'entrada"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Recerca d\'ordres de reg."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cerca noms de contactes"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"El corrector ortogràfic utilitza entrades de la llista de contactes"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibra en prémer tecles"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Suggereix noms de contactes"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilitza els noms de contactes per fer suggeriments i correccions"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Suggeriments personalitz."</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Punt amb doble espai"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Picar dues vegades la barra d\'espai insereix punt i espai blanc"</string>
<string name="auto_cap" msgid="1719746674854628252">"Majúscules automàtiques"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Idiomes d\'introducció"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Torna a tocar per desar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Diccionari disponible"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Activa els comentaris de l\'usuari"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Ajuda a millorar aquest editor de mètode d\'introducció de text mitjançant l\'enviament d\'estadístiques d\'ús i d\'informes d\'error."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclat"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglès (Regne Unit)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglès (EUA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Activa"</string>
<string name="not_now" msgid="6172462888202790482">"Ara no"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ja existeix aquest estil d\'entrada: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'estudi d\'usabilitat"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Retard en mantenir premut"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durada vibració en prémer"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volum del so en prémer tecles"</string>
diff --git a/java/res/values-cs/strings-action-keys.xml b/java/res/values-cs/strings-action-keys.xml
index e9545feca..0ff3506b5 100644
--- a/java/res/values-cs/strings-action-keys.xml
+++ b/java/res/values-cs/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Před."</string>
<string name="label_done_key" msgid="7564866296502630852">"Hot."</string>
<string name="label_send_key" msgid="482252074224462163">"Odes."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauza"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Čekat"</string>
</resources>
diff --git a/java/res/values-cs/strings-talkback-descriptions.xml b/java/res/values-cs/strings-talkback-descriptions.xml
index 7ba691c99..50cc984b9 100644
--- a/java/res/values-cs/strings-talkback-descriptions.xml
+++ b/java/res/values-cs/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Není zadán žádný text"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Klávesou <xliff:g id="KEY_NAME">%1$s</xliff:g> opravíte <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> na <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Klávesou <xliff:g id="KEY_NAME">%1$s</xliff:g> provedete automatickou opravu"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Kód klávesy %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Klávesa Shift je zapnutá (vypnete ji klepnutím)."</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Klávesa Caps Lock je zapnutá (vypnete ji klepnutím)."</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Další symboly"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboly"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Smazat"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboly"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Písmena"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Předchozí"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Klávesa Shift je aktivní"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Klávesa Caps Lock je aktivní"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Klávesa Shift je neaktivní"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Režim symbolů"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Režim dalších symbolů"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Režim písmen"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Režim telefonu"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Režim telefonních symbolů"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Místa"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboly"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikony"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-cs/strings.xml b/java/res/values-cs/strings.xml
index c093d8c50..98a9a13d6 100644
--- a/java/res/values-cs/strings.xml
+++ b/java/res/values-cs/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti zadávání textu a dat"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Příkazy vývoj. protokolu"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Vyhledat kontakty"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Kontrola pravopisu používá záznamy z vašeho seznamu kontaktů."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Při stisku klávesy vibrovat"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Navrhovat jména kontaktů"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Použít jména ze seznamu kontaktů k návrhům a opravám"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Personalizované návrhy"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Tečka dvojitým mezerníkem"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dvojím klepnutím na mezerník vložíte tečku následovanou mezerou."</string>
<string name="auto_cap" msgid="1719746674854628252">"Velká písmena automaticky"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Vstupní jazyky"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Opětovným dotykem provedete uložení"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Slovník k dispozici"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Aktivovat zasílání statistik užívání a zpráv o selhání"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Pomozte nám vylepšit tento editor pro zadávání dat automatickým zasíláním statistik využití a zpráv o selhání do Googlu."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Motiv klávesnice"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angličtina (Velká Británie)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angličtina (USA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Povolit"</string>
<string name="not_now" msgid="6172462888202790482">"Teď ne"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Tento styl zadávání již existuje: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim studie použitelnosti"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Prodleva dlouhého stisknutí"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Délka vibrace u stisku klávesy"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Hlasitost stisknutí klávesy"</string>
diff --git a/java/res/values-da/strings-action-keys.xml b/java/res/values-da/strings-action-keys.xml
index 757dc00d4..96021e5a9 100644
--- a/java/res/values-da/strings-action-keys.xml
+++ b/java/res/values-da/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Forr."</string>
<string name="label_done_key" msgid="7564866296502630852">"Udfør"</string>
<string name="label_send_key" msgid="482252074224462163">"Send"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Vent"</string>
</resources>
diff --git a/java/res/values-da/strings-talkback-descriptions.xml b/java/res/values-da/strings-talkback-descriptions.xml
index 2d613d6c7..b34650e8b 100644
--- a/java/res/values-da/strings-talkback-descriptions.xml
+++ b/java/res/values-da/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Der er ingen indtastet tekst"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> retter <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> til <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> udfører automatisk stavekontrol"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Tastekode %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift er aktiveret (tryk for at deaktivere)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock er slået til (tryk for at deaktivere)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Flere symboler"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift-tast"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboler"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift-tast"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Slet"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboler"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Bogstaver"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Forrige"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift er aktiveret"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock er aktiveret"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift er deaktiveret"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symboltilstand"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Tilstaden Flere symboler"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Bogstavtilstand"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefontilstand"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefonsymboltilstand"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Steder"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboler"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Humørikoner"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-da/strings.xml b/java/res/values-da/strings.xml
index 65025b7a8..d7a005be4 100644
--- a/java/res/values-da/strings.xml
+++ b/java/res/values-da/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Indstillinger for input"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Forskningslogkommandoer"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Anvend kontaktnavne"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Stavekontrollen bruger ord fra dine kontaktpersondata"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibration ved tastetryk"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå navne på kontakter"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Brug navne fra Kontaktpersoner til forslag og rettelser"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Tilpassede forslag"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"To mellemrum for punktum"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"To tryk på mellemrumstasten indsætter et punktum og et mellemrum"</string>
<string name="auto_cap" msgid="1719746674854628252">"Skriv automatisk med stort"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Inputsprog"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Tryk igen for at gemme"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Ordbog er tilgængelig"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Aktivér brugerfeedback"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Vær med til at forbedre dette redigeringsværktøj til indtastningsmetode ved automatisk at sende anvendelsesstatistikker og rapporter om nedbrud til Google."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engelsk (Storbritannien)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engelsk (USA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktivér"</string>
<string name="not_now" msgid="6172462888202790482">"Ikke nu"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Denne inputstil findes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tilstand for brugsstudie"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Forsinket langt tastetryk"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrationstid ved tastetryk"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Lydstyrke ved tastetryk"</string>
diff --git a/java/res/values-de/strings-action-keys.xml b/java/res/values-de/strings-action-keys.xml
index 95d3d7119..b55c2802f 100644
--- a/java/res/values-de/strings-action-keys.xml
+++ b/java/res/values-de/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Zurück"</string>
<string name="label_done_key" msgid="7564866296502630852">"Fertig"</string>
<string name="label_send_key" msgid="482252074224462163">"Senden"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Warten"</string>
</resources>
diff --git a/java/res/values-de/strings-talkback-descriptions.xml b/java/res/values-de/strings-talkback-descriptions.xml
index 9fef63208..3ae624370 100644
--- a/java/res/values-de/strings-talkback-descriptions.xml
+++ b/java/res/values-de/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Kein Text eingegeben"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Mit <xliff:g id="KEY_NAME">%1$s</xliff:g> wird \"<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>\" in \"<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>\" geändert."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Mit <xliff:g id="KEY_NAME">%1$s</xliff:g> erfolgt eine Autokorrektur."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Tastencode %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Umschalttaste"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Umschalttaste aktiviert (zum Deaktivieren berühren)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Feststelltaste aktiviert (zum Deaktivieren berühren)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Weitere Symbole"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift-Taste"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbole"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift-Taste"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Löschen"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbole"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Buchstaben"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Zurück"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Umschalttaste aktiviert"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Feststelltaste aktiviert"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Umschalttaste deaktiviert"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbolmodus"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modus \"Weitere Symbole\""</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Buchstabenmodus"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefonmodus"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefon-Symbolmodus"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Orte"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbole"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticons"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-de/strings.xml b/java/res/values-de/strings.xml
index f2074b762..d5bfec2b4 100644
--- a/java/res/values-de/strings.xml
+++ b/java/res/values-de/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Eingabeoptionen"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Forschungsprotokollbefehle"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontaktnamen prüfen"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Rechtschreibprüfung kann Einträge aus meiner Kontaktliste verwenden"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Bei Tastendruck vibrieren"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Kontakte vorschlagen"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen aus \"Kontakte\" als Vorschläge und Korrekturmöglichkeiten anzeigen"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Personalisierte Vorschläge"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Punkt plus Leerzeichen"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Für Punkt plus Leerzeichen zweimal auf die Leertaste tippen"</string>
<string name="auto_cap" msgid="1719746674854628252">"Autom. Groß-/Kleinschreibung"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Eingabesprachen"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Zum Speichern erneut berühren"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Wörterbuch verfügbar"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Nutzer-Feedback aktivieren"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Tragen Sie zur Verbesserung dieses Eingabemethodeneditors bei, indem Sie automatisch Nutzungsstatistiken und Absturzberichte senden."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastaturdesign"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Englisch (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Englisch (USA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktivieren"</string>
<string name="not_now" msgid="6172462888202790482">"Später"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Der gleiche Eingabestil ist bereits vorhanden: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Studie zur Benutzerfreundlichkeit"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Verzögerung für langes Drücken"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrationsdauer bei Tastendruck"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Tonlautstärke bei Tastendruck"</string>
diff --git a/java/res/values-el/strings-action-keys.xml b/java/res/values-el/strings-action-keys.xml
index a4093e3dc..8b5e395f0 100644
--- a/java/res/values-el/strings-action-keys.xml
+++ b/java/res/values-el/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Προηγούμενο"</string>
<string name="label_done_key" msgid="7564866296502630852">"Τέλος"</string>
<string name="label_send_key" msgid="482252074224462163">"Αποστολή"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Παύση"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Αναμονή"</string>
</resources>
diff --git a/java/res/values-el/strings-talkback-descriptions.xml b/java/res/values-el/strings-talkback-descriptions.xml
index 7393e630e..bb9875780 100644
--- a/java/res/values-el/strings-talkback-descriptions.xml
+++ b/java/res/values-el/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Δεν υπάρχει κείμενο"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> διορθώνει το <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> σε <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> εκτελεί αυτόματη διόρθωση"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Κωδικός πλήκτρου %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Το Shift είναι ενεργοποιημένο (πατήστε για απενεργοποίηση)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Το Caps lock είναι ενεργοποιημένο (πατήστε για απενεργοποίηση)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Περισσότερα σύμβολα"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Σύμβολα"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Διαγραφή"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Σύμβολα"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Γράμματα"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Προηγούμενο"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Το Shift είναι ενεργοποιημένο"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Το Caps lock είναι ενεργοποιημένο"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Το Shift είναι απενεργοποιημένο"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Λειτουργία συμβόλων"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Λειτουργία περισσότερων συμβόλων"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Λειτουργία γραμμάτων"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Λειτουργία τηλεφώνου"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Λειτουργία συμβόλων τηλεφώνου"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Μέρη"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Σύμβολα"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticon"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-el/strings.xml b/java/res/values-el/strings.xml
index 7f0e3f3d7..cfe652b2a 100644
--- a/java/res/values-el/strings.xml
+++ b/java/res/values-el/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Επιλογές εισόδου"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Έρευνα εντολών καταγραφής"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Αναζήτηση ονομάτων επαφών"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Ο ορθογρ. έλεγχος χρησιμοπ. καταχωρίσεις από τη λίστα επαφών σας"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Δόνηση κατά το πάτημα πλήκτρων"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Πρόταση ονομάτων επαφών"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Χρησιμοποιήστε ονόματα από τις Επαφές για προτάσεις και διορθ."</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Εξατομικευμένες προτάσεις"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Τελεία με διπλό πάτημα πλήκτρ.διαστ."</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Το διπλό πάτημα του πλήκτρ.διαστ. εισάγει μια τελεία και ένα κενό"</string>
<string name="auto_cap" msgid="1719746674854628252">"Αυτόματη χρήση κεφαλαίων"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Γλώσσες εισόδου"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Αγγίξτε ξανά για αποθήκευση"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Λεξικό διαθέσιμο"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Ενεργοποίηση σχολίων χρηστών"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Βοηθήστε μας να βελτιώσουμε αυτό το πρόγραμμα επεξεργασίας μεθόδου εισόδου, στέλνοντας αυτόματα στατιστικά στοιχεία και αναφορές σφαλμάτων."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Θέμα πληκτρολογίου"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Αγγλικά (Η.Β.)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Αγγλικά (Η.Π.Α)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Ενεργοποίηση"</string>
<string name="not_now" msgid="6172462888202790482">"Όχι τώρα"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Το ίδιο στυλ εισόδου υπάρχει ήδη: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Λειτουργία μελέτης χρηστικότητας"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Καθυστέρηση παρατεταμένου πατήματος πλήκτρου"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Διάρκεια δόνησης πατήμ. πλήκτ."</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Ένταση ήχου πατήματος πλήκτρου"</string>
diff --git a/java/res/values-en-rGB/strings-action-keys.xml b/java/res/values-en-rGB/strings-action-keys.xml
index 366cf3cdf..b8b02e149 100644
--- a/java/res/values-en-rGB/strings-action-keys.xml
+++ b/java/res/values-en-rGB/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Prev"</string>
<string name="label_done_key" msgid="7564866296502630852">"Finished"</string>
<string name="label_send_key" msgid="482252074224462163">"Send"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Wait"</string>
</resources>
diff --git a/java/res/values-en-rGB/strings-talkback-descriptions.xml b/java/res/values-en-rGB/strings-talkback-descriptions.xml
index c9393ee79..3956777ea 100644
--- a/java/res/values-en-rGB/strings-talkback-descriptions.xml
+++ b/java/res/values-en-rGB/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"No text entered"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrects <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> to <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> performs auto-correction"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Key code %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift on (tap to disable)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock on (tap to disable)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"More symbols"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbols"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Delete"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbols"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letters"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Previous"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift enabled"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock enabled"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift disabled"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbols mode"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"More symbols mode"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Letters mode"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Phone mode"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Phone symbols mode"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Places"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbols"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticons"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-en-rGB/strings.xml b/java/res/values-en-rGB/strings.xml
index 89e978925..0053a257c 100644
--- a/java/res/values-en-rGB/strings.xml
+++ b/java/res/values-en-rGB/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Input options"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Look up contact names"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Spell checker uses entries from your contact list"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on keypress"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Personalised suggestions"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Double-space full stop"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Double tap on spacebar inserts a full stop followed by a space"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Input languages"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Touch again to save"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Enable user feedback"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Help improve this input method editor by automatically sending usage statistics and crash reports"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Enable"</string>
<string name="not_now" msgid="6172462888202790482">"Not now"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Usability study mode"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Key long press delay"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Keypress vibration duration"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Keypress sound volume"</string>
diff --git a/java/res/values-en-rIN/strings-action-keys.xml b/java/res/values-en-rIN/strings-action-keys.xml
index 366cf3cdf..b8b02e149 100644
--- a/java/res/values-en-rIN/strings-action-keys.xml
+++ b/java/res/values-en-rIN/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Prev"</string>
<string name="label_done_key" msgid="7564866296502630852">"Finished"</string>
<string name="label_send_key" msgid="482252074224462163">"Send"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Wait"</string>
</resources>
diff --git a/java/res/values-en-rIN/strings-talkback-descriptions.xml b/java/res/values-en-rIN/strings-talkback-descriptions.xml
index c9393ee79..3956777ea 100644
--- a/java/res/values-en-rIN/strings-talkback-descriptions.xml
+++ b/java/res/values-en-rIN/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"No text entered"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrects <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> to <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> performs auto-correction"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Key code %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift on (tap to disable)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock on (tap to disable)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"More symbols"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbols"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Delete"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbols"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letters"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Previous"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift enabled"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock enabled"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift disabled"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbols mode"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"More symbols mode"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Letters mode"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Phone mode"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Phone symbols mode"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Places"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbols"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticons"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-en-rIN/strings.xml b/java/res/values-en-rIN/strings.xml
index 89e978925..0053a257c 100644
--- a/java/res/values-en-rIN/strings.xml
+++ b/java/res/values-en-rIN/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Input options"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Look up contact names"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Spell checker uses entries from your contact list"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrate on keypress"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Suggest Contact names"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Use names from Contacts for suggestions and corrections"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Personalised suggestions"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Double-space full stop"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Double tap on spacebar inserts a full stop followed by a space"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-capitalisation"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Input languages"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Touch again to save"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dictionary available"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Enable user feedback"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Help improve this input method editor by automatically sending usage statistics and crash reports"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Keyboard theme"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"English (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"English (US)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Enable"</string>
<string name="not_now" msgid="6172462888202790482">"Not now"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Usability study mode"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Key long press delay"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Keypress vibration duration"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Keypress sound volume"</string>
diff --git a/java/res/values-es-rUS/strings-action-keys.xml b/java/res/values-es-rUS/strings-action-keys.xml
index d375617f4..5921ff43d 100644
--- a/java/res/values-es-rUS/strings-action-keys.xml
+++ b/java/res/values-es-rUS/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Ant."</string>
<string name="label_done_key" msgid="7564866296502630852">"Listo"</string>
<string name="label_send_key" msgid="482252074224462163">"Env."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pausa"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Esp."</string>
</resources>
diff --git a/java/res/values-es-rUS/strings-talkback-descriptions.xml b/java/res/values-es-rUS/strings-talkback-descriptions.xml
index ab4979fc7..75fa14c2b 100644
--- a/java/res/values-es-rUS/strings-talkback-descriptions.xml
+++ b/java/res/values-es-rUS/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"No se ingresó texto."</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrige <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> por <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrige automáticamente."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Clave de código %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Mayúsculas"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Mayúsculas activado (presiona para desactivarlo)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Bloqueo de mayúsculas activado (presiona para desactivarlo)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Más símbolos"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Mayúscula"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Símbolos"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Mayúscula"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Eliminar"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Símbolos"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letras"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Mayúsculas activado"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Bloqueo de mayúsculas activado"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Mayúsculas desactivado"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Modo Símbolos"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modo de más símbolos"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Modo Letras"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Modo Teléfono"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Modo Símbolos del teléfono"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Lugares"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Símbolos"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticones"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-es-rUS/strings.xml b/java/res/values-es-rUS/strings.xml
index d440c0ce6..ffbd54364 100644
--- a/java/res/values-es-rUS/strings.xml
+++ b/java/res/values-es-rUS/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opciones de entrada"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Comandos registro invest."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Buscar nombres contactos"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"El corrector ortográfico usa entradas de tu lista de contactos."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar al pulsar teclas"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nombres de contacto"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nombres de los contactos para sugerencias y correcciones"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Sugerenc. personalizadas"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Punto y doble espacio"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Tocar dos veces la barra espaciadora inserta un punto y espacio."</string>
<string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Idiomas de entrada"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Vuelve a tocar para guardar."</string>
<string name="has_dictionary" msgid="6071847973466625007">"Diccionario disponible"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Activar los comentarios del usuario"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Envíanos automáticamente las estadísticas de uso y los informes sobre fallos para ayudarnos a mejorar este editor de método de entrada de texto."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema del teclado"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglés (Reino Unido)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglés (EE.UU.)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Activar"</string>
<string name="not_now" msgid="6172462888202790482">"Ahora no"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ya existe el estilo de entrada <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudio de usabilidad"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Demora de presión prolongada"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durac. vibrac. al presionar"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Vol. sonido al presionar tecla"</string>
diff --git a/java/res/values-es/strings-action-keys.xml b/java/res/values-es/strings-action-keys.xml
index 2701146c8..4b3039d29 100644
--- a/java/res/values-es/strings-action-keys.xml
+++ b/java/res/values-es/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Anterior"</string>
<string name="label_done_key" msgid="7564866296502630852">"Listo"</string>
<string name="label_send_key" msgid="482252074224462163">"Enviar"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pausar"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Espera"</string>
</resources>
diff --git a/java/res/values-es/strings-talkback-descriptions.xml b/java/res/values-es/strings-talkback-descriptions.xml
index 72bb6f104..11422bc56 100644
--- a/java/res/values-es/strings-talkback-descriptions.xml
+++ b/java/res/values-es/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"No se ha introducido texto"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrige <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> a <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corregirá la palabra automáticamente"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Código del teclado: %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Mayús"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Mayúsculas activadas (tocar para inhabilitar)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Bloqueo de mayúsculas activado (tocar para inhabilitar)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Más símbolos"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Mayús"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Símbolos"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Mayús"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Eliminar"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Símbolos"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letras"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Mayúsculas habilitadas"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Bloq Mayús habilitado"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Mayúsculas inhabilitadas"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Modo de símbolos"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modo de más símbolos"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Modo de letras"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Modo de teléfono"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Modo de símbolos de teléfono"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Sitios"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Símbolos"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticonos"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-es/strings.xml b/java/res/values-es/strings.xml
index 3476ac5dd..1174614c5 100644
--- a/java/res/values-es/strings.xml
+++ b/java/res/values-es/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opciones entrada texto"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Comandos registro investigación"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Nombres de contactos"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Añadir nombres de tu lista de contactos al corrector"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar al pulsar tecla"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir contactos"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nombres de contactos para sugerencias y correcciones"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Sugerencias personalizadas"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Punto y espacio"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Si tocas dos veces el espacio, se inserta un punto seguido de un espacio"</string>
<string name="auto_cap" msgid="1719746674854628252">"Mayúsculas automáticas"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Idiomas de introducción"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Toca otra vez para guardar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Hay un diccionario disponible"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Habilitar comentarios de usuarios"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Ayuda a mejorar este editor de método de introducción de texto enviando estadísticas de uso e informes de error."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema de teclado"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"inglés (Reino Unido)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"inglés (EE.UU.)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Habilitar"</string>
<string name="not_now" msgid="6172462888202790482">"Ahora no"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ya existe el estilo de entrada <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo estudio de usabilidad"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Retraso de pulsación prolongada"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Duración vibración al pulsar"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volumen sonido al pulsar tecla"</string>
diff --git a/java/res/values-et-rEE/strings-action-keys.xml b/java/res/values-et-rEE/strings-action-keys.xml
index 64ba6d6d7..fa054dff0 100644
--- a/java/res/values-et-rEE/strings-action-keys.xml
+++ b/java/res/values-et-rEE/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Eelm."</string>
<string name="label_done_key" msgid="7564866296502630852">"Valmis"</string>
<string name="label_send_key" msgid="482252074224462163">"Saada"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Peata"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Oota"</string>
</resources>
diff --git a/java/res/values-et-rEE/strings-talkback-descriptions.xml b/java/res/values-et-rEE/strings-talkback-descriptions.xml
index 5a359c1a3..5bbe63b17 100644
--- a/java/res/values-et-rEE/strings-talkback-descriptions.xml
+++ b/java/res/values-et-rEE/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Teksti ei ole sisestatud"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> parandab sõna <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> järgmiselt: <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> teeb automaatse paranduse"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Klahvi kood: %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Tõstuklahv"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Tõstuklahv sees (puudutage keelamiseks)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Suurtähelukk on sees (puudutage keelamiseks)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Rohkem sümboleid"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Tõstuklahv"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Sümbolid"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Tõstuklahv"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Kustutamine"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Sümbolid"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Tähed"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Eelmine"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Tõstuklahv on lubatud"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Suurtähelukk on lubatud"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Tõstuklahv on keelatud"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Sümbolite režiim"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Režiim Rohkem sümboleid"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Tähtede režiim"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefonirežiim"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefoni sümbolite režiim"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Kohad"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Sümbolid"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikonid"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-et-rEE/strings.xml b/java/res/values-et-rEE/strings.xml
index 6fbc4b40c..00d17bc60 100644
--- a/java/res/values-et-rEE/strings.xml
+++ b/java/res/values-et-rEE/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Sisestusvalikud"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Uuringulogi käsud"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontakti nimede kontroll."</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Õigekirjakontroll kasutab teie kontaktisikute loendi sissekandeid"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibreeri klahvivajutusel"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Soovita kontaktkirjeid"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Kasuta soovitusteks ja parandusteks nimesid kontaktiloendist"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Isikupärast. soovitused"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Punkt tühikuklahviga"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Tühikuklahvi kaks korda puudutades sisestatakse punkt ja tühik"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automaatne suurtähtede kasutamine"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Sisestuskeeled"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Salvestamiseks puudutage uuesti"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Sõnastik saadaval"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Luba kasutaja tagasiside"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Aidake seda sisestusmeetodi redigeerijat parandada, saates automaatselt kasutusstatistikat ja krahhiaruandeid."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klaviatuuri teema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglise (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglise (USA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Luba"</string>
<string name="not_now" msgid="6172462888202790482">"Mitte kohe"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sama sisendstiil on juba olemas: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kasutatavuse uurimisrežiim"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Pika klahvivajutuse viide"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Klahvivajutuse vibreerimise kestus"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Klahvivajutuse helitugevus"</string>
diff --git a/java/res/values-fa/strings-action-keys.xml b/java/res/values-fa/strings-action-keys.xml
index 78faa8c0b..ae393bbf6 100644
--- a/java/res/values-fa/strings-action-keys.xml
+++ b/java/res/values-fa/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"قبلی"</string>
<string name="label_done_key" msgid="7564866296502630852">"اتمام"</string>
<string name="label_send_key" msgid="482252074224462163">"ارسال"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"مکث"</string>
<string name="label_wait_key" msgid="5891247853595466039">"انتظار"</string>
</resources>
diff --git a/java/res/values-fa/strings-talkback-descriptions.xml b/java/res/values-fa/strings-talkback-descriptions.xml
index 26e99cb7b..c70040fae 100644
--- a/java/res/values-fa/strings-talkback-descriptions.xml
+++ b/java/res/values-fa/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"نوشتاری وارد نشده است"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g>، ‏<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> را به <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> تصحیح می‌کند"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> تصحیح خودکار را انجام می‌دهد"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"‏کد کلید %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"‏Shift روشن است (برای غیرفعال کردن ضربه بزنید)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"‏Caps Lock روشن است (برای غیرفعال کردن ضربه بزنید)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"نمادهای بیشتر"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"تبدیل"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"نمادها"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"تبدیل"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"حذف"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"نمادها"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"حروف"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"قبلی"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"‏Shift فعال شد"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"‏Caps lock فعال شد"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"‏Shift غیرفعال شد"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"حالت نمادها"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"حالت نمادهای بیشتر"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"حالت حروف"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"حالت تلفن"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"حالت نمادهای تلفن"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"مکان‌ها"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"نمادها"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"شکلک‌ها"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-fa/strings.xml b/java/res/values-fa/strings.xml
index 04c6a5aca..8a6e5a2dc 100644
--- a/java/res/values-fa/strings.xml
+++ b/java/res/values-fa/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"گزینه‌های ورودی"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"فرمان‌های گزارش‌گیری پژوهش"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"جستجوی نام مخاطبین"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"غلط‌گیر املا از ورودی‌های لیست مخاطبین شما استفاده می‌کند"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"لرزش با فشار کلید"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"پیشنهاد نام‌های مخاطب"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"برای پیشنهاد و تصحیح از نام مخاطبین استفاده شود"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"پیشنهادات شخصی شده"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"نقطه با دو فاصله"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"با دوبار ضربه روی دکمه فاصله نقطه با یک فاصله بعد آن درج می‌شود"</string>
<string name="auto_cap" msgid="1719746674854628252">"بزرگ‌کردن خودکار حروف"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"زبان‌های ورودی"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"برای ذخیره دوباره لمس کنید"</string>
<string name="has_dictionary" msgid="6071847973466625007">"دیکشنری موجود است"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"فعال کردن بازخورد کاربر"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"با ارسال خودکار آمار استفاده و گزارش‌های خرابی، به بهبود این ویرایشگر روش ورودی کمک کنید"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"طرح زمینه صفحه‌کلید"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"انگلیسی (بریتانیا)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"انگلیسی (امریکا)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"فعال کردن"</string>
<string name="not_now" msgid="6172462888202790482">"الآن نه"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"سبک ورودی مشابهی در حال حاضر وجود دارد: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"حالت بررسی قابلیت استفاده"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"تأخیر فشار طولانی کلید"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"طول مدت لرزش در اثر فشردن کلید"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"میزان صدای فشردن کلید"</string>
diff --git a/java/res/values-fi/strings-action-keys.xml b/java/res/values-fi/strings-action-keys.xml
index da7f11197..5472fc31a 100644
--- a/java/res/values-fi/strings-action-keys.xml
+++ b/java/res/values-fi/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Edel."</string>
<string name="label_done_key" msgid="7564866296502630852">"Valm."</string>
<string name="label_send_key" msgid="482252074224462163">"Läh."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Tauko"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Odota"</string>
</resources>
diff --git a/java/res/values-fi/strings-emoji-descriptions.xml b/java/res/values-fi/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..ad08bbda2
--- /dev/null
+++ b/java/res/values-fi/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Copyright-merkki"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Rekisteröidyn tavaramerkin merkki"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Kaksi huutomerkkiä"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Huutomerkki ja kysymysmerkki"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Tavaramerkin merkki"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Tietolähde"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Nuoli vasemmalle ja oikealle"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Nuoli ylös ja alas"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Nuoli vasemmalle ylös"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Nuoli oikealle ylös"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Nuoli oikealle alas"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Nuoli vasemmalle alas"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Koukkunuoli vasemmalle"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Koukkunuoli oikealle"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"Katso"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Tiimalasi"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Musta oikealle osoittava kaksoiskolmio"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Musta vasemmalle osoittava kaksoiskolmio"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Musta ylös osoittava kaksoiskolmio"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Musta alas osoittava kaksoiskolmio"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Herätyskello"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Tiimalasi ja hiekka"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Ympyröity iso M-kirjain"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Pieni musta neliö"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Pieni valkoinen neliö"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Musta oikealle osoittava kolmio"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Musta vasemmalle osoittava kolmio"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Suuri valkoinen neliö"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Suuri musta neliö"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Valkoinen neliö"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Musta neliö"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Musta aurinko"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Pilvi"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Musta puhelin"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Valittu kyselyruutu"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Sateenvarjo ja sadepisarat"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Kuuma juoma"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Valkoinen käsi, ylös osoittava etusormi"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Valkoinen hymyilevä naama"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Oinas"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Härkä"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Kaksoset"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Rapu"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Leijona"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Neitsyt"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Vaaka"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Skorpioni"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Jousimies"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Kauris"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Vesimies"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Kalat"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Musta patasymboli"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Musta ristisymboli"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Musta herttasymboli"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Musta ruutusymboli"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Kuuma lähde"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Musta kierrätysmerkki"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Pyörätuolin symboli"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Ankkuri"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Varoitusmerkki"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Korkean jännitteen symboli"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Valkoinen ympyrä"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Musta ympyrä"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Jalkapallo"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Pesäpallo"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Lumiukko ilman lunta"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Aurinko pilven takana"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Käärmeenkantaja"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Kielletty ajosuunta"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Kirkko"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Suihkulähde"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Lippu reiässä"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Purjevene"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Teltta"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Polttoainepumppu"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Mustat sakset"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Valkoinen valintamerkki"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Lentokone"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Kirjekuori"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Nyrkki"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Pystyssä oleva kämmen"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Voitonmerkki"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Lyijykynä"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Musta kynänkärki"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Paksu valintamerkki"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Paksu kertomerkki"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Tuikkivat tähdet"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Kahdeksansakarainen tähti"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Kahdeksansakarainen musta tähti"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Lumihiutale"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Kipinä"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Ristimerkki"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Valkoinen ristimerkki mustalla taustalla"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Musta koristeellinen kysymysmerkki"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Valkoinen koristeellinen kysymysmerkki"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Valkoinen koristeellinen huutomerkki"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Paksu huutomerkki"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Väritetty sydän"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Paksu plusmerkki"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Paksu miinusmerkki"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Paksu jakomerkki"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Musta nuoli oikealle"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Silmukka"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Kaksoissilmukka"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Oikealle ja ylös osoittava nuoli"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Oikealle ja alas osoittava nuoli"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Musta nuoli vasemmalle"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Musta nuoli ylös"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Musta nuoli alas"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Suuri musta neliö"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Suuri valkoinen neliö"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Valkoinen tähti"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Paksu suuri ympyrä"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Aaltoviiva"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Vuorottelumerkki"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Ideogrammi onnittelu ympyrän sisällä"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Ideogrammi salaisuus ympyrän sisällä"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Mahjong-laatta, punainen lohikäärme"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Pelikortti, musta jokeri"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Veriryhmä A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Veriryhmä B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Veriryhmä O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Pysäköintialue"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Veriryhmä AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"CL neliön sisällä"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Sana COOL neliön sisällä"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Sana FREE neliön sisällä"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"ID neliön sisällä"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"Sana NEW neliön sisällä"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"NG neliön sisällä"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"OK neliön sisällä"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"SOS neliön sisällä"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"Sana UP ja huutomerkki neliön sisällä"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"VS neliön sisällä"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Katakana täällä neliön sisällä"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Katakana palvelu neliön sisällä"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Ideogrammi maksuton neliön sisällä"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Ideogrammi varattu paikka neliön sisällä"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Ideogrammi kielto neliön sisällä"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Ideogrammi vapaita paikkoja neliön sisällä"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Ideogrammi hyväksyntä neliön sisällä"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Ideogrammi täynnä neliön sisällä"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Ideogrammi maksettu neliön sisällä"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Ideogrammi kuukausittain neliön sisällä"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Ideogrammi tilaus neliön sisällä"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Ideogrammi alennus neliön sisällä"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Ideogrammi liiketoiminta neliön sisällä"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Ideogrammi etu neliön sisällä"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Ideogrammi hyväksy ympyrän sisällä"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Pyörremyrsky"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Sumu"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Suljettu sateenvarjo"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Yömaisema"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Auringonnousu vuorilla"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Auringonnousu"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Kaupunkimaisema hämärässä"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Auringonlasku rakennusten taakse"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Sateenkaari"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Silta yöllä"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Vaahtopää"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Tulivuori"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Linnunrata"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Maapallo, Eurooppa – Afrikka"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Maapallo, Amerikat"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Maapallo Aasia – Australia"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Maapallo ja pituuspiirit"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Uudenkuun symboli"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Kasvavan kuunsirpin symboli"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"Kuun ensimmäisen neljänneksen symboli"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Kasvavan puolikuun symboli"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Täysikuun symboli"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Vähenevän kuun symboli"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Kuun viimeisen neljänneksen symboli"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Vähenevän kuunsirpin symboli"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Kuunsirppi"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Uusikuu, jolla kasvot"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Ensimmäisen neljänneksen kuu, jolla kasvot"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Viimeisen neljänneksen kuu, jolla kasvot"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Täysikuu, jolla kasvot"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Aurinko, jolla kasvot"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Loistava tähti"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Tähdenlento"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Kastanja"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Taimi"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Havupuu"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Lehtipuu"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Palmu"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Kaktus"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Tulppaani"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Kirsikankukka"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Ruusu"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Kiinanruusu"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Auringonkukka"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Kukka"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Maissintähkä"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Riisintähkä"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Yrtti"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Neliapila"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Vaahteranlehti"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Pudonnut lehti"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Tuulessa leijaileva lehti"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Sieni"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Tomaatti"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Munakoiso"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Viinirypäleet"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Meloni"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Vesimeloni"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Mandariini"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Sitruuna"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Banaani"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Ananas"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Punainen omena"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Vihreä omena"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Päärynä"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Persikka"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Kirsikat"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Mansikka"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Hampurilainen"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Pitsapala"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Lihainen luu"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Kanankoipi"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Riisikeksi"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Riisipallo"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Keitetty riisi"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Curry ja riisi"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Höyryävä kulho"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Spagetti"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Leipä"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Ranskalaiset perunat"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Jamssi"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Dango"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oden"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Sushi"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Friteeratut katkaravut"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Surimiviipale, jossa pyörrekuvio"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Pehmytjäätelö"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Murskattu jää"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Jäätelö"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Donitsi"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Pikkuleipä"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Suklaapatukka"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Karamelli"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Tikkukaramelli"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Vanukas"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Hunajapurkki"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Kakkuviipale"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Bento-lounaslaatikko"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Ruokapata"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Ruoanlaitto"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Haarukka ja veitsi"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Teekuppi ilman korvaa"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Sake-pullo ja kuppi"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Viinilasi"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Cocktail-lasi"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Trooppinen drinkki"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Oluttuoppi"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Kippistävät olutmukit"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Tuttipullo"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Rusetti"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Lahjapaketti"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Syntymäpäiväkakku"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Kurpitsalyhty"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Joulukuusi"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Joulupukki"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Ilotulitus"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Tähtisadetikku"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Ilmapallo"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Konfettipommi"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Konfettipallo"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Tanabata-puu"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Liput ristikkäin"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Japanilainen mäntykoriste"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Japanilaiset nuket"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Kalanmuotoiset tuulipussit"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Tuulikello"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Kuujuhla"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Koululaukku"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Valmistujaislakki"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Karusellihevonen"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Maailmanpyörä"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Vuoristorata"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Onki ja kala"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Mikrofoni"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Elokuvakamera"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Elokuvateatteri"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Kuulokkeet"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Taiteilijan paletti"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Silinterihattu"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Sirkusteltta"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Lippu"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Klaffi"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Näyttämötaide"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Videopeli"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Napakymppi"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Peliautomaatti"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Biljardi"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Arpakuutio"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Keilailu"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Hanafuda-pelikortit"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Nuotti"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Nuotteja"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Saksofoni"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Kitara"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Koskettimet"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Trumpetti"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Viulu"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Nuottiviivasto"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Juoksupaita"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Tennismaila ja pallo"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Suksi ja mono"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Koripallo ja kori"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Ruutulippu"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Lumilautailija"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Juoksija"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Lainelautailija"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Palkintopokaali"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Laukkakilpailut"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Amerikkalainen jalkapallo"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Rugby-pallo"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Uimari"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Talo"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Talo ja puutarha"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Toimistorakennus"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Japanilainen postitoimisto"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Eurooppalainen postitoimisto"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Sairaala"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Pankki"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Pankkiautomaatti"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Hotelli"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Japanilainen love-hotelli"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Päivittäistavarakauppa"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Koulu"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Tavaratalo"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Tehdas"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Izakaya-ravintolan lyhty"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Japanilainen linna"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Eurooppalainen linna"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Rotta"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Hiiri"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Härkä"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Vesipuhveli"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Lehmä"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Leopardi"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Jänis"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Kissa"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Lohikäärme"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Krokotiili"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Valas"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Etana"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Käärme"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Hevonen"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Pässi"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Vuohi"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Lammas"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Apina"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Kukko"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Kana"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Koira"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Sika"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Villisika"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Norsu"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Mustekala"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Simpukankuori"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Hyönteinen"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Muurahainen"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Mehiläinen"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Leppäkerttu"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Kala"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Trooppinen kala"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Pallokala"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Kilpikonna"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Kuoriutuva kananpoika"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Kananpoika"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Eteenpäin katsova kananpoika"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Lintu"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Pingviini"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Koala"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Villakoira"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Yksikyttyräinen kameli"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Kaksikyttyräinen kameli"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Delfiini"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Hiiren pää"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Lehmän pää"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Tiikerin pää"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Jäniksen pää"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Kissan pää"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Lohikäärmeen pää"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Valas ja vesisuihku"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Hevosen pää"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Apinan pää"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"Koiran pää"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Sian pää"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Sammakon pää"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Hamsterin pää"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Suden pää"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Karhun pää"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Pandan pää"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Sian kärsä"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Tassunjäljet"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Silmät"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Korva"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Nenä"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Suu"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Kieli"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Valkoinen käsi, ylös osoittava etusormi"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Valkoinen käsi, alas osoittava etusormi"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Valkoinen käsi, vasemmalle osoittava etusormi"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Valkoinen käsi, oikealle osoittava etusormi"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Käsi nyrkissä"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Vilkuttava käsi"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"OK-merkki"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Peukalo pystyssä"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Peukalo alaspäin"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Taputtavat kädet"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Avoimet kämmenet"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Kruunu"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Naisen hattu"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Silmälasit"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Kravatti"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"T-paita"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Farkut"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Leninki"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Kimono"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Bikinit"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Naisen paita"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Kukkaro"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Käsilaukku"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Pussukka"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Miesten kenkä"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Urheilujalkine"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Korkokenkä"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Naisen sandaali"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Naisen saappaat"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Jalanjäljet"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Rintakuvan ääriviivat"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Rintakuvien ääriviivat"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Poika"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Tyttö"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Mies"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Nainen"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Perhe"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Mies ja nainen käsi kädessä"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Kaksi miestä käsi kädessä"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Kaksi naista käsi kädessä"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Poliisi"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Nainen, jolla on pupun korvat"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Morsian hunnussa"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Vaaleahiuksinen henkilö"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Mies, jolla aasialainen päähine"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Mies, jolla turbaani"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Vanha mies"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Vanha nainen"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Vauva"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Rakennustyöläinen"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Prinsessa"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Japanilainen hirviö"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Japanilainen menninkäinen"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Kummitus"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Enkelivauva"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Ulkoavaruuden olento"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Avaruusolio"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Pikkupiru"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Kallo"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Asiakaspalvelija"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Vartija"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Tanssija"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Huulipuna"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Kynsilakka"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Kasvohieronta"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Hiusten leikkaus"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Parturin pylväs"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Ruisku"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Pilleri"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Huulet"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Rakkauskirje"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Sormus"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Jalokivi"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Suudelma"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Kukkakimppu"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Pariskunta ja sydän"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Häät"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Sykkivä sydän"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Särkynyt sydän"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Kaksi sydäntä"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Säihkyvä sydän"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Kasvava sydän"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Sydän ja nuoli"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Sininen sydän"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Vihreä sydän"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Keltainen sydän"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Violetti sydän"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Sydän ja rusetti"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Pyörivät sydämet"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Sydänkoriste"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Vinoneliö, jossa on sisällä piste"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Hehkulamppu"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Vihan symboli"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Pommi"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Unen symboli"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Törmäyksen symboli"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Hikipisarat"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Pisara"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Liikkeen symboli"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Kakkakasa"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Hauis"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Huimauksen symboli"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Puhekupla"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Ajatuskupla"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Valkoinen kukka"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Sadan pisteen symboli"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Rahasäkki"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Valuutanvaihto"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Paksu dollarin symboli"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Luottokortti"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Seteli, jossa jenin symboli"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Seteli, jossa dollarin symboli"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Seteli, jossa euron symboli"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Seteli, jossa punnan symboli"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Setelinippu, jolla siivet"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Noususuuntainen kaavio, jossa jenin symboli"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Paikka"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Tietokone"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Salkku"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Minilevy"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Levyke"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Optinen levy"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD-levy"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Tiedostokansio"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Avaa tiedostokansio"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Alhaalta käpristynyt sivu"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Sivu edestä"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Kalenteri"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Kalenteri, irtirevittävät sivut"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Kortihakemisto"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Noususuuntainen kaavio"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Laskusuuntainen kaavio"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Pylväskaavio"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Leikepöytä"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Nasta"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Pyöreäpäinen nasta"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Paperiliitin"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Suora viivain"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Kolmioviivain"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Kirjanmerkit"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Kierreselkäinen vihko"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Muistikirja"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Muistikirja, jossa koristekansi"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Suljettu kirja"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Avoin kirja"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Vihreä kirja"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Sininen kirja"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Oranssi kirja"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Kirjat"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Nimilappu"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Rulla"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Muistio"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Puhelimen kuuloke"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Hakulaite"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Faksi"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Satelliittiantenni"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Julkisen tilan kovaääninen"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Megafoni"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Lähtevien lokero"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Saapuvien lokero"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Paketti"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"Sähköpostin symboli"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Saapuva kirjekuori"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Kirjekuori alaspäin osoittavan nuolen alla"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Suljettu postilaatikko lippu alhaalla"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Suljettu postilaatikko lippu ylhäällä"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Avattu postilaatikko lippu ylhäällä"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Avattu postilaatikko lippu alhaalla"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Postilaatikko"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Postitorvi"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Sanomalehti"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Matkapuhelin"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Matkapuhelin, jonka vasemmalla puolella on sitä osoittava nuoli"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Värinätila"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Matkapuhelin pois käytöstä"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Ei matkapuhelimia"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Antennisymboli ja palkit"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Kamera"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Videokamera"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Televisio"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Radio"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Videokasetti"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Kaksi ristikkäistä oikealle osoittavaa nuolta"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Ympyrä, jossa myötäpäivään oikealle ja vasemmalle osoittavat nuolet"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Ympyrä, jossa myötäpäivään oikealle ja vasemmalle osoittavat nuolet ja jonka päällä ympyröity numero yksi"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Ympyrä, jossa myötäpäivään ylös ja alas osoittavat nuolet"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Ympyrä, jossa vastapäivään ylös ja alas osoittavat nuolet"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Alhaisen kirkkauden symboli"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Suuren kirkkauden symboli"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Yliviivattu kaiutin"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Kaiutin"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Kaiutin ja yksi ääniaalto"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Kaiutin ja kolme ääniaaltoa"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Akku"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Pistoke"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Vasemmalle osoittava suurennuslasi"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Oikealle osoittava suurennuslasi"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Lukko ja mustekynä"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Suljettu lukko ja avain"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Avain"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Lukko"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Avoin lukko"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Soittokello"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Yliviivattu soittokello"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Kirjanmerkki"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Linkin symboli"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Valintanappi"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Sana BACK, jonka yläpuolella vasemmalle osoittava nuoli"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"Sana END, jonka yläpuolella vasemmalle osoittava nuoli"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"Sana ON ja huutomerkki, yläpuolella vasemmalle ja oikealle osoittava nuoli"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Sana SOON, jonka yläpuolella oikealle osoittava nuoli"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Sana TOP, jonka yläpuolella ylös osoittava nuoli"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"Ikäraja 18 vuotta"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Näppäin 10"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Latinalaisten isojen kirjainten symboli"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Latinalaisten pienten kirjainten symboli"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Numeroiden symboli"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Symbolien symboli"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Latinalaisten kirjainten symboli"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Tuli"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Taskulamppu"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Jakoavain"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Vasara"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Mutteri ja pultti"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Hochoveitsi"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Pistooli"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Mikroskooppi"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Kaukoputki"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Kristallipallo"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Kuusisakarainen tähti, jossa keskellä piste"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Japanilainen aloittelijan merkki"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Trident-symboli"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Musta neliönmuotoinen painike"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Valkoinen neliönmuotoinen painike"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Suuri punainen ympyrä"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Suuri sininen ympyrä"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Suuri oranssi vinoneliö"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Suuri sininen vinoneliö"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Pieni oranssi vinoneliö"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Pieni sininen vinoneliö"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Ylöspäin osoittava punainen kolmio"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Alaspäin osoittava punainen kolmio"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Ylöspäin osoittava pieni punainen kolmio"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Alaspäin osoittava pieni punainen kolmio"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Kellotaulu, kello yksi"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Kellotaulu, kello kaksi"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Kellotaulu, kello kolme"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Kellotaulu, kello neljä"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Kellotaulu, kello viisi"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Kellotaulu, kello kuusi"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Kellotaulu, kello seitsemän"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Kellotaulu, kello kahdeksan"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Kellotaulu, kello yhdeksän"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Kellotaulu, kello kymmenen"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Kellotaulu, kello yksitoista"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Kellotaulu, kello kaksitoista"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Kellotaulu, kello puoli kaksi"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Kellotaulu, kello puoli kolme"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Kellotaulu, kello puoli neljä"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Kellotaulu, kello puoli viisi"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Kellotaulu, kello puoli kuusi"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Kellotaulu, kello puoli seitsemän"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Kellotaulu, kello puoli kahdeksan"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Kellotaulu, kello puoli yhdeksän"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Kellotaulu, kello puoli kymmenen"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Kellotaulu, kello puoli yksitoista"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Kellotaulu, kello puoli kaksitoista"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Kellotaulu, kello puoli yksi"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Fuji-vuori"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Tokio-torni"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Vapaudenpatsas"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Japanin kartta"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Moai-kivipatsas"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Virnistävä naama"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Virnistävä naama silmät sirrillään"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Naama ja ilon kyyneleet"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Hymyilevä naama, suu auki"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Hymyilevä naama, suu auki ja silmät sirrillään"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Hymyilevä naama, suu auki ja kylmä hiki"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Hymyilevä naama, suu auki ja silmät kiinni"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Hymyilevä naama ja sädekehä"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Hymyilevä naama ja sarvet"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Silmää iskevä naama"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Hymyilevä naama, silmät sirrillään"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Naama ja huulia lipova kieli"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Helpottunut naama"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Hymyilevä naama ja sydämenmuotoiset silmät"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Hymyilevä naama ja aurinkolasit"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Virnistävä naama"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Naamalla perusilme"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Ilmeetön naama"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Kyllästynyt naama"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Naama ja kylmä hiki"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Mietteliäs naama"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Ymmällä oleva naama"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Hämmentynyt naama"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Naama ja pusuhuulet"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Lentosuukko ja silmänisku"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Naama ja pusuhuulet, silmät sirrillään"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Naama ja pusuhuulet, silmät kiinni"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Kieltä näyttävä naama"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Silmää iskevä ja kieltä näyttävä naama"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Kieltä näyttävä naama, silmät kiinni"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Pettynyt naama"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Huolestunut naama"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Vihainen naama"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Mököttävä naama"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Itkevä naama"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Sinnikäs naama"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Voitokas naama"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Pettynyt mutta huojentunut naama"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Surullinen naama, suu auki"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Tuskainen naama"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Pelokas naama"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Uupunut naama"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Uninen naama"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Väsynyt naama"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Irvistävä naama"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Rajusti itkevä naama"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Naama, suu auki"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Pelokas naama"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Naama, suu auki ja kylmä hiki"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Pelosta kirkuva naama"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Hämmästynyt naama"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Punastunut naama"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Nukkuva naama"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Naama taju kankaalla"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Naama ilman suuta"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Naama ja suumaski"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Virnistävä kissan naama, silmät sirrillään"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Kissan naama ja ilon kyyneleet"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Hymyilevä kissan naama, suu auki"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Hymyilevä kissan naama, sydämen muotoiset silmät"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Kissan naama, kuivakka hymy"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Kissan naama, pusuhuulet ja silmät kiinni"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Mököttävä kissan naama"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Itkevä kissan naama"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Uupunut kissan naama"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Naama ja epäonnistumisen ele"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Naama, OK-ele"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Syvään kumartava henkilö"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Silmänsä peittänyt apina"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Korvansa peittänyt apina"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Suunsa peittänyt apina"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Iloinen henkilö yksi käsi pystyssä"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Juhliva henkilö molemmat kädet pystyssä"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Henkilö otsa kurtussa"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Henkilö ja mököttävä ilme"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Henkilö, jolla kämmenet yhdessä"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Raketti"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Helikopteri"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Höyryveturi"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Junanvaunu"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Pikajuna"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Luotijuna"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Juna"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metro"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Kevyt raideliikenne"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Asema"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Raitiovaunu"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Raitiovaunun vaunu"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Bussi"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Bussi edestä"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Johdinauto"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Bussipysäkki"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Pikkubussi"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulanssi"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Paloauto"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Poliisiauto"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Poliisiauto edestä"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Taksi"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Taksi edestä"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Auto"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Auto edestä"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Maastoauto"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Kuorma-auto"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Kuorma-auto"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Traktori"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Yksiraiteinen rautatie"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Vuoristojuna"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Riippuva rautatie"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Köysirata"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Köysirata"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Laiva"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Soutuvene"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Pikavene"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Vaakasuuntaiset liikennevalot"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Pystysuuntaiset liikennevalot"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Rakennustyömaan merkki"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Poliisiauton hälytysvalo"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Kolmiolippu"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Ovi"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Kulku kielletty -merkki"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Tupakointisymboli"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Tupakointi kielletty"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Roskat roskakoriin -symboli"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Älä roskaa -symboli"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Juomaveden symboli"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Juomakelvottoman veden symboli"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Polkupyörä"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Pyöräily kielletty"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Pyöräilijä"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Maastopyöräilijä"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Jalankulkija"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Jalankulku kieletty"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Lapsia-varoitusmerkki"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Miehen symboli"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Naisen symboli"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"WC"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Vauvan symboli"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"WC"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"WC"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Suihku"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Kylpy"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Kylpyamme"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Passintarkastus"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Tulli"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Matkatavaroiden nouto"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Matkatavaroiden säilytys"</string>
+</resources>
diff --git a/java/res/values-fi/strings-talkback-descriptions.xml b/java/res/values-fi/strings-talkback-descriptions.xml
index 2d0d7a782..e2e66e3fe 100644
--- a/java/res/values-fi/strings-talkback-descriptions.xml
+++ b/java/res/values-fi/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Ei kirjoitettua tekstiä"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> korjaa sanan <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> sanaksi <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> suorittaa automaattisen korjauksen"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Näppäimen koodi %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Vaihto"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Vaihto päällä (poista käytöstä napauttamalla)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock päällä (poista käytöstä napauttamalla)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Lisää symboleita"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Vaihto"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbolit"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Vaihto"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Delete"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbolit"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Kirjaimet"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Edellinen"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Vaihto päällä"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock päällä"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Vaihto pois päältä"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbolit-tila"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Lisää symboleita -tila"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Näppäimistötila"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Puhelintila"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Puhelinsymbolit-tila"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Paikat"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbolit"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Hymiöt"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-fi/strings.xml b/java/res/values-fi/strings.xml
index 756684ae0..de9866acb 100644
--- a/java/res/values-fi/strings.xml
+++ b/java/res/values-fi/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Syöttövalinnat"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Tutkimuslokin komennot"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Hae yht.tietojen nimiä"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Oikeinkirjoituksen tarkistus käyttää yhteystietojasi."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Käytä värinää näppäimiä painettaessa"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Ehdota yht.tietojen nimiä"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Käytä yhteystietojen nimiä ehdotuksissa ja korjauksissa"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Räätälöidyt ehdotukset"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Kaksoisvälilyönti = piste"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Välilyönnin kaksoisnapautus lisää tekstiin pisteen ja välilyönnin"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automaattiset isot kirjaimet"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Syöttökielet"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Tallenna koskettamalla uudelleen"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Sanakirja saatavilla"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Ota käyttäjäpalaute käyttöön"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Auta parantamaan tätä syöttötavan muokkausohjelmaa lähettämällä automaattisesti käyttötietoja ja kaatumisraportteja."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Näppäimistöteema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"englanti (Iso-Britannia)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"englanti (Yhdysvallat)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Ota käyttöön"</string>
<string name="not_now" msgid="6172462888202790482">"Ei nyt"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Syöttötyyli on jo olemassa: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Käytettävyystutkimustila"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Pitkän painalluksen viive"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Painalluksen värinän kesto"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Näppäinpainalluksen äänenvoim."</string>
diff --git a/java/res/values-fr-rCA/strings-action-keys.xml b/java/res/values-fr-rCA/strings-action-keys.xml
index bb5568e79..b35dd61bd 100644
--- a/java/res/values-fr-rCA/strings-action-keys.xml
+++ b/java/res/values-fr-rCA/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Préc."</string>
<string name="label_done_key" msgid="7564866296502630852">"Term."</string>
<string name="label_send_key" msgid="482252074224462163">"Env."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Att."</string>
</resources>
diff --git a/java/res/values-fr-rCA/strings-talkback-descriptions.xml b/java/res/values-fr-rCA/strings-talkback-descriptions.xml
index b632edca3..2a0bec474 100644
--- a/java/res/values-fr-rCA/strings-talkback-descriptions.xml
+++ b/java/res/values-fr-rCA/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Aucun texte entré"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"La touche <xliff:g id="KEY_NAME">%1$s</xliff:g> permet de remplacer <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> par <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"La touche <xliff:g id="KEY_NAME">%1$s</xliff:g> permet d\'effectuer une correction automatique"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Code touche %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Majuscule"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Touche Majuscule activée (toucher pour désactiver)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Verrouillage des majuscules activé (toucher pour désactiver)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Autres symboles"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Majuscule"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboles"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Majuscule"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Supprimer"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboles"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Lettres"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Précédente"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Touche Maj activée"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Verrouillage des majuscules activé"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Touche Majuscule désactivée"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Mode Symboles"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Mode Autres symboles"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Mode Lettres"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Mode Téléphone"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Mode Symboles du téléphone"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Lieux"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboles"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Émoticônes"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-fr-rCA/strings.xml b/java/res/values-fr-rCA/strings.xml
index 5b1308166..357210f0c 100644
--- a/java/res/values-fr-rCA/strings.xml
+++ b/java/res/values-fr-rCA/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Options de saisie"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Commandes journaux rech."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Rechercher noms contacts"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Correcteur orthographique utilise entrées de liste de contacts."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer à chaque touche"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Suggestions personnalisées"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Point et espace"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Appuyez deux fois sur la barre d\'espace pour insérer un point et une espace"</string>
<string name="auto_cap" msgid="1719746674854628252">"Majuscules automatiques"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Langues de saisie"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Appuyer de nouveau pour enregistrer"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Autoriser les commentaires des utilisateurs"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Contribuer à l\'amélioration de cet éditeur du mode de saisie grâce à l\'envoi automatique de statistiques d\'utilisation et de rapports d\'erreur"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglais (britannique)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglais (États-Unis)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Activer"</string>
<string name="not_now" msgid="6172462888202790482">"Pas maintenant"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Le style de saisie suivant existe déjà : <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'étude de l\'utilisabilité"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Délai appui prolongé sur touche"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durée vibration press. touche"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume pression de touche"</string>
diff --git a/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml b/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml
index d72f72b92..5a4914245 100644
--- a/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml
+++ b/java/res/values-fr/donottranslate-config-spacing-and-punctuations.xml
@@ -22,6 +22,8 @@
<string name="symbols_preceded_by_space">([{&amp;;:!?</string>
<!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
<string name="symbols_followed_by_space">.,;:!?)]}&amp;</string>
+ <!-- Symbols that behave like a single punctuation when typed next to each other -->
+ <string name="symbols_clustering_together">!?</string>
<!-- Symbols that separate words -->
<!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
<string name="symbols_word_separators">"&#x0009;&#x0020;&#x000A;&#x00A0;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
diff --git a/java/res/values-fr/strings-action-keys.xml b/java/res/values-fr/strings-action-keys.xml
index 1c36552d4..e69351c07 100644
--- a/java/res/values-fr/strings-action-keys.xml
+++ b/java/res/values-fr/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Préc."</string>
<string name="label_done_key" msgid="7564866296502630852">"OK"</string>
<string name="label_send_key" msgid="482252074224462163">"Envoyer"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Attente"</string>
</resources>
diff --git a/java/res/values-fr/strings-talkback-descriptions.xml b/java/res/values-fr/strings-talkback-descriptions.xml
index efa140b49..a79fd2107 100644
--- a/java/res/values-fr/strings-talkback-descriptions.xml
+++ b/java/res/values-fr/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Aucun texte saisi"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"La touche <xliff:g id="KEY_NAME">%1$s</xliff:g> permet de remplacer \"<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>\" par \"<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>\"."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"La touche <xliff:g id="KEY_NAME">%1$s</xliff:g> permet d\'effectuer une correction automatique."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Code touche %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Maj"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Touche Maj activée (appuyer pour désactiver)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Verrouillage des majuscules activé (appuyer pour désactiver)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Autres symboles"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Maj"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboles"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Maj"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Supprimer"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboles"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Lettres"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Précédent"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"La touche Maj a bien été activée."</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Le verrouillage des majuscules a bien été activé."</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"La touche Maj a bien été désactivée."</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Mode Symboles"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Mode Autres symboles"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Mode Lettres"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Mode Téléphone"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Mode Symboles du téléphone"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Lieux"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboles"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Émoticônes"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-fr/strings.xml b/java/res/values-fr/strings.xml
index 1bb856783..ea7eed688 100644
--- a/java/res/values-fr/strings.xml
+++ b/java/res/values-fr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Options de saisie"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Commandes journaux rech."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Rechercher noms contacts"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Correcteur orthographique utilise entrées de liste de contacts."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer à chaque touche"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Proposer noms de contacts"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utiliser des noms de contacts pour les suggestions et corrections"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Suggestions personnalisées"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Point et espace"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Appuyez deux fois sur la barre d\'espace pour insérer un point et un espace."</string>
<string name="auto_cap" msgid="1719746674854628252">"Majuscules auto"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Langues de saisie"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Appuyer de nouveau pour enregistrer"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dictionnaire disponible"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Autoriser les commentaires des utilisateurs"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Contribuer à l\'amélioration de cet éditeur du mode de saisie grâce à l\'envoi automatique de statistiques d\'utilisation et de rapports d\'erreur"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Thème du clavier"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglais (Royaume-Uni)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglais (États-Unis)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Activer"</string>
<string name="not_now" msgid="6172462888202790482">"Pas maintenant"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Le style de saisie suivant existe déjà : <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>."</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode d\'étude de l\'utilisabilité"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Délai appui prolongé sur touche"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durée vibration press. touche"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume son pression de touche"</string>
diff --git a/java/res/values-hi/strings-action-keys.xml b/java/res/values-hi/strings-action-keys.xml
index 92cb194ea..a90434329 100644
--- a/java/res/values-hi/strings-action-keys.xml
+++ b/java/res/values-hi/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"पिछला"</string>
<string name="label_done_key" msgid="7564866296502630852">"पूर्ण"</string>
<string name="label_send_key" msgid="482252074224462163">"भेजें"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"रोकें"</string>
<string name="label_wait_key" msgid="5891247853595466039">"प्रतीक्षा करें"</string>
</resources>
diff --git a/java/res/values-hi/strings-talkback-descriptions.xml b/java/res/values-hi/strings-talkback-descriptions.xml
index df9511905..78e4c8d6e 100644
--- a/java/res/values-hi/strings-talkback-descriptions.xml
+++ b/java/res/values-hi/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"कोई पाठ नहीं डाला गया"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> को सुधार कर <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> करता है"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> स्वत: सुधार करता है"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"कुंजी कोड %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"शिफ़्ट"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"शिफ़्ट चालू (अक्षम करने के लिए टैप करें)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"कैप्स लॉक चालू (अक्षम करने के लिए टैप करें)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"और प्रतीक"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"शिफ़्ट"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"प्रतीक"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"शिफ़्ट"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"डिलीट"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"प्रतीक"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"अक्षर"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"पिछला"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"शिफ़्ट सक्षम किया गया"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"कैप्स लॉक सक्षम किया गया"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"शिफ़्ट अक्षम किया गया"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"प्रतीक मोड"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"और प्रतीक मोड"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"अक्षर मोड"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"फ़ोन मोड"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"फ़ोन प्रतीक मोड"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"स्थान"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"प्रतीक"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"इमोटिकॉन्स"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml
index 3129d86cc..26d9595ef 100644
--- a/java/res/values-hi/strings.xml
+++ b/java/res/values-hi/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"इनपुट विकल्‍प"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"लॉग आदेशों का शोध करें"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"संपर्क नामों को खोजें"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"वर्तनी परीक्षक आपकी संपर्क सूची की प्रविष्टियों का उपयोग करता है"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"कुंजी दबाने पर कंपन करता है"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"संपर्क नाम सुझाएं"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव और सुधार के लिए संपर्क से नामों का उपयोग करें"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"वैयक्तिकृत सुझाव"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"दोहरे स्पेस वाला पीरियड"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबार पर डबल टैप करने से पीरियड शामिल हो जाता है जिसके बाद एक रिक्ति होती है"</string>
<string name="auto_cap" msgid="1719746674854628252">"स्‍वत: अक्षर बड़े करना"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"इनपुट भाषाएं"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"सहेजने के लिए पुन: स्‍पर्श करें"</string>
<string name="has_dictionary" msgid="6071847973466625007">"शब्‍दकोश उपलब्‍ध है"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"उपयोगकर्ता फ़ीडबैक सक्षम करें"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"उपयोग के आंकड़े और क्रैश रिपोर्ट अपने आप भेजकर इस इनपुट पद्धति संपादक को बेहतर बनाने में सहायता करें."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"कीबोर्ड थीम"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेज़ी (यूके)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेज़ी (यूएस)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"सक्षम करें"</string>
<string name="not_now" msgid="6172462888202790482">"अभी नहीं"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"ऐसी ही इनपुट शैली पहले से मौजूद है: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"उपयोगिता अध्ययन मोड"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"कुंजी को देर तक दबाने का विलंब"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"कुंजी-स्पर्श कंपन अवधि"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"कुंजी-स्पर्श ध्वनि आवाज़"</string>
diff --git a/java/res/values-hr/strings-action-keys.xml b/java/res/values-hr/strings-action-keys.xml
index 564f70363..c13da1897 100644
--- a/java/res/values-hr/strings-action-keys.xml
+++ b/java/res/values-hr/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Pret."</string>
<string name="label_done_key" msgid="7564866296502630852">"Got."</string>
<string name="label_send_key" msgid="482252074224462163">"Poš."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauz."</string>
<string name="label_wait_key" msgid="5891247853595466039">"Čekaj"</string>
</resources>
diff --git a/java/res/values-hr/strings-talkback-descriptions.xml b/java/res/values-hr/strings-talkback-descriptions.xml
index 31c7eb5f8..b3d5f707c 100644
--- a/java/res/values-hr/strings-talkback-descriptions.xml
+++ b/java/res/values-hr/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nije unesen tekst"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ispravlja <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> u <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> vrši samoispravljanje"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Kôd tipke %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Uključena je tipka Shift (dodirnite za onemogućivanje)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Uključeno je pisanje velikim slovima (Caps Lock) (dodirnite za onemogućivanje)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Više simbola"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simboli"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Brisanje"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simboli"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Slova"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Prethodna"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Omogućena je tipka Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Omogućen je Caps Lock"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Tipka Shift onemogućena je"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Način unosa simbola"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Način s više simbola"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Način unosa slova"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefonski način rada"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Način unosa telefonskih simbola"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Mjesta"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simboli"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikoni"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-hr/strings.xml b/java/res/values-hr/strings.xml
index 0882faad4..3d749e111 100644
--- a/java/res/values-hr/strings.xml
+++ b/java/res/values-hr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opcije ulaza"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Istraživanje naredbi dnevnika"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Potražite imena kontakata"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Provjera pravopisa upotrebljava unose iz vašeg popisa kontakata"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibracija pri pritisku na tipku"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Predlaži imena kontakata"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Upotreba imena iz Kontakata za prijedloge i ispravke"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Prilagođeni prijedlozi"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Točka s dva razmaka"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dvostrukim dodirivanjem razmaknice umeću se točka i razmak"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatsko pisanje velikih slova"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Jezici unosa"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Dodirnite ponovo za spremanje"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Rječnik je dostupan"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Omogući korisničke povratne informacije"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Pomozite u poboljšanju ovog uređivača načina unosa automatskim slanjem statistike upotrebe i izvješća o padu programa"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engleski (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engleski (SAD)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Omogući"</string>
<string name="not_now" msgid="6172462888202790482">"Ne sada"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Već postoji isti stil unosa: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način studije upotrebljivosti"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Odgoda dugog pritiska tipke"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Trajanje vibracije pritiska"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Glasnoća pritiska tipke"</string>
diff --git a/java/res/values-hu/strings-action-keys.xml b/java/res/values-hu/strings-action-keys.xml
index 257f30f34..94445f58b 100644
--- a/java/res/values-hu/strings-action-keys.xml
+++ b/java/res/values-hu/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Előző"</string>
<string name="label_done_key" msgid="7564866296502630852">"Kész"</string>
<string name="label_send_key" msgid="482252074224462163">"Küld"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Állj"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Vár"</string>
</resources>
diff --git a/java/res/values-hu/strings-talkback-descriptions.xml b/java/res/values-hu/strings-talkback-descriptions.xml
index ec2c353ab..cf505c472 100644
--- a/java/res/values-hu/strings-talkback-descriptions.xml
+++ b/java/res/values-hu/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nincs szöveg megadva"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> billentyű – <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> szóra javítja a következőt: <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> billentyű automatikus javítást végez"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Billentyűkód: %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"A Shift be van kapcsolva (érintse meg a kikapcsoláshoz)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"A Caps lock be van kapcsolva (érintse meg a kikapcsoláshoz)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"További szimbólumok"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Szimbólumok"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Törlés"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Szimbólumok"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Betűk"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Előző"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift bekapcsolva"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock bekapcsolva"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift kikapcsolva"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"„Szimbólumok” mód"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"További szimbólumok mód"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"„Betű” mód"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"„Telefon” mód"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"„Telefonos szimbólumok” mód"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Helyek"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Szimbólumok"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Hangulatjelek"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-hu/strings.xml b/java/res/values-hu/strings.xml
index 8a953ab9d..5691bf703 100644
--- a/java/res/values-hu/strings.xml
+++ b/java/res/values-hu/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Beviteli beállítások"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Naplózási parancsok"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Névjegyek keresése"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"A helyesírás-ellenőrző használja a névjegyek bejegyzéseit"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Rezgés gombnyomásra"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Javasolt névjegyek"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"A névjegyek használata a javaslatokhoz és javításokhoz"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Testreszabott javaslatok"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dupla szóköz: pont"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"A szóköz kétszeri megérintése beszúr egy pontot, majd egy szóközt"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatikusan nagy kezdőbetű"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Beviteli nyelvek"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Érintse meg újból a mentéshez"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Van elérhető szótár"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Felhasználói visszajelzés engedélyezése"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Segíthet a beviteli módszer szerkesztőjének javításában, ha engedélyezi a használati statisztikák és a hibajelentések automatikus elküldését."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Billentyűzettéma"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angol (brit)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angol (amerikai)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Engedélyezés"</string>
<string name="not_now" msgid="6172462888202790482">"Most nem"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ugyanez a bemenetstílus már létezik: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Használhatósági teszt"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Hosszú nyomás késleltetése"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Gombnyomás rezgési időtartama"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Gombnyomás hangereje"</string>
diff --git a/java/res/values-hy-rAM/strings-action-keys.xml b/java/res/values-hy-rAM/strings-action-keys.xml
index af9dd5d9d..574ae5a42 100644
--- a/java/res/values-hy-rAM/strings-action-keys.xml
+++ b/java/res/values-hy-rAM/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Նախորդը"</string>
<string name="label_done_key" msgid="7564866296502630852">"Պատրաստ է"</string>
<string name="label_send_key" msgid="482252074224462163">"Ուղարկել"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Դադարեցնել"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Սպասել"</string>
</resources>
diff --git a/java/res/values-hy-rAM/strings-emoji-descriptions.xml b/java/res/values-hy-rAM/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..f41f2fc96
--- /dev/null
+++ b/java/res/values-hy-rAM/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Հեղինակային իրավունքի նշան"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Գրանցված ապրանքանիշի նշան"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Կրկնակի բացականչական նշան"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Բացականչական հարցական նշան"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Ապրանքանշանի նշան"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Տեղեկատվական աղբյուր"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Ձախ-աջ սլաք"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Վեր-վար սլաք"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Սլաք դեպի հյուսիս-արևմուտք"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Սլաք դեպի հյուսիս-արևելք"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Սլաք դեպի հարավ-արևելք"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Սլաք դեպի հարավ-արևմուտք"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Կեռ ձախ սլաք"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Կեռ աջ սլաք"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"Ժամացույց"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Ավազի ժամացույց"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Դեպի աջ ուղղված սև կրկնակի եռանկյուն"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Դեպի ձախ ուղղված սև կրկնակի եռանկյուն"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Դեպի վեր ուղղված սև կրկնակի եռանկյուն"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Դեպի վար ուղղված սև կրկնակի եռանկյուն"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Զարթուցիչ"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Հոսող ավազով ժամացույց"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Շրջանաձև լատիներեն մեծատառ m"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Փոքր սև քառակուսի"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Փոքր սպիտակ քառակուսի"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Դեպի աջ ուղղված սև եռանկյուն"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Դեպի ձախ ուղղված սև եռանկյուն"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Միջին սպիտակ քառակուսի"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Միջին սև քառակուսի"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Միջին փոքր սպիտակ քառակուսի"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Միջին փոքր սև քառակուսի"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Սև արև` ճառագայթներով"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Ամպ"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Սև հեռախոս"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Քվեատուփ` նշանով"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Անձրևանոց` անձրևի կաթիլներով"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Տաք ըմպելիք"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Սպիտակ դեպի վեր ուղղված դասիչ"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Սպիտակ ժպտացող դեմք"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Խոյ"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Ցուլ"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Երկվորյակ"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Խեցգետին"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Առյուծ"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Կույս"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Կշեռք"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Կարիճ"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Աղեղնավոր"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Այծեղջյուր"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Ջրհոս"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Ձկներ"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Սև ագռավ"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Սև խաչ"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Սև սիրտ"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Սև աղյուս"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Տաք աղբյուրներ"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Սև վերամշակման նշան"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Սայլակի նշան"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Խարիսխ"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Զգուշացման նշան"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Բարձր լարման նշան"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Միջին սպիտակ շրջան"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Միջին սև շրջան"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Ֆուտբոլի գնդակ"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Բեյսբոլ"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Առանց ձյան ձնեմարդ"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Արևն ամպի ետևում"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Օձակալ"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Մուտք չկա"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Եկեղեցի"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Շատրվան"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Դրոշը փոսում"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Առագաստանավ"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Վրան"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Վառելիքի պոմպ"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Սև մկրատ"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Սպիտակ խոշոր ստուգանիշ"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Ինքնաթիռ"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Ծրար"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Բարձրացրած բռունցք"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Բարձրացրած ձեռք"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Հաղթանշան"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Մատիտ"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Սև գրչածայր"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Խոշոր ստուգանիշ"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Խոշոր բազմապատկում x"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Կայծեր"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Ութանկյուն աստղանիշ"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Ութ կետով սև աստղ"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Ձյան փաթիլ"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Կայծ"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Խաչանշան"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Բացասական քառակուսի խաչանշան"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Սև հարցական նշաններով նախշազարդ"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Սպիտակ հարցական նշաններով նախշազարդ"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Սպիտակ բացականչական նշաններով նախշազարդ"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Խոշոր բացականչական նշան"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Սև սիրտ"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Խոշոր գումարման նշան"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Խոշոր հանման նշան"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Խոշոր բաժանման նշան"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Սև դեպի աջ սլաք"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Խուճուճ հանգույց"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Կրկնակի խուճուճ հանգույց"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Դեպի աջ ուղղված, ապա դեպի վեր ծռված սլաք"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Դեպի աջ ուղղված, ապա դեպի վար ծռված սլաք"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Դեպի ձախ սև սլաք"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Դեպի վեր սև սլաք"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Դեպի վար սև սլաք"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Մեծ սև քառակուսի"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Մեծ սպիտակ քառակուսի"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Միջին սպիտակ քառակուսի"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Խոշոր շրջան"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Ալիքաձև գծիկ"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Երաժշտական փոփոխականի նշան"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Շնորհավորանքի շրջանաձև խորհրդանշան"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Գաղտնիքի շրջանաձև խորհրդանշան"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Մահջոնգի սալիկ՝ կարմիր վիշապով"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Սև ջոկեր խաղաքարտ"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Արյան Ա խումբ"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Արյան Բ խումբ"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Արյան Օ խումբ"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Ավտոկայանատեղի"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Արյան ԱԲ խումբ"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"Քառակուսի CL"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Քառակուսի COOL"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Քառակուսի FREE"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"Քառակուսի ID"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"Քառակուսի NEW"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"Քառակուսի NG"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"Քառակուսի OK"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"Քառակուսի SOS"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"Քառակուսի UP բացականչական նշանով"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"Քառակուսի vs"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Քառակուսի Կատականա այստեղ"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Քառակուսի Կատականա ծառայություն"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Քառակուսի խորհրդանշան անվճար"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Քառակուսի խորհրդանշան պահված տեղ"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Քառակուսի խորհրդանշան արգելում"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Քառակուսի խորհրդանշան թափուր աշխատատեղ"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Քառակուսի խորհրդանշան ընդունված"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Քառակուսի խորհրդանշան լրիվ զբաղվածություն"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Քառակուսի խորհրդանշան վճարված"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Քառակուսի խորհրդանշան ամսական"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Քառակուսի խորհրդանշան դիմում"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Քառակուսի խորհրդանշան զեղչ"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Քառակուսի խորհրդանշան աշխատում է"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Շրջանաձև խորհրդանշան առավելություն"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Շրջանաձև խորհրդանշան ընդունում"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Ցիկլոն"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Մառախլապատ"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Փակ անձրևանոց"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Աստղազարդ գիշեր"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Արևածագը լեռներում"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Արևածագ"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Քաղաքը մթնշաղում"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Մայրամուտը շենքերի վրա"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Ծիածան"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Կամուրջը գիշերը"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Ծովի ալիք"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Հրաբուխ"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Ծիր կաթին"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Երկրագունդը՝ Եվրոպա-Աֆրիկա"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Երկրագունդը՝ Ամերիկաներ"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Երկրագունդը՝ Ավստրալիա"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Երկրագունդը միջօրեականներով"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Նորալուսնի նշան"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Աճող կիսալուսնի նշան"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"Լուսնի առաջին քառորդի նշան"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Աճող ուռուցիկ լուսնի նշան"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Լիալուսնի նշան"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Փոքրացող ուռուցիկ լուսնի նշան"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Լուսնի վերջին քառորդի նշան"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Փոքրացող կիսալուսնի նշան"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Կիսալուսին"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Դեմքով նորալուսին"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Առաջին քառորդ լուսին՝ դեմքով"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Վերջին քառորդ լուսին՝ դեմքով"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Դեմքով լիալուսին"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Դեմքով արև"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Փայլուն աստղ"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Կրակող աստղ"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Շագանակ"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Սածիլ"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Մշտադալար ծառ"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Տերևաշատ ծառ"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Պալմա"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Կակտուս"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Կակաչ"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Բալենու ծաղիկ"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Վարդ"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Հիբիսկուս"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Արևածաղիկ"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Ծաղիկ"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Եգիպտացորեն"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Բրինձ"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Խոտաբույս"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Քառատերև երեքնուկ"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Թխկու տերև"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Թափված տերև"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Քամուց թռչող տերև"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Սունկ"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Լոլիկ"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Սմբուկ"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Խաղող"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Սեխ"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Ձմերուկ"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Մանդարին"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Կիտրոն"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Բանան"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Արքայախնձոր"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Կարմիր խնձոր"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Կանաչ խնձոր"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Տանձ"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Դեղձ"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Բալ"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Ելակ"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Համբուրգեր"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Պիցցայի կտոր"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Ոսկորով միս"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Հավի բուդ"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Բրնձի կրեկեր"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Բրնձի կլորակ"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Եփած բրինձ"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Քարի և բրինձ"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Գոլորշիացող բաժակ"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Սպագետտի"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Հաց"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Տապակած կարտոֆիլ"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Տապակած քաղցր կարտոֆիլ"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Դանգո"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Օդեն"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Սուշի"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Տապակած ծովախեցգետին"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Ձկան տորթ՝ օղակաձև ձևավորմամբ"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Լցնովի պաղպաղակ"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Սառցե դեսերտ"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Պաղպաղակ"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Դոնաթ"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Թխվածքաբլիթ"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Շոկոլադի սալիկ"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Կոնֆետ"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Սառնաշաքար կոնֆետ"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Եփովի կրեմ"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Մեղրանոթ"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Տորթի կտոր"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Բենտոյով տուփ"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Սնունդով լի ափսե"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Խոհարարություն"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Դանակ և պատառաքաղ"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Թեյի անպոչ բաժակ"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Սակեի շիշ և գավաթ"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Գինու գավաթ"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Կոկտեյլի բաժակ"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Արևադարձային խմիչք"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Գարեջրի բաժակ"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Զրնգացող գարեջրի բաժակներ"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Մանկական շիշ"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Ժապավեն"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Փաթեթավորված նվեր"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Ծննդյան տորթ"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Դդմի լապտեր"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Տոնածառ"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Ձմեռ պապ"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Հրավառություն"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Բենգալյան կրակ"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Փուչիկ"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Ճայթուկ"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Կոնֆետտի գնդակ"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Տանաբատա ծառ"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Հատվող դրոշներ"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Սոճու ձևավորում"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Ճապոնական տիկնիկներ"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Կարպ նավադրոշ"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Քամու երգ"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Լուսնի դիտման արարողություն"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Դպրոցական պայուսակ"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Ավարտական ​​գլխարկ"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Ձի կարուսել"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Սատանայի անիվ"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Ուրախ սարեր"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Ձկնորսական կարթ և ձուկ"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Բարձրախոս"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Տեսախցիկ"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Կինոթատրոն"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Ականջակալ"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Ներկապնակ"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Ցիլինդր"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Կրկեսային վրան"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Տոմս"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Ծափափեղկ"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Կատարողական արվեստ"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Տեսախաղ"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Ուղղակի հարված"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Խաղասարք"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Բիլիարդ"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Խաղազառ"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Բոուլինգ"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Ծաղկով խաղաքարտեր"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Երաժշտական ձայնանիշ"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Մի քանի երաժշտական ձայնանիշ"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Սաքսոֆոն"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Կիթառ"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Երաժշտական ստեղնաշար"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Շեփոր"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Ջութակ"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Նոտագրում"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Վազքի վերնաշապիկ"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Թենիսի թիակ և գնդակ"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Դահուկ և դահուկի կոշիկ"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Բասկետբոլի գնդակ և զամբյուղ"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Վերջնակետի դրոշ"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Ձնատախտակորդ"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Վազորդ"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Ալեսահորդ"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Մրցանակ"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Ձիարշավ"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Ամերիկյան ֆուտբոլ"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Ռեգբի"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Լողորդ"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Բնակելի շենք"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Այգով տուն"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Գրասենյակային շենք"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Ճապոնական փոստատուն"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Եվրոպական փոստատուն"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Հիվանդանոց"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Բանկ"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Բանկոմատ"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Հյուրանոց"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Սիրո հյուրանոց"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Պարենային խանութ"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Դպրոց"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Հանրախանութ"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Գործարան"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Ճապոնական լապտեր"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Ճապոնական ամրոց"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Եվրոպական ամրոց"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Առնետ"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Մուկ"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Եզ"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Գոմեշ"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Կով"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Ընձառյուծ"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Ճագար"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Կատու"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Վիշապ"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Կոկորդիլոս"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Կետ"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Խխունջ"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Օձ"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Ձի"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Խոյ"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Այծ"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Ոչխար"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Կապիկ"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Աքաղաղ"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Հավ"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Շուն"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Խոզ"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Վարազ"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Փիղ"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Ութոտնուկ"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Պարուրաձև խեցի"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Բզեզ"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Մրջյուն"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Մեղու"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Զատիկ"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Ձուկ"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Արևադարձային ձուկ"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Գնդաձուկ"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Կրիա"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Թուխսի ճուտ"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Ճուտիկ"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Դիմահայաց ճուտիկ"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Թռչուն"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Պինգվին"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Կոալա"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Պուդել"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Դրոմադեր ուղտ"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Երկսապատանի ուղտ"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Դելֆին"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Մկան մռութ"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Կովի մռութ"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Վագրի մռութ"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Ճագարի մռութ"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Կատվի մռութ"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Վիշապի մռութ"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Թռչող կետ"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Ձիու մռութ"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Կապիկի մռութ"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"Շան մռութ"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Խոզի մռութ"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Գորտի մռութ"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Գերմանամկան դեմք"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Գայլի մռութ"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Արջի մռութ"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Պանդայի մռութ"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Խոզի քիթ"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Թաթի հետքեր"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Աչքեր"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Ականջ"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Քիթ"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Բերան"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Լեզու"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Վեր ուղղված սպիտակ ցուցամատ"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Վար ուղղված սպիտակ ցուցամատ"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Ձախ ուղղված սպիտակ ցուցամատ"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Աջ ուղղված սպիտակ ցուցամատ"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Բռունցքի նշան"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Թափահարող ձեռքի նշան"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"Ok-ի նշան"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Բութ մատները վեր նշան"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Բութ մատները վար նշան"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Ծափահարող ձեռքերի նշան"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Բաց ափերով ձեռքերի նշան"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Թագ"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Կնոջ գլխարկ"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Ակնոց"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Փողկապ"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"Շապիկ"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Ջինս"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Զգեստ"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Կիմոնո"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Բիկինի"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Կնոջ հագուստ"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Դրամապանակ"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Պայուսակ"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Քսակ"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Տղամարդու կոշիկ"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Մարզակոշիկ"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Բարձրակրունկ կոշիկ"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Կնոջ սանդալներ"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Կնոջ երկարաճիտ կոշիկներ"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Ոտնահետքեր"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Կիսանդրու ուրվագիծ"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Կիսանդրիների ուրվագիծ"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Տղա"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Աղջիկ"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Տղամարդ"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Կին"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Ընտանիք"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Միացված ձեռքերով տղամարդ և կին"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Միացված ձեռքերով երկու տղամարդ"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Միացված ձեռքերով երկու կին"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Ոստիկան"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Նապաստակի ականջներով կին"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Քողով հարսնացու"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Շիկահեր մարդ"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Չինական գլխարկով տղամարդ"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Գլխաշորով տղամարդ"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Ծեր տղամարդ"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Ծեր կին"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Մանուկ"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Շինարար"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Արքայադուստր"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Ճապոնական օգր"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Ճապոնական գոբլին"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Ուրվական"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Մանուկ հրեշտակ"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Այլմոլորակային"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Այլմոլորակային հրեշ"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Սատանայի ճուտ"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Գանգ"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Տեղեկատու անձ"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Պահնորդ"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Պարող"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Շրթներկ"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Եղունգաներկ"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Դեմքի մերսում"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Սանրվածք"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Վարսավիրի նշան"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Ներարկիչ"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Հաբ"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Համբույրի նշան"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Սիրային նամակ"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Մատանի"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Թանկարժեք քար"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Համբույր"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Ծաղկեփունջ"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Զույգը սրտի մեջ"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Հարսանիք"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Բաբախող սիրտ"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Կոտրված սիրտ"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Երկու սրտեր"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Պսպղացող սիրտ"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Աճող սիրտ"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Խոցված սիրտ"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Կապույտ սիրտ"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Կանաչ սիրտ"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Դեղին սիրտ"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Մանուշակագույն սիրտ"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Ժապավենով սիրտ"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Միացող սրտեր"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Սրտիկներով ձևավորում"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Շեղանկյուն` կետիկով"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Էլեկտրական լամպ"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Ջղայնության նշան"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Ռումբ"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Քնի նշան"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Բախման նշան"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Հոսող քրտինքի նշան"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Կաթիլ"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Գծիկի նշան"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Կեղտի կույտ"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Լարված երկգլուխ մկան"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Գլխապտույտի նշան"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Խոսքի փուչիկ"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Մտքի փուչիկ"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Սպիտակ ծաղիկ"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Հարյուր միավորի նշան"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Փողի քսակ"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Արտարժույթի փոխանակում"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Խոշոր դոլարի նշան"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Վարկային քարտ"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Իենի նշանով թղթադրամ"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Դոլարի նշանով թղթադրամ"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Եվրոյի նշանով թղթադրամ"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Ֆունտի նշանով թղթադրամ"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Թևավոր թղթադրամ"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Աճման միտումով և իենի նշանով գրաֆիկ"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Նստատեղ"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Անհատական համակարգիչ"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Թղթապանակ"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Փոքր սկավառակ"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Ճկուն սկավառակ"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Օպտիկական սկավառակ"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Ֆայլերի թղթապանակ"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Ֆայլերի բաց թղթապանակ"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Ոլորված ծայրով էջ"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Թեքված էջ"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Օրացույց"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Պոկվող էջերով օրացույց"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Քարտային դասիչ"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Աճման միտումով գրաֆիկ"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Նվազման միտումով գրաֆիկ"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Ձողային գրաֆիկ"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Սեղմատախտակ"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Սևեռակ"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Կլոր սևեռակ"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Ամրակ"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Ուղիղ քանոն"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Եռանկյուն քանոն"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Էջանիշ"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Մատյան"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Նոթատետր"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Ձևավոր կազմով նոթատետր"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Փակ գիրք"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Բաց գիրք"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Կանաչ գիրք"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Կապույտ գիրք"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Նարնջագույն գիրք"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Գրքեր"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Անվանաքարտ"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Գալար"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Հիշեցում"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Լսափող"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Փեյջեր"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Հեռապատճենի սարք"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Արբանյակային ալեհավաք"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Հրապարակային բարձրախոս"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Ուրախ բարձրախոս"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Ելքային արկղ"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Մուտքային արկղ"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Փաթեթ"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"Էլփոստի նշան"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Մուտքային ծրար"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Վերևից դեպի վար սլաքով ծրար"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Իջեցված դրոշով փակ փոստարկղ"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Բարձրացված դրոշով փակ փոստարկղ"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Բարձրացված դրոշով փակ փոստարկղ"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Իջեցված դրոշով բաց փոստարկղ"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Փոստարկղ"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Փոստային եղջյուր"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Թերթ"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Բջջային հեռախոս"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Բջջային հեռախոս՝ ձախ կողմում դեպի վեր սլաքով"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Թրթռոցի ռեժիմ"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Բջջային հեռախոսը` անջատած"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Բջջային հեռախոսներ չկան"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Ձողերով ալեհավաք"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Ֆոտոխցիկ"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Տեսախցիկ"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Հեռուստատեսություն"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Ռադիո"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Տեսաժապավեն"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Պտտված դեպի աջ սլաքներ"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Ժամացույցի սլաքի ուղղությամբ դեպի աջ և ձախ բաց շրջանաձև սլաքներ"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Ժամացույցի սլաքի ուղղությամբ դեպի աջ և ձախ բաց շրջանաձև սլաքներ՝ շրջանաձև մեկ վերադրումով"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Ժամացույցի սլաքի ուղղությամբ դեպի վար և վեր բաց շրջանաձև սլաքներ"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Ժամացույցի սլաքի հակառակ ուղղությամբ դեպի վար և վեր բաց շրջանաձև սլաքներ"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Ցածր պայծառության նշան"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Բարձր պայծառության նշան"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Չեղարկման գծով բարձրախոս"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Բարձրախոս"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Մեկ ձայնային ալիքով բարձրախոս"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Երեք ձայնային ալիքով բարձրախոս"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Մարտկոց"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Էլեկտրական խրոցակ"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Ձախ թեքված խոշորացույց"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Աջ թեքված խոշորացույց"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Կողպեք և թանաքի գրիչ"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Փակված կողպեք՝ բանալիով"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Բանալի"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Կողպեք"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Բաց կողպեք"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Զանգ"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Չեղարկման գծով զանգ"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Էջանիշ"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Հղման նշան"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Կետակոճակ"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Հետ՝ վերևում դեպի ձախ սլաքով"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"Վերջ՝ վերևում դեպի ձախ սլաքով"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"Միացված է՝ բացականչական նշանով և վերևում դեպի աջ ու ձախ սլաքով"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Շուտով՝ վերևում դեպի աջ սլաքով"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Վերև՝ վերևում դեպի վեր սլաքով"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"Տասնութից ցածրի արգելման նշան"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Ստեղնատասնյակ"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Լատիներեն մեծատառերով մուտքագրման նշան"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Լատիներեն փոքրատառերով մուտքագրման նշան"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Թվային մուտքագրման նշան"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Նշանների ներածման նշան"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Լատինատառ մուտքագրման նշան"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Կրակ"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Էլեկտրական լապտեր"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Ոլորակ"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Մուրճ"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Մանեկ ու պտուտակ"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Ճապոնական դանակ"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Ատրճանակ"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Մանրադիտակ"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Հեռադիտակ"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Ապակե գնդակ"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Միջակետով վեցանկյուն աստղ"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Ճապոնական սկսնակի նշան"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Եռաժանու նշան"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Սև քառակուսի կոճակ"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Սպիտակ քառակուսի կոճակ"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Մեծ կարմիր շրջան"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Մեծ կապույտ շրջան"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Մեծ նարնջագույն շեղանկյուն"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Մեծ կապույտ շեղանկյուն"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Փոքր նարնջագույն շեղանկյուն"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Փոքր կապույտ շեղանկյուն"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Վեր ուղղված կարմիր եռանկյուն"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Վար ուղղված կարմիր եռանկյուն"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Վեր ուղղված փոքր կարմիր եռանկյուն"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Վար ուղղված փոքր կարմիր եռանկյուն"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Թվատախտակ՝ ժամը մեկով"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Թվատախտակ՝ ժամը երկուսով"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Թվատախտակ՝ ժամը երեքով"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Թվատախտակ՝ ժամը չորսով"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Թվատախտակ՝ ժամը հինգով"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Թվատախտակ՝ ժամը վեցով"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Թվատախտակ՝ ժամը յոթով"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Թվատախտակ՝ ժամը ութով"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Թվատախտակ՝ ժամը ինով"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Թվատախտակ՝ ժամը տասով"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Թվատախտակ՝ ժամը տասնմեկով"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Թվատախտակ՝ ժամը տասներկուսով"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Թվատախտակ՝ ժամը մեկն անց երեսուն"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Թվատախտակ՝ ժամը երկուսն անց երեսուն"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Թվատախտակ՝ ժամը երեքն անց երեսուն"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Թվատախտակ՝ ժամը չորսն անց երեսուն"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Թվատախտակ՝ ժամը հինգն անց երեսուն"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Թվատախտակ՝ ժամը վեցն անց երեսուն"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Թվատախտակ՝ ժամը յոթն անց երեսուն"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Թվատախտակ՝ ժամը ութն անց երեսուն"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Թվատախտակ՝ ժամը ինն անց երեսուն"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Թվատախտակ՝ ժամը տասն անց երեսուն"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Թվատախտակ՝ ժամը տասնմեկն անց երեսուն"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Թվատախտակ՝ ժամը տասներկուսն անց երեսուն"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Ֆուձի լեռ"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Տոկիոյի աշտարակ"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Ազատության արձան"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Ճապոնիայի ուրվագիծ"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Մայաների քարե արձան"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Քմծիծաղով դեմք"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Քմծիծաղով դեմք՝ ժպտացող աչքերով"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Ուրախության արցունքներով դեմք"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Ժպտացող դեմք՝ բաց բերանով"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Ժպտացող դեմք՝ բաց բերանով և ժպտացող աչքերով"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Ժպտացող դեմք՝ բաց բերանով և սառը քրտինքով"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Ժպտացող դեմք՝ բաց բերանով և պինդ փակված աչքերով"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Ժպտացող դեմք` լուսապսակով"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Ժպյտացող դեմք` պոզերով"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Աչքով անող դեմք"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Ժպտացող դեմք` ժպտացող աչքերով"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Համեղ ուտեստներ վայելող դեմք"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Հանգստացած դեմք"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Ժպտացող դեմք` սրտաձև աչքերով"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Ժպտացող դեմք` արևային ակնոցով"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Հեգնական ժպիտով դեմք"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Չեզոք դեմք"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Արտահայտությունից զուրկ դեմք"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Չհետաքրքրված դեմք"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Սառը քրտինքով դեմք"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Մտախոհ դեմք"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Շփոթված դեմք"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Մոլորված դեմք"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Համբուրող դեմք"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Օդային համբույր ուղարկող դեմք"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Համբուրող դեմք` ժպտացող աչքերով"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Համբուրող դեմք` փակ աչքերով"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Լեզուն հանած դեմք"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Լեզուն հանած և աչքով անող դեմք"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Լեզուն հանած և աչքերը փակած դեմք"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Հիասթափված դեմք"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Մտահոգ դեմք"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Ջղային դեմք"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Շրթունքներն ուռած դեմք"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Լացող դեմք"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Կամակոր դեմք"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Հաղթական արտահայտությամբ դեմք"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Հիասթափված, բայց հանգստացած դեմք"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Բաց բերանով խոժոռ դեմք"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Տանջված դեմք"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Վախեցած դեմք"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Հոգնած դեմք"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Քնաթաթախ դեմք"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Հոգնած դեմք"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Ծամածռված դեմք"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Բարձրաձայն լացող դեմք"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Բաց բերանով դեմք"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Լռող դեմք"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Բաց բերանով և սառը քրտինքով դեմք"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Վախից ճչացող դեմք"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Ապշած դեմք"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Շիկնած դեմք"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Քնած դեմք"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Գլխապտույտով դեմք"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Առանց բերանի դեմք"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Բժշկական դիմակով դեմք"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Քմծիծաղող կատվի դեմք՝ ժպտացող աչքերով"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Կատվի դեմք՝ երջանկության արցունքներով"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Ժպտացող կատվի դեմք՝ բաց բերանով"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Ժպտացող կատվի դեմք՝ սրտաձև աչքերով"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Կատվի դեմք՝ ծուռ ժպիտով"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Համբուրող կատվի դեմք՝ փակ աչքերով"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Շրթունքներն ուռած կատվի դեմք"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Լացող կատվի դեմք"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Հոգնած կատվի դեմք"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"«Ոչ լավ» արտահայտությամբ դեմք"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"«Լավ» արտահայտությամբ դեմք"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Կռացած դեմք"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Աչքերը ձեռքերով փակած կապիկ"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Ականջները ձեռքերով փակած կապիկ"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Բերանը ձեռքերով փակած կապիկ"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Երջանիկ մարդ` բարձրացրած ձեռքով"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Երկու ձեռքը ողջույնի համար բարձրացրած մարդ"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Դժգոհ մարդ"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Շրթունքներն ուռեցրած դեմքով մարդ"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Ծալված ձեռքերով մարդ"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Հրթիռ"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Ուղղաթիռ"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Շոգեքարշ"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Վագոն"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Ճեպընթաց գնացք"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Ճեպընթաց գնացք` փամփուշտաձև քթով"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Գնացք"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Մետրո"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Մոնոռելս"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Կայան"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Տրամվայ"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Տրամվայ"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Ավտոբուս"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Հանդիպակաց ավտոբուս"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Տրոլեյբուս"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Ավտոբուսի կանգառ"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Միկրոավտոբուս"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Շտապ օգնություն"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Հրշեջ մեքենա"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Ոստիկանական մեքենա"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Հանդիպակաց եկող ոստիկանական մեքենա"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Տաքսի"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Հանդիպակաց եկող տաքսի"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Ավտոմեքենա"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Հանդիպակաց եկող ավտոմեքենա"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Ավտոտնակ"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Առաքման մեքենա"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Ինքնագնաց"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Տրակտոր"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Մոնոռելս"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Լեռնային երկաթուղի"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Երկաթուղային կախոց"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Լեռնային ճոպանուղի"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Ճոպանուղի"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Նավ"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Լաստանավ"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Մոտորանավ"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Հորիզոնական լուսացույց"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Ուղղահայաց լուսացույց"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Շինարարության նշան"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Ոստիկականան մեքենայի ազդանշանային լույսեր"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Եռանկյուն դրոշ"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Դուռ"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Չմտնելու նշան"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Ծխելու նշան"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Չծխելու նշան"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Աղբը իր տեղում թափելու նշան"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Աղբ չթափելու նշան"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Խմելու ջրի նշան"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Ոչ խմելու ջրի նշան"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Հեծանիվ"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Հեծանիվների արգելք"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Հեծանվորդ"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Լեռնային հեծանվորդ"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Հետիոտն"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Հետիոտների արգելք"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Հատող երեխաներ"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Տղամարդկանց նշան"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Կանանց նշան"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Զուգարան"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Մանուկի նշան"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Զուգարան"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"Արտաքնոց"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Ցնցուղ"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Բաղնիք"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Լոգարան"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Անձնագրերի ստուգում"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Մաքսատուն"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Ուղեբեռի ստացում"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Ձախ ուղեբեռ"</string>
+</resources>
diff --git a/java/res/values-hy-rAM/strings-talkback-descriptions.xml b/java/res/values-hy-rAM/strings-talkback-descriptions.xml
index e5b1ce6d9..5b7e4b522 100644
--- a/java/res/values-hy-rAM/strings-talkback-descriptions.xml
+++ b/java/res/values-hy-rAM/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Տեքստ չի մուտքագրվել"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g>-ը շտկում է <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>-ը՝ դարձնելով <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ստեղնը ինքնաշտկում է կատարում"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Բանալու կոդը՝ %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift-ը միացված է (հպել անջատելու համար)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock-ը միացված է (հպել՝ անջատելու համար)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Հավելյալ նշաններ"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Նշաններ"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Ջնջել"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Նշաններ"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Տառեր"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Նախորդը"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift-ը միացված է"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock-ը միացված է"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift-ն անջատված է"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Նշանների ռեժիմ"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Հավելյալ նշանների ռեժիմ"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Տառերի ռեժիմ"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Հեռախոսային ռեժիմ"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Հեռախոսի նշանների ռեժիմ"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Վայրեր"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Նշաններ"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Զմայլիկներ"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-hy-rAM/strings.xml b/java/res/values-hy-rAM/strings.xml
index 03d56a626..d7851b540 100644
--- a/java/res/values-hy-rAM/strings.xml
+++ b/java/res/values-hy-rAM/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Ներածման ընտրանքներ"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Հետազոտական գրառումների հրամաններ"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Փնտրել կոնտակտային անուններ"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Տառասխալների ուղղիչն օգտագործում է ձեր կոնտակտների ցանկի տվյալները"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Թրթռալ սեղմման ժամանակ"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Առաջարկել կոնտակտների անունները"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Օգտագործել կոնտակտների անունները՝ առաջարկների և ուղղումների համար"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Անհատականացված առաջարկներ"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Կրկնաբացակի վերջակետ"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Բացակի ստեղնի կրկնակի հպումը բացակից հետո վերջակետ է դնում"</string>
<string name="auto_cap" msgid="1719746674854628252">"Ավտոմատ գլխատառացում"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Մուտքագրման լեզուներ"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Պահպանելու համար կրկին հպեք"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Բառարանն առկա է"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Միացնել օգտվողի արձագանքը"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Օգնել բարելավել այս մուտքագրման եղանակի խմբագրիչը՝ ինքնուրույն ուղարկելով Google-ին օգտագործման վիճակագրությունն ու վթարների հաշվետվությունները:"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Ստեղնաշարի թեման"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Անգլերեն (ՄԹ)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Անգլերեն (ԱՄՆ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Միացնել"</string>
<string name="not_now" msgid="6172462888202790482">"Ոչ հիմա"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Մուտքագրման այսպիսի ոճ արդեն գոյություն ունի՝ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Հարմարավետության ուսումնասիրության ռեժիմ"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ստեղնի երկար սեղմման ուշացում"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Սեղմման թրթռոցի տևողություն"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Սեղմման ձայնի բարձրությունը"</string>
diff --git a/java/res/values-in/strings-action-keys.xml b/java/res/values-in/strings-action-keys.xml
index 26f32254d..052798d02 100644
--- a/java/res/values-in/strings-action-keys.xml
+++ b/java/res/values-in/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Balik"</string>
<string name="label_done_key" msgid="7564866296502630852">"Beres"</string>
<string name="label_send_key" msgid="482252074224462163">"Kirim"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Jeda"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Tunggu"</string>
</resources>
diff --git a/java/res/values-in/strings-talkback-descriptions.xml b/java/res/values-in/strings-talkback-descriptions.xml
index 73bf712f3..6f2970795 100644
--- a/java/res/values-in/strings-talkback-descriptions.xml
+++ b/java/res/values-in/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Tidak ada teks yang dimasukkan"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> mengoreksi <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> menjadi <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> melakukan koreksi otomatis"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Kode tombol %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift aktif (ketuk untuk menonaktifkan)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock aktif (ketuk untuk menonaktifkan)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Simbol lainnya"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simbol"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Hapus"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simbol"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Huruf"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Sebelumnya"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift diaktifkan"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock diaktifkan"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift dinonaktifkan"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Mode simbol"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Mode simbol lainnya"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Mode huruf"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Mode telepon"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Mode simbol telepon"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Tempat"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simbol"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikon"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-in/strings.xml b/java/res/values-in/strings.xml
index e3c551629..3205a5db4 100644
--- a/java/res/values-in/strings.xml
+++ b/java/res/values-in/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opsi masukan"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Riset Perintah Log"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cari nama kontak"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Pemeriksa ejaan menggunakan entri dari daftar kontak Anda"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Getar jika tombol ditekan"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sarankan nama Kontak"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama dari Kontak untuk saran dan koreksi"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Saran hasil personalisasi"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Titik spasi ganda"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Mengetuk tombol spasi dua kali akan memasukkan titik diikuti satu spasi"</string>
<string name="auto_cap" msgid="1719746674854628252">"Kapitalisasi otomatis"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Bahasa masukan"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Sentuh lagi untuk menyimpan"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Kamus yang tersedia"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Aktifkan masukan pengguna"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Bantu tingkatkan editor metode masukan dengan mengirim statistik penggunaan dan laporan kerusakan secara otomatis"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema keyboard"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inggris (Inggris)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inggris (AS)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktifkan"</string>
<string name="not_now" msgid="6172462888202790482">"Nanti saja"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Sudah ada gaya masukan yang sama: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mode studi daya guna"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Penundaan tekan lama tombol"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durasi getar saat tekan tombol"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume suara saat tekan tombol"</string>
diff --git a/java/res/values-is/strings.xml b/java/res/values-is/strings.xml
index 1588534c9..ab2f2625a 100644
--- a/java/res/values-is/strings.xml
+++ b/java/res/values-is/strings.xml
@@ -22,7 +22,6 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- no translation found for english_ime_input_options (3909945612939668554) -->
<skip />
- <!-- no translation found for english_ime_research_log (8492602295696577851) -->
<skip />
<!-- no translation found for use_contacts_for_spellchecking_option_title (5374120998125353898) -->
<skip />
@@ -140,9 +139,7 @@
<skip />
<!-- no translation found for has_dictionary (6071847973466625007) -->
<skip />
- <!-- no translation found for prefs_enable_log (6620424505072963557) -->
<skip />
- <!-- no translation found for prefs_description_log (7525225584555429211) -->
<skip />
<!-- no translation found for keyboard_layout (8451164783510487501) -->
<skip />
@@ -198,7 +195,6 @@
<skip />
<!-- no translation found for custom_input_style_already_exists (8008728952215449707) -->
<skip />
- <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
<skip />
<!-- no translation found for prefs_key_longpress_timeout_settings (6102240298932897873) -->
<skip />
diff --git a/java/res/values-it/strings-action-keys.xml b/java/res/values-it/strings-action-keys.xml
index 02e7b9c94..0a0cf9b7b 100644
--- a/java/res/values-it/strings-action-keys.xml
+++ b/java/res/values-it/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Prec."</string>
<string name="label_done_key" msgid="7564866296502630852">"Fine"</string>
<string name="label_send_key" msgid="482252074224462163">"Invia"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pausa"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Attendi"</string>
</resources>
diff --git a/java/res/values-it/strings-talkback-descriptions.xml b/java/res/values-it/strings-talkback-descriptions.xml
index 760db696c..f9eeefea0 100644
--- a/java/res/values-it/strings-talkback-descriptions.xml
+++ b/java/res/values-it/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nessun testo inserito"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corregge <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> con <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> esegue la correzione automatica"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Codice tasto %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Maiusc"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Maiusc attivo (tocca per disattivare)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Blocco maiuscole attivo (tocca per disattivare)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Altri simboli"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Maiusc"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simboli"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Maiusc"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Elimina"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simboli"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Lettere"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Precedente"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Maiusc attivo"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Bloc Maiusc attivo"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Maiusc disattivato"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Modalità simboli"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modalità altri simboli"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Modalità lettere"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Modalità telefono"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Modalità simboli telefono"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Luoghi"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simboli"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticon"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-it/strings.xml b/java/res/values-it/strings.xml
index 6685095be..e51a87184 100644
--- a/java/res/values-it/strings.xml
+++ b/java/res/values-it/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opzioni inserimento"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Ricerca comandi di log"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cerca in nomi contatti"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"La funzione di controllo ortografico usa voci dell\'elenco contatti"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrazione tasti"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Suggerisci nomi di contatti"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizza nomi di Contatti per suggerimenti e correzioni"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Suggerimenti personalizz."</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Doppio spazio per punto"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Tocca due volte barra spaziatr. per inserire punto seguito da spazio"</string>
<string name="auto_cap" msgid="1719746674854628252">"Maiuscole automatiche"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Lingue comandi"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Tocca di nuovo per salvare"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dizionario disponibile"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Attiva commenti degli utenti"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Contribuisci a migliorare l\'editor del metodo di immissione inviando automaticamente statistiche sull\'utilizzo e rapporti sugli arresti anomali"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema della tastiera"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglese (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglese (USA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Attiva"</string>
<string name="not_now" msgid="6172462888202790482">"Non ora"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Esiste già uno stile di inuput uguale: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modalità Studio sull\'usabilità"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ritardo pressione lunga tasti"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Durata vibraz. pressione tasto"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume audio a pressione tasto"</string>
diff --git a/java/res/values-iw/strings-action-keys.xml b/java/res/values-iw/strings-action-keys.xml
index f0f466b8e..398c081d6 100644
--- a/java/res/values-iw/strings-action-keys.xml
+++ b/java/res/values-iw/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"הקודם"</string>
<string name="label_done_key" msgid="7564866296502630852">"בוצע"</string>
<string name="label_send_key" msgid="482252074224462163">"שלח"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"השהה"</string>
<string name="label_wait_key" msgid="5891247853595466039">"המתן"</string>
</resources>
diff --git a/java/res/values-iw/strings-talkback-descriptions.xml b/java/res/values-iw/strings-talkback-descriptions.xml
index e6344fb04..435aaba51 100644
--- a/java/res/values-iw/strings-talkback-descriptions.xml
+++ b/java/res/values-iw/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"לא הוזן טקסט"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> מתקן את <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> ל-<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> מבצע תיקון אוטומטי"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"‏קוד מקש %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"‏Shift פועל (הקש כדי להשבית)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"‏Caps Lock פועל (הקש כדי להשבית)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"סמלים נוספים"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"סמלים"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"מחק"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"סמלים"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"אותיות"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"הקודם"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"‏Shift פועל"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"‏Caps Lock פועל"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"‏Shift מושבת"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"מצב סמלים"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"מצב \'סמלים נוספים\'"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"מצב אותיות"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"מצב טלפון"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"מצב סמלי טלפון"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"מקומות"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"סמלים"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"רגשונים"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-iw/strings.xml b/java/res/values-iw/strings.xml
index dab2d8ed8..36cb66330 100644
--- a/java/res/values-iw/strings.xml
+++ b/java/res/values-iw/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"אפשרויות קלט"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"פקודות יומן מחקר"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"חפש שמות של אנשי קשר"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"בודק האיות משתמש בערכים מרשימת אנשי הקשר שלך"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"רטט בלחיצה על מקשים"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"הצע שמות של אנשי קשר"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"השתמש בשמות מרשימת אנשי הקשר עבור הצעות ותיקונים"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"הצעות מותאמות אישית"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"רווח כפול לנקודה"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"הקשה פעמיים על מקש הרווח מזינה נקודה ואחריה רווח"</string>
<string name="auto_cap" msgid="1719746674854628252">"הפיכת אותיות לרישיות באופן אוטומטי"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"שפות קלט"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"גע שוב כדי לשמור"</string>
<string name="has_dictionary" msgid="6071847973466625007">"מילון זמין"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"הפעל משוב ממשתמשים"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"עזור לשפר את עורך שיטת הקלט על ידי שליחה אוטומטית של סטטיסטיקת שימוש ודוחות קריסה."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"עיצוב מקלדת"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"אנגלית (בריטניה)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"אנגלית (ארה\"ב)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"הפעל"</string>
<string name="not_now" msgid="6172462888202790482">"לא עכשיו"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"סגנון קלט זהה כבר קיים: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"מצב לחקירת שימושיות"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"השהיית לחיצה ארוכה על מקש"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"משך רטט של לחיצת מקש"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"עוצמת קול של לחיצת מקש"</string>
diff --git a/java/res/values-ja/strings-action-keys.xml b/java/res/values-ja/strings-action-keys.xml
index 68aa6479e..ba8d06c78 100644
--- a/java/res/values-ja/strings-action-keys.xml
+++ b/java/res/values-ja/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"前へ"</string>
<string name="label_done_key" msgid="7564866296502630852">"完了"</string>
<string name="label_send_key" msgid="482252074224462163">"送信"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"停止"</string>
<string name="label_wait_key" msgid="5891247853595466039">"待機"</string>
</resources>
diff --git a/java/res/values-ja/strings-talkback-descriptions.xml b/java/res/values-ja/strings-talkback-descriptions.xml
index 990774e16..a3b4c8faa 100644
--- a/java/res/values-ja/strings-talkback-descriptions.xml
+++ b/java/res/values-ja/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"テキストが入力されていません"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g>は<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>を<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>に修正します"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g>で自動修正が実行されます"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"キーコード: %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift有効(タップして解除)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"CapsLock有効(タップして解除)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"記号拡張"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"記号"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"削除"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"記号"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"英字"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"前へ"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift有効"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"CapsLock有効"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift解除"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"記号モード"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"記号拡張モード"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"英数モード"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"電話モード"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"電話記号モード"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"場所"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"記号"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"絵文字"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ja/strings.xml b/java/res/values-ja/strings.xml
index 7d749a6a2..b6eea69dd 100644
--- a/java/res/values-ja/strings.xml
+++ b/java/res/values-ja/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"入力オプション"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"ログコマンドの検索"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"連絡先名の検索"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"スペルチェッカーでは連絡先リストのエントリを使用します"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"キー操作バイブ"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"連絡先の名前を候補に表示"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"連絡先の名前を使用して候補表示や自動修正を行います"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"入力候補のカスタマイズ"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"ダブルスペースピリオド"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"スペースバーをダブルタップするとピリオドとスペースを挿入できます"</string>
<string name="auto_cap" msgid="1719746674854628252">"自動大文字変換"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"入力言語"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"保存するにはもう一度タップ"</string>
<string name="has_dictionary" msgid="6071847973466625007">"辞書を利用できます"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"ユーザーフィードバックを有効にする"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"IMEの機能向上のため、使用統計状況やクラッシュレポートをGoogleに自動送信します。"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"キーボードのテーマ"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英語 (英国)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英語 (米国)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"有効にする"</string>
<string name="not_now" msgid="6172462888202790482">"後で行う"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"同じ入力スタイルが既に存在します: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"使いやすさの研究モード"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"キーの長押し時間"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"キー操作バイブの振動時間"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"キー操作音の音量"</string>
diff --git a/java/res/values-ka-rGE/strings-action-keys.xml b/java/res/values-ka-rGE/strings-action-keys.xml
index e2dd05f7b..3ad6c3395 100644
--- a/java/res/values-ka-rGE/strings-action-keys.xml
+++ b/java/res/values-ka-rGE/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"წინა"</string>
<string name="label_done_key" msgid="7564866296502630852">"დასრ."</string>
<string name="label_send_key" msgid="482252074224462163">"გაგზ."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"პაუზა"</string>
<string name="label_wait_key" msgid="5891247853595466039">"მოცდა"</string>
</resources>
diff --git a/java/res/values-ka-rGE/strings-emoji-descriptions.xml b/java/res/values-ka-rGE/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..1840efc10
--- /dev/null
+++ b/java/res/values-ka-rGE/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"საავტორო უფლების ნიშანი"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"რეგისტრირებული სავაჭრო ნიშნის სიმბოლო"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"ორმაგი ძახილის ნიშანი"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"ძახილის და კითხვის ნიშანი"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"სავაჭრო ნიშნის ნიშანი"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"ინფორმაციის წყარო"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"მარცხენა და მარჯვენა ისარი"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"ზედა და ქვედა ისარი"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"ჩრდილო დასავლეთის ისარი"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"ჩრდილო აღმოსავლეთის ისარი"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"სამხრეთ აღმოსავლეთის ისარი"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"სამხრეთ დასავლეთის ისარი"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"მარცხნივ მიმართული ისარი კაუჭით"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"მარჯვნივ მიმართული ისარი კაუჭით"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"საათი"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"ქვიშის საათი"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"მარჯვნივ მიმართული შავი ორმაგი სამკუთხედი"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"მარცხნივ მიმართული შავი ორმაგი სამკუთხედი"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"ზევით მიმართული შავი ორმაგი სამკუთხედი"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"ქვევით მიმართული შავი ორმაგი სამკუთხედი"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"მაღვიძარა"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"ქვიშის საათი ჩამოყრილი ქვიშით"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"წრეში ჩასმული ლათინური ასო m"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"შავი პატარა კვადრატი"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"თეთრი პატარა კვადრატი"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"შავი მარჯვნივ მიმართული სამკუთხედი"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"შავი მარცხნივ მიმართული სამკუთხედი"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"თეთრი საშუალო კვადრატი"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"შავი საშუალო კვადრატი"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"თეთრი საშუალო პატარა კვადრატი"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"შავი საშუალო პატარა კვადრატი"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"შავი მზე სხივებით"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"ღრუბელი"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"შავი ტელეფონი"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"მონიშნული საარჩევნო ბიულეტენი"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"ქოლგა წვიმის წვეთებით"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"ცხელი სასმელი"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"თეთრი ზევით მიმართული საჩვენებელი"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"თეთრი მომღიმარი სახე"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"ვერძი"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"კურო"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"ტყუპები"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"კირჩხიბი"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"ლომი"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"ქალწული"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"სასწორი"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"მორიელი"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"მშვილდოსანი"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"თხის რქა"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"მერწყული"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"თევზები"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"ბანქოს შავი ყვავი"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"ბანქოს შავი ჯვარი"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"ბანქოს შავი გული"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"ბანქოს შავი აგური"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"ცხელი წყარო"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"უნივერსალური გადამუშავების შავი სიმბოლო"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"სატარებელი სავარძლის სიმბოლო"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"ღუზა"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"გაფრთხილების ნიშანი"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"მაღალი ძაბვის ნიშანი"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"საშუალო თეთრი წრე"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"საშუალო შავი წრე"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"ფეხბურთის ბურთი"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"ბეისბოლის ბურთი"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"თოვლის კაცი თოვლის გარეშე"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"ღრუბელს მიფარებული მზე"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"გველისმჭერის თანავარსკვლავედი"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"შესვლა აკრძალულია"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"ეკლესია"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"შადრევანი"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"ალამი ორმოში"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"იალქნიანი გემი"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"კარავი"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"საწვავის სატუმბი"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"შავი მაკრატელი"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"თეთრი მკვეთრი მონიშვნის ნიშანი"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"თვითმფრინავი"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"კონვერტი"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"აღმართული მუშტი"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"აღმართული ხელი"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"გამარჯვების აღმნიშვნელი ხელი"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"ფანქარი"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"შავი კალმის წვერი"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"მკვეთრი მონიშვნის ნიშანი"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"მკვეთრი გამრავლების x"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"ნაპერწკლები"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"რვაწვერა ვარსკვლავი"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"რვაქიმიანი შავი ვარსკვლავი"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"ფიფქი"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"ნაპერწკალი"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"გადახაზვის ნიშანი"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"კვადრატში ჩასმული გადახაზული ნიშანი ნეგატივში"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"შავი კითხვის ნიშნის ორნამენტი"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"თეთრი კითხვის ნიშნის ორნამენტი"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"თეთრი ძახილის ნიშნის ორნამენტი"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"მკვეთრი ძახილის ნიშნის სიმბოლო"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"დიდი შავი გული"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"მკვეთრი პლუსის ნიშანი"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"მკვეთრი მინუსის ნიშანი"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"მკვეთრი გაყოფის ნიშანი"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"შავი მარჯვნივ მიმართული ისარი"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"მარყუჟი"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"ორმაგი მარყუჟი"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"მარჯვნივ მიმართული და ზევით მოხვეული ისარი"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"მარჯვნივ მიმართული და ქვევით მოხვეული ისარი"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"მარცხნივ მიმართული შავი ისარი"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"ზევით მიმართული შავი ისარი"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"მარცხნივ ქვევით მიმართული შავი ისარი"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"დიდი შავი კვადრატი"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"დიდი თეთრი კვადრატი"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"თეთრი საშუალო ვარსკვლავი"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"მკვეთრი დიდი წრე"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"ტალღოვანი ტირე"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"იორიტენი"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"მილოცვის იდეოგრაფი წრეში"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"საიდუმლოების იდეოგრაფი წრეში"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Mahjong მოზაიკის წითელი დრაკონი"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"ბანქოს შავი ჯოკერი"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"სისხლის ტიპი A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"სისხლის ტიპი B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"სისხლის ტიპი O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"პარკინგის ადგილი"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"სისხლის ტიპი AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"CL კვადრატში"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"cool კვადრატში"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"free კვადრატში"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"ID კვადრატში"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"new კვადრატში"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"N G კვადრატში"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"OK კვადრატში"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"SOS კვადრატში"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"up ძახილის ნიშნით კვადრატში"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"vs კვადრატში"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"katakana koko კვადრატში"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"katakana sa კვადრატში"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"CJK უნიფიცირებული იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"დაჯავშნილი ადგილის იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"პროჰიბიციის იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"ვაკანსიის იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"მიღების იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"დაკავებულობის იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"იდეოგრაფი გადახდილია კვადრატში"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"იდეოგრაფი ყოველთვიურად კვადრატში"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"იდეოგრაფი აპლიკაცია კვადრატში"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"ფასდაკლების იდეოგრაფი კვადრატში"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"იდეოგრაფი მუშაობს კვადრატში"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"უპირატესობის იდეოგრაფი წრეში"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"მიღების იდეოგრაფი წრეში"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"ციკლონი"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"ნისლიანი"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"დახურული ქოლგა"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"ვარსკვლავიანი ღამე"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"მზის ამოსვლა მთებზე"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"მზის ამოსვლა"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"ქალაქის პეიზაჟი შებინდებისას"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"მზის ჩასვლა შენობების ფონზე"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"ცისარტყელა"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"ხიდი ღამით"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"წყლის ტალღა"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"ვულკანი"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"ირმის ნახტომი"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"გლობუსი ევროპა-აფრიკა"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"გლობუსი ამერიკა"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"გლობუსი აზია-ავსტრალია"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"გლობუსი მერიდიანებით"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"ახალი მთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"შევსებადი ნახევარმთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"პირველი მეოთხედის მთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"მილევადი ნახევარმთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"სავსე მთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"შევსებადი კუზიანი მთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"ბოლო მეოთხედის მთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"შევსებადი ნახევარმთვარის სიმბოლო"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"ნახევარმთვარე"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"ახალი მთვარი სახით"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"პირველი მეოთხედის მთვარე სახით"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"ბოლო მეოთხედის მთვარე სახით"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"სავსე მთვარე სახით"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"მზე სახით"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"მოკიაფე ვარსკვლავი"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"ჩამოვარდნილი ვარსკვლავი"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"წაბლი"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"ნერგი"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"მარადმწვანე ხე"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"ფოთლოვანი ხე"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"პალმის ხე"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"კაქტუსი"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"ტიტა"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"აყვავებული ალუბალი"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"ვარდი"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"ჰიბისკუსი"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"მზესუმზირა"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"ყვავილობა"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"სიმინდის ტარო"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"ბრინჯის თავთავი"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"ბალახი"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"ოთხფოთლიანი სამყურა"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"ნეკერჩხლის ფოთოლი"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"ჩამოვარდნილი ფოთოლი"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"ქარში მოფრიალე ფოთოლი"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"სოკო"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"პომიდორი"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"ბადრიჯანი"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"ყურძენი"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"ნესვი"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"საზამთრო"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"მანდარინი"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"ლიმონი"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"ბანანი"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"ანანასი"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"წითელი ვაშლი"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"მწვანე ვაშლი"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"მსხალი"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"ატამი"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"ალუბალი"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"მარწყვი"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"ჰამბურგერი"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"პიცას ნაჭერი"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"ხორცი ძვალზე"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"ქათმის ბარკალი"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"ბრინჯის კრეკერი"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"ბრინჯის გუნდა"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"მოხარშული ბრინჯი"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"კარი და ბრინჯი"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"ორთქლიანი თასი"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"სპაგეტი"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"პური"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"კარტოფილი ფრი"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"შემწვარი ტკბილი კარტოფილი"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"დანგო"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"ოდენი"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"სუში"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"შემწვარი კრევეტი"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"ტორტი ლოკოკინის დიზაინით"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"ჩამოსასხმელი ნაყინი"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"გაცრილი ყინული"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"ნაყინი"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"დონატი"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"შინაური ნამცხვარი"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"შოკოლადის ფილა"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"კანფეტი"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"შაქარყინული"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"ნადუღის კრემი"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"თაფლის ქოთანი"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"ფხვიერი ნამცხვარი"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"ბენტოს ყუთი"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"საკვების თასი"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"სამზარეულო"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"დანა-ჩანგალი"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"ჩაის"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"საკეს ბოთლი და ჭიქა"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"ღვინის ჭიქა"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"კოქტეილის ჭიქა"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"ტროპიკული სასმელი"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"ლუდის კათხა"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"ლუდის კათხების მიჭახუნება"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"ჩვილის ბოთლი"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"ლენტი"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"შეფუთული საჩუქარი"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"დაბადების დღის ტორტი"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"ჯეკის ფარანი"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"ნაძვის ხე"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"თოვლის ბაბუა"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"ფეიერვერკი"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"ფეიერვერკის შუშხუნი"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"ბუშტი"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"სადღესასწაულო სატკაცუნო"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"კონფეტის ბურთი"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"ტანაბატას ტოტი"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"გადაჯვარედინებული დროშები"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"ფიჭვის დეკორაცია"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"იაპონური სათამაშოები"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"კარპას ალამი"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"ქარის ზარი"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"მთვარის ჭვრეტის ცერემონიალი"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"სკოლის ჩანთა"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"ოქსფორდის ქუდი"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"კარუსელის ცხენი"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"ეშმაკის ბორბალი"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"როლერკოსტერი"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"თევზი და ანკესი"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"მიკროფონი"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"კინოკამერა"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"კინოთეატრი"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"ყურსასმენი"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"მხატვრის პალიტრა"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"ცილინდრი"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"ცირკის კარავი"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"ბილეთი"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"კინოს ტკაცუნა"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"საშემსრულებლო ხელოვნება"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"ვიდეოთამაში"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"მიზანში გარტყმა"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"სლოტ-ავტომატი"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"ბილიარდი"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"კამათელი"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"ბოულინგი"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"ჰანაფუდა"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"მუსიკალური ნოტი"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"მუსიკალური ნოტები"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"საქსოფონი"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"გიტარა"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"კლავიშებიანი მუსიკალური ინსტრუმენტი"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"საყვირი"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"ვიოლინო"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"მუსიკალური ნოტები"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"სარბენი მაისური ლენტით"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"ტენისის ჩოგანი და ბურთი"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"თხილამური და ჩექმა"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"ბურთი და კალათა"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"კუბოკრული დროშა"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"სნოუბორდერი"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"მორბენალი"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"სერფერი"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"თასი"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"ცხენების დოღი"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"ამერიკული ფეხბურთის ბურთი"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"რაგბის ბურთი"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"მოცურავე"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"სახლის შენება"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"სახლი ბაღით"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"საოფისე შენობა"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"იაპონური ფოსტა"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"ევროპული ფოსტა"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"საავადმყოფო"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"ბანკი"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"ბანკომატი"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"სასტუმრო"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"სიყვარულის სასტუმრო"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"სადღეღამისო მაღაზია"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"სკოლა"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"უნივერსალური მაღაზია"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"ქარხანა"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"იზაკაიას ფარანი"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"იაპონური ციხე-სიმაგრე"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"ევროპული ციხე-სიმაგრე"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"ვირთხა"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"თაგვი"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"ხარი"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"აზიური კამეჩი"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"ძროხა"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"ლეოპარდი"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"კურდღელი"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"კატა"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"დრაკონი"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"ნიანგი"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"ვეშაპი"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"ლოკოკინა"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"გველი"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"ცხენი"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"ვერძი"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"თხა"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"ცხვარი"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"მაიმუნი"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"მამალი"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"ქათამი"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"ძაღლი"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"ღორი"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"დათვი"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"სპილო"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"რვაფეხა"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"სპირალური ნიჟარა"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"ხოჭო"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"ჭიანჭველა"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"ფუტკარი"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"ჭიამაია"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"თევზი"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"ტროპიკული თევზი"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"ზღარბთევზა"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"კუ"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"წიწილა და ნაჭუჭი"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"წიწილა"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"წიწილას სახე"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"ჩიტი"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"პინგვინი"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"კოალა"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"პუდელი"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"ცალკუზა აქლემი"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"ორკუზა აქლემი"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"დელფინი"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"თაგვის სახე"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"ძროხის სახე"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"ვეფხვის სახე"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"კურდღლის სახე"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"კატის სახე"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"დრაკონის სახე"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"მჩქეფარე ვეშაპი"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"ცხენის სახე"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"მაიმუნის სახე"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"ძაღლის სახე"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"ღორის სახე"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"ბაყაყის სახე"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"ზაზუნას სახე"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"მგლის სახე"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"დათვის სახე"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"პანდას სახე"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"ღორის ცხვირი"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"თათების კვალი"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"თვალები"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"ყური"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"ცხვირი"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"პირი"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"ენა"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"თეთრი ზევით მიმართული შეტრიალებული საჩვენებელი"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"თეთრი ქვევით მიმართული შეტრიალებული საჩვენებელი"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"თეთრი მარცხნივ მიმართული შეტრიალებული საჩვენებელი"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"თეთრი მარჯვნივ მიმართული შეტრიალებული საჩვენებელი"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"მომუშტული ხელი"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"ხელის დაქნევა"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"ხელის ნიშანი OK"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"მაღლა აწეული ცერი"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"დაბლა დაწეული ცერი"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"ტაშის დაკვრა"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"ღია ხელები"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"გვირგვინი"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"ქალის ქუდი"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"სათვალეები"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"ჰალსტუხი"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"მაისური"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"ჯინსი"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"კაბა"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"კიმონო"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"ბიკინი"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"ქალის ტანსაცმელი"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"საფულე"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"ხელჩანთა"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"ქისა"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"კაცის ფეხსაცმელი"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"სპორტული ფეხსაცმელი"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"მაღალქუსლიანი ფეხსაცმელი"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"ქალის სანდალი"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"ქალის ჩექმა"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"ფეხის კვალი"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"ბიუსტი სილუეტში"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"ბიუსეტები სილუეტში"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"ბიჭი"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"გოგო"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"კაცი"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"ქალი"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"ოჯახი"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"ხელჩაკიდებული ქალი და კაცი"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"ხელჩაკიდებული ორი კაცი"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"ხელჩაკიდებული ორი ქალი"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"პოლიციელი"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"ქალი კურდღის ყურებით"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"პატარძალი პირბადით"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"ქერათმიანი ადამიანი"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"კაცი გუა-პი-მაოს ქუდით"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"კაცი ჩალმით"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"ხანდაზმული ადამიანი"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"ხანდაზმული ქალი"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"ჩვილი"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"მშენებელი"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"პრინცესა"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"იაპონელი კაციჭამია"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"იაპონელი გობლინი"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"მოჩვენება"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"ჩვილი ანგელოზი"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"უცხოპლანეტელი"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"უცხოპლანეტელი მონსტრი"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"ჭინკა"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"თავის ქალა"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"ინფორმაციის პუნქტის თანამშრომელი"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"მცველი"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"მოცეკვავე"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"პომადა"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"მანიკური"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"სახის მასაჟი"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"ვარცხნილობა"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"დალაქის ბოძი"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"შპრიცი"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"აბი"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"კოცნის ნიშანი"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"სასიყვარულო წერილი"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"დარეკვა"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"ძვირფასი ქვა"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"კოცნა"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"ბუკეტი"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"წყვილი გულით"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"ქორწილი"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"მფეთქავი გული"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"გატეხილი გული"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"ორი გული"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"მღელვარე გული"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"დიდი გული"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"გული ისრით"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"ლურჯი გული"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"მწვანე გული"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"ყვითელი გული"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"მეწამული გული"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"გული ლენტით"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"მბრუნავი გულები"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"გულის დეკორაცია"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"ალმასის ფორმა შიგნით წერტილით"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"ნათურა"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"სიბრაზის სიმბოლო"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"ბომბი"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"ძილის სიმბოლო"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"დაჯახების სიმბოლო"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"დაღვრილი ოფლის სიმბოლო"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"წვეთი"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"შხაპის სიმბოლო"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"განავალი"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"დაჭიმული კუნთი"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"თავბრუსხვევის სიმბოლო"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"დიალოგის ბუშტი"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"ფიქრის ბუშტი"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"თეთრი ყვავილი"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"ასქულიანი სიმბოლო"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"ფულის ჩანთა"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"ვალუტის გაცვლა"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"დოლარის მუქი ნიშანი"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"საკრედიტო ბარათი"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"ბანკნოტი იენის ნიშნით"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"ბანკნოტი დოლარის ნიშნით"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"ბანკნოტი ევროს ნიშნით"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"ბანკნოტი ფუნტის ნიშნით"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"ფრთიანი ფული"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"მატებადი დიაგრამა იენის ნიშნით"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"ადგილი"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"პერსონალური კომპიუტერი"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"ქეისი"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Minidisc"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Floppy დიკსი"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"ოპტიკური დისკი"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"ფაილის საქაღალდე"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"ღია საქაღალდე"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"მოღუნული ქაღალდი"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"გვერდი პირაღმა"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"კალენდარი"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"მოსახევი კალენდარი"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"ბარათების ინდექსი"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"მატებადი დიაგრამა"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"კლებადი დიაგრამა"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"სვეტებიანი დიაგრამა"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"ფურცლის სამაგრი დაფა"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"საკანცელარიო ჭიკარტი"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"მომრგვალებული ჭიკარტი"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"ფურცლის საკინძი"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"სწორი სახაზავი"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"სამკუთხა სახაზავი"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"სანიშნის ყურები"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"დავთარი"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"რვეული"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"რვეული დეკორატიული ყდით"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"დახურული წიგნი"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"ღია წიგნი"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"მწვანე წიგნი"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"ლურჯი წიგნი"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"ნარინჯისფერი წიგნი"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"წიგნები"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"ბეჯი"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"გრაგნილი"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"ჩანაწერი"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"ყურმილი"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"პეიჯერი"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"ფაქსის აპარატი"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"სატელიტური ანტენა"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"რუპორი"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"გამამხნევებელი მეგაფონი"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"გამავალ წერილთა სათავსო"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"შემოსულების სათავსო"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"ამანათი"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"ელფოსტის სიმბოლო"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"შემომავალი კონვერტი"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"კონვერტი ქვედა ისრით ზევით"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"დახურული საფოსტო ყუთი დაშვებული ალმით"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"დახურული საფოსტო ყუთი აღმართული ალმით"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"ღია საფოსტო ყუთი აღმართული ალმით"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"ღია საფოსტო ყუთი დაშვებული ალმით"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"საფოსტო ყუთი"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"საფოსტო საყვირი"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"გაზეთი"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"მობილური ტელეფონი"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"მობილური ტელეფონი მარჯვნივ მიმართული ისრით მარცხნივ"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"ვიბრაციის რეჟიმი"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"მობილური ტელეფონის გამორთვა"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"მობილური ტელეფონები აკრძალულია"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"ანტენა სვეტებით"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"ფოტოაპარატი"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"ვიდეოკამერა"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"ტელევიზია"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"რადიო"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"ვიდეოკასეტა"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"გადაჯვარედინებული მარჯვნივ მიმართული ისრები"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"საათის მიმართულებით მარჯვენა და მარცხენა ღია წრიული ისრები"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"საათის მიმართულებით მარჯვენა და მარცხენა ღია წრიული ისრები, ერთიანით წრეში"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"საათის მიმართულებით ქვედა და ზედა ღია წრიული ისრები"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"საათის საწინააღმდეგო მიმართულებით ქვედა და ზედა ღია წრიული ისრები"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"დაბალი სიკაშკაშის სიმბოლო"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"მაღალი სიკაშკაშის სიმბოლო"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"ხაზგადასმული სპიკერი"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"სპიკერი"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"სპიკერი ხმის ერთი ტალღით"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"სპიკერი ხმის სამი ტალღით"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"ბატარეა"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"ელექტრონული შესაერთებელი"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"მარცხნივ მიმართული გამადიდებელი ლუპა"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"მარჯვნივ მიმართული გამადიდებელი ლუპა"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"საკეტი მელნის კალმით"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"დახურული საკეტი გასაღებით"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"გასაღები"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"საკეტი"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"ღია საკეტი"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"ზარი"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"ხაზგადასმული ზარი"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"სანიშნე"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"ბმულის სიმბოლო"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"არჩევანის ღილაკი"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Back მარცხენა ისრით ზევით"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"End მარცხენა ისრით ზევით"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"On ძახილის ნიშნით, მარცხენა მარჯვენა ისრით ზევით"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Soon მარჯვენა ისრით ზევით"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Top ზედა ისრით ზევით"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"18 წლამდე აკრძალვის სიმბოლო"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"კლავიში ათი"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"ლათინური დიდი ასოების შეყვანის სიმბოლო"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"ლათინური პატარა ასოების შეყვანის სიმბოლო"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"რიცხვების შეყვანის სიმბოლო"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"სიმბოლოთა შეყვანის სიმბოლო"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"ლათინური ასოების შეყვანის სიმბოლო"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"ხანძარი"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"ელექტრო ლამპარი"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"ქანჩი"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"ჩაქუჩი"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"თხილი და სამტვრევი"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"ჰოჩოს დანა"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"პისტოლეტი"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"მიკროსკოპი"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"ტელესკოპი"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"კრისტალის ბურთი"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"ექვსქიმა ვარსკვლავი შუა წერტილით"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"დამწყების იაპონური სიმბოლო"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"სამკაპის ემბლემა"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"შავი კვადრატული ღილაკი"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"თეთრი კვადრატული ღილაკი"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"დიდი წითელი წრე"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"დიდი ლურჯი წრე"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"დიდი ნარინჯისფერი ალმასი"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"დიდი ლურჯი ალმასი"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"პატარა ნარინჯისფერი ალმასი"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"პატარა ლურჯი ალმასი"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"ზევით მიმართული წითელი სამკუთხედი"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"ქვევით მიმართული წითელი სამკუთხედი"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"ზევით მიმართული პატარა წითელი სამკუთხედი"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"ქვევით მიმართული პატარა წითელი სამკუთხედი"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"საათი, რომელიც აჩვენებს პირველ საათს"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"საათი, რომელიც აჩვენებს ორ საათს"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"საათი, რომელიც აჩვენებს სამ საათს"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"საათი, რომელიც აჩვენებს ოთხ საათს"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"საათი, რომელიც აჩვენებს ხუთ საათს"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"საათი, რომელიც აჩვენებს ექვს საათს"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"საათი, რომელიც აჩვენებს შვიდ საათს"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"საათი, რომელიც აჩვენებს რვა საათს"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"საათი, რომელიც აჩვენებს ცხრა საათს"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"საათი, რომელიც აჩვენებს ათ საათს"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"საათი, რომელიც აჩვენებს თერთმეტ საათს"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"საათი, რომელიც აჩვენებს თორმეტ საათს"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"საათი, რომელიც აჩვენებს ორის ნახევარს"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"საათი, რომელიც აჩვენებს სამის ნახევარს"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"საათი, რომელიც აჩვენებს ოთხის ნახევარს"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"საათი, რომელიც აჩვენებს ხუთის ნახევარს"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"საათი, რომელიც აჩვენებს ექვსის ნახევარს"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"საათი, რომელიც აჩვენებს შვიდის ნახევარს"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"საათი, რომელიც აჩვენებს რვის ნახევარს"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"საათი, რომელიც აჩვენებს ცხრის ნახევარს"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"საათი, რომელიც აჩვენებს ათის ნახევარს"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"საათი, რომელიც აჩვენებს თერთმეტის ნახევარს"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"საათი, რომელიც აჩვენებს თორმეტის ნახევარს"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"საათი, რომელიც აჩვენებს პირველის ნახევარს"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"ფუძიამა"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"ტოკიოს ანძა"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"თავისუფლების ქანდაკება"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"იაპონიის სილუეტი"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"მოიანის ქვის ქანდაკება"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"სასტიკი სახე"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"სასტიკი სახე მომღიმარი თვალებით"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"სახე სიხარულის ცრემლებით"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"მომღიმარი პირდაღებული სახე"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"მომღიმარი სახე, ღია პირით და მოცინარი თვალებით"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"მომღიმარი სახე, ღია პირით და ცივი ოფლით"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"მომღიმარი სახე, ღია პირით და კარგად დახუჭული თვალებით"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"მომღიმარი სახე მნათი წრით"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"მომღიმარი სახე რქებით"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"თვალის ჩაკვრა"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"მომღიმარი სახე მომღიმარი თვალებით"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"გემრიელი საჭმლის დამაგემოვნებელი სახე"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"შებამოგვრილი სახე"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"მომღიმარი სახე გულის ფორმის თვალებით"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"მომღიმარი სახე მზის სათვალეებით"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"თავმომწონე სახე"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"ნეიტრალური სახე"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"უემოციო სახე"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"უკმაყოფილო სახე"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"სახე ცივი ოფლით"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"ჩაფიქრებული სახე"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"დაბნეული სახე"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"შეცბუნებული სახე"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"კოცნის სახე"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"კოცნის გაგზავნის სახე"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"კოცნის სახე მომღიმარი თვალებით"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"კოცნის სახე დახუჭული თვალებით"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"ენაგამოყოფილი სახე"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"ენაგამოყოფილი სახე თვალის ჩაკვრით"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"ენაგამოყოფილი სახე მჭიდროდ დახუჭული თვალებით"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"იმედგაცრუებული სახე"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"შეწუხებული სახე"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"ბრაზიანი სახე"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"გაბუტული სახე"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"მტირალი სახე"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"შეუპოვარი სახე"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"ტრიუმფალური სახე"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"იმედგაცრუებული მაგრამ შვებამოგვრილი სახე"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"წარბშეჭმუხნული პირდაღებული სახე"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"გატანჯული სახე"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"შიშნარევი სახე"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"დაქანცული სახე"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"მომძინარე სახე"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"დაღლილი სახე"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"დამანჭული სახე"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"ხმამაღლა მტირალი სახე"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"პირდაღებული სახე"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"გაჩუმებული სახე"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"სახე ღია პირით და ცივი ოფლით"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"შიშისგან მყვირალი სახე"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"გაოცებული სახე"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"წამოწითლებული სახე"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"მძინარი სახე"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"თავბრუდახვეული სახე"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"უპირო სახე"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"სახე სამედიცინო ნიღბით"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"სასტიკი კატის სახე მომღიმარი თვალებით"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"კატის სახე სიხარულის ცრემლებით"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"მომღიმარი კატის პირდაღებული სახე"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"მომღიმარი კატის სახე გულის ფორმის თვალებით"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"კატის სახე ირონიული ღიმილით"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"კოცნის სახე დახუჭული თვალებით"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"გაბუტული კატის სახე"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"მტირალი კატის სახე"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"დაქანცული კატის სახე"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"სახე უვარგისობის ჟესტით"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"სახე ok ჟესტით"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"ადამიანი თავის დაკვრით"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"არც-თუ-ისე ეშმაკი მაიმუნი"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"არ-მესმის მაიმუნი"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"არ ვლაპარაკობ მაიმუნი"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"ბედნიერი, ხელაწეული ადამიანი"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"სიხარულით ხელაპყრობილი ადამიანი"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"წარბშეკრული ადამიანი"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"ადამიანი გაბუტული სახით"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"ადამიანი დაწყობილი ხელებით"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"რაკეტა"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"ვერტმფრენი"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"ორთქლის ლოკომოტივი"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"რკინიგზის ვაგონი"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"ჩქაროსნული მატარებელი"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"ჩქაროსნული მატარებელი ტყვიის წვერით"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"მატარებელი"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"მეტრო"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"მსუბუქი რკინიგზა"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"სადგური"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"ტრამვაი"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"ტრამვაის ვაგონი"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"ავტობუსი"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"მომავალი ავტობუსი"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"ტროლეიბუსი"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"ავტობუსის გაჩერება"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"მიკროავტობუსი"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"სასწრაფო"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"სახანძრო"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"პოლიციის მანქანა"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"მომავალი პოლიციის მანქანა"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"ტაქსი"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"მომავალი ტაქსი"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"ავტომობილი"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"მომავალი ავტომობილი"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"რეკრეაციული ავტომანქანა"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"სატვირთო მანქანა"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"გადაბმული სატვირთო"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"ტრაქტორი"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"მონორელსი"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"მთის რკინიგზა"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"შეჩერებული რკინიგზა"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"მთის საბაგირო"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"საბაგირო"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"გემი"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"სანიჩბოსნო ნავი"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"სწრაფმავალი მოტორიანი გემი"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"ჰორიზონტალური შუქნიშანი"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"ვერტიკალური შუქნიშანი"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"მშენებლობის ნიშანი"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"პოლიციის მანქანა შუქის სიგნალით"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"სამკუთხა ალამი პოსტზე"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"კარი"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"შესვლის აკრძალვის ნიშანი"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"მოწევის ნიშანი"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"მოწევის აკრძალვის ნიშანი"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"ნაგვის გამოყოფილ ადგილზე ჩაყრის სიმბოლო"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"სიმბოლო ნაგავი არ დაყაროთ"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"დასალევად ვარგისი წყლის სიმბოლო"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"დასალევად უვარგისი წყლის სიმბოლო"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"ველოსიპედი"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"ველოსიპედები არ არის"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"ველოსიპედისტი"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"სამთო ველოსიპედისტი"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"ფეხით მოსიარულე"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"ფეხით სიარული აკრძალულია"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"ბავშვების გადასასვლელი"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"კაცების ნიშანი"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"ქალების ნიშანი"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"საპირფარეშო"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"ჩვილების ნიშანი"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"ტუალეტი"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"უნიტაზი"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"შხაპი"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"სააბაზანო"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"აბაზანა"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"პასპორტის კონტროლი"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"საბაჟო"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"ბარგის აღება"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"ბარგის ჩაბარება"</string>
+</resources>
diff --git a/java/res/values-ka-rGE/strings-talkback-descriptions.xml b/java/res/values-ka-rGE/strings-talkback-descriptions.xml
index c4fd65939..0cf7e7ce4 100644
--- a/java/res/values-ka-rGE/strings-talkback-descriptions.xml
+++ b/java/res/values-ka-rGE/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"ტექსტი შეყვანილი არ არის"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> შეასწორებს <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>-ს <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>-ად"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ასრულებს ავტოკორექციას"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"კლავიატურის კოდი %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift ჩართულია (შეეხეთ გამოსართავად)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"ჩართულია Caps (შეეხეთ გამოსართავად)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"დამატებითი სიმბოლოები"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"სიმბოლოები"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"წაშლა"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"სიმბოლოები"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"ასოები"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"წინა"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift ჩართულია"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"ჩართულია Caps"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift გამორთულია"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"სიმბოლოების რეჟიმი"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"დამატებითი სიმბოლოების რეჟიმი"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"ასოების რეჟიმი"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"ტელეფონის რეჟიმი"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"ტელეფონის სიმბოლოების რეჟიმი"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"ადგილები"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"სიმბოლოები"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"სიცილაკები"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ka-rGE/strings.xml b/java/res/values-ka-rGE/strings.xml
index 547bf29ca..3360c6209 100644
--- a/java/res/values-ka-rGE/strings.xml
+++ b/java/res/values-ka-rGE/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"შეყვანის მეთოდები"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"კვლევის აღრიცხვის ბრძანებები"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"კონტაქტებში ძებნა"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"კონტაქტების სიის გამოყენება მართლწერის შემოწმებისას"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"ვიბრაცია კლავიშზე დაჭერისას"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"კონტაქტის სახელების შეთავაზება"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"კონტაქტებიდან სახელების გამოყენება შეთავაზებებისთვის და კორექციისთვის"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"პერსონალიზებული შეთავაზებები"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"წერტილი ორმაგი შორისით"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"შორისზე ორჯერ შეხება დაწერს წერტილს და შორისის სიმბოლოს"</string>
<string name="auto_cap" msgid="1719746674854628252">"ავტო-კაპიტალიზაცია"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"შეყვანის ენები"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"შეეხეთ ისევ შესანახად"</string>
<string name="has_dictionary" msgid="6071847973466625007">"ხელმისაწვდომია ლექსიკონი"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"მომხმარებლის უკუკავშირის ჩართვა"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"შეიტანეთ წვლილი შეყვანის ამ მეთოდის გაუმჯობესებაში — გააგზავნეთ მოხმარების სტატისტიკა და ავარიული გათიშვების ანგარიშები"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"კლავიატურის თემა"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"ინგლისური (გართ. სამ.)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"ინგლისური (აშშ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"ჩართვა"</string>
<string name="not_now" msgid="6172462888202790482">"ახლა არა"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"შეყვანის იგივე სტილი უკვე არსებობს: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"გამოყენებადობის კვლევის რეჟიმი"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"კლავიშზე გრძელი დაჭერის დაყოვნება"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"კლავიშზე დაჭერის ვიბრაციის ხანგრძლივობა"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"კლავიშზე დაჭერის ხმა"</string>
diff --git a/java/res/values-kk/strings-talkback-descriptions.xml b/java/res/values-kk/strings-talkback-descriptions.xml
index 13adf830d..39388a4d7 100644
--- a/java/res/values-kk/strings-talkback-descriptions.xml
+++ b/java/res/values-kk/strings-talkback-descriptions.xml
@@ -27,7 +27,8 @@
<skip />
<!-- no translation found for spoken_auto_correct_obscured (6276420476908833791) -->
<skip />
- <string name="spoken_description_unknown" msgid="3197434010402179157">"Перне коды %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="244197883292549308">"Shift"</string>
<string name="spoken_description_shift_shifted" msgid="1681877323344195035">"Shift қосулы (өшіру үшін түрту)"</string>
<string name="spoken_description_caps_lock" msgid="3276478269526304432">"Caps lock қосулы (өшіру үшін түрту)"</string>
diff --git a/java/res/values-kk/strings.xml b/java/res/values-kk/strings.xml
index 83ac0daf7..29780513c 100644
--- a/java/res/values-kk/strings.xml
+++ b/java/res/values-kk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Енгізу опциялары"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Журнал пәрмендерін зерттеу"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Контакт аттарын іздеу"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Емлені тексеру құралы контактілер тізімінің жазбаларын пайдаланады"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Пернені басқан кездегі діріл"</string>
@@ -82,8 +81,6 @@
<string name="select_language" msgid="3693815588777926848">"Енгізу тілдері"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Сақтау үшін қайта түртіңіз"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Сөздік қолжетімді"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Пайдаланушының кері байланысын қосу"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Қолданыс статистикасын және бұзылыс есептерін автоматты түрде жіберу арқылы осы енгізу әдісінің редакторын арттыруға көмектесу"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Пернетақта тақырыбы"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"ағылшын (ҰБ)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"ағылшын (АҚШ)"</string>
@@ -113,7 +110,6 @@
<string name="enable" msgid="5031294444630523247">"Қосу"</string>
<string name="not_now" msgid="6172462888202790482">"Қазір емес"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Бірдей енгізу стилі бұрыннан бар: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Қолайлылықты зерттеу режимі"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Пернені ұзақ басу кідірісі"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Пернені басқан кездегі діріл ұзақтығы"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Пернені басқан кездегі дыбыс деңгейі"</string>
diff --git a/java/res/values-km-rKH/strings-action-keys.xml b/java/res/values-km-rKH/strings-action-keys.xml
index ff747d9f5..d6b11b7ce 100644
--- a/java/res/values-km-rKH/strings-action-keys.xml
+++ b/java/res/values-km-rKH/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"មុន"</string>
<string name="label_done_key" msgid="7564866296502630852">"រួចរាល់"</string>
<string name="label_send_key" msgid="482252074224462163">"ផ្ញើ"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"ផ្អាក"</string>
<string name="label_wait_key" msgid="5891247853595466039">"រង់ចាំ"</string>
</resources>
diff --git a/java/res/values-km-rKH/strings-emoji-descriptions.xml b/java/res/values-km-rKH/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..757df50e7
--- /dev/null
+++ b/java/res/values-km-rKH/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"សញ្ញា​រក្សា​សិទ្ធ​"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"សញ្ញា​​​ចុះ​បញ្ជី"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"សញ្ញា​ឧទាន​​ពីរ"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"សញ្ញា​​ឧទាន​សញ្ញា​សួរ​​"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"សញ្ញា​​​និក្ខិត្តសញ្ញា"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"ប្រភព​ព័ត៌មាន"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"ព្រួញ​ឆ្វេងស្ដាំ"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"ព្រួញ​ឡើង​លើ​ចុះក្រោម"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"ព្រួញ​ទិសពាយព្យ"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"ព្រួញ​​ទិស​ឥសាន្ត​ឦសាន្ត​"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"ព្រួញ​​ទិស​អាគ្នេយ៍"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"ព្រួញ​​ទិស​និរតី"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"ព្រួញ​ទៅ​ឆ្វេង​មាន​ទំពក់"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"ព្រួញ​ទៅ​​ស្ដាំ​មាន​ទំពក់"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"នាឡិកា​ដៃ"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"នាឡិកា​ពិសោធន៍"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"ត្រីកោណ​ខ្មៅ​ពីរ​ចង្អុល​ទៅ​ស្ដាំ"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"ត្រីកោណ​ខ្មៅ​ពីរ​ចង្អុល​ទៅ​ឆ្វេង"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"ត្រីកោណ​ខ្មៅ​ពីរ​ចង្អុល​​ឡើង​លើ"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"ត្រីកោណ​ខ្មៅ​ពីរ​ចង្អុល​​ចុះក្រោម"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"នាឡិកា​រោទ៍​"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"កែវ​ពិសោធន៍​មាន​ខ្សាច់ហូរ"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"អក្សរ​អឹម​ធំ​ក្នុង​រង្វង់"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"ការ៉េ​តូច​​ពណ៌ខ្មៅ"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"ការ៉េ​តូច​ពណ៌​ស"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"ត្រីកោណ​ចង្អុល​ស្ដាំ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"ត្រីកោណ​ចង្អុល​​ឆ្វេង​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"ការ៉េ​មធ្យម​ពណ៌ស"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"ការ៉េ​មធ្យម​ពណ៌​​ខ្មៅ"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"ការ៉េ​តូច​មធ្យម​ពណ៌​ស"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"ការ៉េ​តូច​មធ្យម​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"ព្រះអាទិត្យ​ពណ៌​ខ្មៅ​​បញ្ចេញ​ពន្លឺ"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"ពពក"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"ទូរស័ព្ទ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"ប្រអប់​មាន​សញ្ញា​ធីក"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"ឆត្រ​មាន​តំណក់​ទឹក​ភ្លៀង"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"ភេសជ្ជៈ​ក្ដៅ"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"ចង្អុល​ដៃ​ចង្អុល​ឡើង​ពណ៌ស"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"មុខ​ញញឹម​ពណ៌​ស"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"មេសៈរាសី"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"តៅរ៉ូស"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"ហ្គិមីនី"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"សញ្ញា​ទី៤​នៃ​រាសីចក្រ"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"លីអូ"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"សញ្ញា​រាសី"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"លីប្រា"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"រាសីវច្ចៈ"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"រាសី​ធ្នូ"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"រាសី​សេះ"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Aquarius"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"រាសី​អាប់អួ"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"ឈុត​ប៊ិច​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"ឈុត​​ជួង​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"ឈុត​​កឺ​ពណ៌ខ្មៅ"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"ឈុត​​ការ៉ូ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Hot springs"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"និមិត្ត​សញ្ញា​ធុងសំរាម​សកល​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"និមិត្ត​សញ្ញា​រទេះ​រុញ"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"យុថ្កា"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"សញ្ញា​ព្រមាន"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"សញ្ញា​តង់ស្យុង​​ខ្ពស់"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"រង្វង់​ពណ៌ស​មធ្យម"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"រង្វង់​ពណ៌​ខ្មៅ​មធ្យម"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"បាល់​ទាត់"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"បាល់បោះ"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"អ្នកលេង​ព្រិល​ដោយ​គ្មាន​ព្រិល"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"ព្រះអាទិត្យ​នៅ​​ក្រោយ​ពពក"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"សញ្ញា (⛎)"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"ហាមចូល"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"វិហារ​សាសនា"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"បាញ់​ទឹក"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"ទង់ជាតិ​​​ក្នុង​រន្ធ"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"ទូក​ក្ដោង"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"តង់"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"បូម​ប្រេង"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"កន្ត្រៃ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"សញ្ញា​ធីក​ពណ៌​ស​ធំ"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"យន្តហោះ"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"ស្រោម​សំបុត្រ"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"លើក​កណ្ដាប់ដៃ"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"លើកដៃ"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"លើក​ដៃ​​ជ័យជម្នះ"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"ខ្មៅដៃ"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"ចុង​ខ្មៅ​ដៃ"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"សញ្ញា​ធីក​ដិត"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"សញ្ញា​គុណ​ដិត"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"បញ្ចេញ​ពន្លឺ"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"ផ្កាយ​ប្រាំ​បី​ជ្រុង"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"ផ្កាយ​ប្រាំ​បី​ជ្រុង​ដិត"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"សញ្ញា (❄)"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"បញ្ចេញ​ពន្លឺ"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"សញ្ញា​​ខ្វែង"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"សញ្ញា​ខ្វែង​ក្នុង​ប្រអប់"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"សញ្ញា​សួរ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"សញ្ញា​សួរ​ពណ៌ស"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"សញ្ញា​ឧទាន​ពណ៌​ស"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"សញ្ញា​ឧទាន​ពណ៌ខ្មៅ​ដិត"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"បេះដូង​​​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"សញ្ញា​បូក​ដិត"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"សញ្ញា​ដក​​ដិត"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"សញ្ញា​​​ចែក​ដិត"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"ព្រួញ​ទៅ​ស្ដាំ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"រង្វង់​​អង្កាញ់"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"រង្វង់​អង្កាញ់​ពីរ"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"ព្រួញ​ចង្អុល​ទៅ​ស្ដាំ​បន្ទាប់មក​បត់​ឡើង​លើ"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"ព្រួញ​ចង្អុល​ទៅ​ស្ដាំ​បន្ទាប់មក​បត់​ចុះ​ក្រោម"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"ព្រួញ​ពណ៌ខ្មៅ​ទៅ​ឆ្វេង"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"ព្រួញ​​ពណ៌​ខ្មៅ​ឡើង​លើ"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"ព្រួញ​ពណ៌​ខ្មៅ​​ចុះក្រោម"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"ប្រអប់​ការ៉េ​ធំ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"ប្រអប់​ការ៉េ​ធំ​ពណ៌​ស"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"​ផ្កាយ​​មធ្យម​ពណ៌ស"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"រង្វង់​ធំ​​ដិត"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"សញ្ញា​​រលក​ដិត"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"សញ្ញា (〽)"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"សញ្ញា (㊗)"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"សញ្ញា (㊙)"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"សញ្ញា (🀄)"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"សញ្ញា (🃏)"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"ឈាម​ប្រភេទ A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"ឈាម​ប្រភេទ B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"ឈាម​ប្រភេទ O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"ចំណត"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"ឈាម​ប្រភេទ AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"ប្រអប់ CL"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"ប្រអប់ cool"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"ប្រអប់ free"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"ប្រអប់ ID"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"ប្រអប់ new"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"ប្រអប់ N G"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"ប្រអប់ OK"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"ប្រអប់ SOS"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"ប្រអប់ up!"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"ប្រអប់ vs"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"សញ្ញា (🈁)"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"សញ្ញា (🈂)"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"សញ្ញា (🈚)"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"សញ្ញា (🈯)"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"សញ្ញា (🈲)"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"សញ្ញា (🈳)"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"សញ្ញា (🈴)"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"សញ្ញា (🈵)"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"សញ្ញា (🈶)"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"សញ្ញា (🈷)"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"សញ្ញា (🈸)"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"សញ្ញា (🈹)"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"សញ្ញា (🈺)"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"សញ្ញា (🉐)"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"សញ្ញា (🉑)"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"ស៊ីក្លូន"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"អ័ភ្រ"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"ឆត្រ​បិទ"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"រាត្រី​​មាន​​ផ្កាយ"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"ព្រះ​អាទិត្យ​​​លើ​ភ្នំ"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"ព្រះ​អាទិត្យរះ"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"ទីក្រុង​ពេល​ព្រលប់"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"ព្រះអាទិត្យ​លិច​ចន្លោះ​អាគារ"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"ឥន្ទធនូ"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"ស្ពាន​ពេល​រាត្រី"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"ទឹក​រលក"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"ភ្នំភ្លើង"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"មេឃ​ស្រទំ"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"ភូគោល​​អឺរ៉ុប-អាហ្រិក"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"ភូគោល​អាមេរិក"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"ភូគោល​អាស៊ី-អូស្ត្រាលី"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"ភូគោល​មាន​ខ្សែ​វណ្ឌ"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"​​ព្រះចន្ទ"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"ព្រះ​ចន្ទ​មួយ​ចំណិត​ស្ដាំ"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"ព្រះ​ចន្ទ​ពាក់​កណ្ដាល"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"ព្រះ​ចន្ទ​មួយ​ចំណិត​ឆ្វេង"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"ព្រះចន្ទ​ពេញ​វង់​"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"ព្រះ​ចន្ទ​ភ្លឺ​មួយ​ចំហៀង"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"ព្រះ​ចន្ទ​ភ្លឺ​ពាក់​កណ្ដាល"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"ព្រះ​ចន្ទ​ភ្លឺ​មួយ​ចំណិត​ឆ្វេង"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"ព្រះ​ចន្ទ​មួយ​ចំណិត"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"ព្រះ​ចន្ទ​មាន​មុខ​មនុស្ស"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"ព្រះ​ចន្ទ​មាន​មុខ​មនុស្ស​ពាក់កណ្ដាល​ស្ដាំ"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"ព្រះ​ចន្ទ​មាន​មុខ​មនុស្ស​ពាក់កណ្ដាលឆ្វេង"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"ព្រះចន្ទ​មាន​មុខ​មនុស្ស​ពេញ​វង់"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"ព្រះ​អាទិត្យ​មានមុខ​មនុស្ស"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"ផ្កាយ"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"បាញ់​ផ្កាយ"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"ឆេសណាត់"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"កូន​ឈើ"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"ដើម​ឈើ​បៃតង"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"ដើម​ឈើ​មិន​ខៀវ​ជា​និច្ច"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"ដើម​ត្នោត"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"ដំបង​យក្ស"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"ផ្កា"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"ផ្កាឈឺរី"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"ផ្កា​កុលាប"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"ផ្កា​រំយោល"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"ផ្កា​ឈូករ័ត្ន"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"ផ្កា"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"ស្នៀត​​​​ពោត"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"គួរ​ស្រូវ"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"រុក្ខជាតិ"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"ដើម​ដង្ហិត"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"ស្លឹក​ឈើ"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"ស្លឹក​ឈើ​ជ្រុះ"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"ស្លឹកឈើបក់តាមខ្យល់"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"ផ្សិត"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"ប៉េងប៉ោះ"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"ត្រប់"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"ទំពាំង​បាយ​ជូរ"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"ត្រសក់​ស្រូវ"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"ឪឡឹក"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"ក្រូច​ឃ្វិច"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"ក្រូចឆ្មារ"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"​ចេក"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"ម្នាស់"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"​ប៉ោម​​​ក្រហម"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"​ប៉ោម​​​បៃតង"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"ផ្លែព័រ"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"ផ្លែប៉ែស"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"ផ្លែ​ឈឺរី"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"ផ្លែស្ត្របេរី"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"ហាំប៊ឺហ្គឺ"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"ភីហ្សា​​មួយ​ស្លាយ"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"សាច់ចង្កាក់"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"ភ្លៅ​មាន់"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"ប៊ីស្គី​បាយ"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"ដុំ​បាយ"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"បាយ​មួយ​ចាន"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"ការី​ និង​បាយ"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"ចាន​ចំហុយ"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"ស្ប៉ាហ្គាទី"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"នំប៉័ង"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"ដំឡូង​បំពង"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"ដំឡូង​ដុត"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"ប្រហិត​ដោត​ចង្កាក់"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"ម្ហូប​សមុទ្រ​ដោត​ចង្កាក់"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"ស៊ូស៊ី"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"កំពឹស​ចៀន"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"នំ​ត្រី​រាង​មូល"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"ការ៉េម​​បំពង់"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"ការ៉េម​កែវ"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"ការ៉េម​"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"ដូណាត់"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"ខូគី"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"​​សូកូឡា"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"ស្ករគ្រាប់"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"ស្ករ​គ្រាប់​មាន​ដង​​កាន់"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"សង់ខ្យា"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"ថូ"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"នំ​ខេក"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"ប្រអប់​បេនតូ"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"ឆ្នាំង​អាហារ"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"ចម្អិន​អាហារ"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"សម ​និង​កាំបិត"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"ពែង​តែ​អត់​ដៃកាន់"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"ដប និង​ពែង"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"កែវ​ស្រា"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"កែវ​ស្រា​ក្រឡុក"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"ភេសជ្ជៈ​​​ត្រូពិក"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"កែវ​​ស្រាបៀ​"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"ជល់​កែវ​ស្រាបៀ"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"ដប​ទឹកដោះ​គោ"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"ខ្សែ​បូ"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"ខ្ចប់​កា​ដូរ"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"នំ​ខួប​កំណើត"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"គោម"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"ដើម​ឈើ​បុណ្យ​ណូអែល"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"តា​ណូអែល"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"កាំជ្រួច"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"ពន្លឺ​កាំជ្រួច"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"ប៉េងប៉ោង"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"ឧបករណ៍​​​ផ្ទុះ​ពេល​ជប់លៀង"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"ក្រដាស​ពណ៌​តូចៗ"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"ដើម​​តាណាប៉ាតា"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"ទង់​ជាតិ​ខ្វែង"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"ការ​តុបតែង​ដោយ​​ផ្លែ​ស្រល់"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"តុក្កតា​ជប៉ុន"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"ខ្សែ​បូ​ត្រី​គល់រាំង"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"កណ្ដឹង​ខ្យល់"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"ពិធី​មើល​ព្រះ​ចន្ទ"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"កាបូប​ទៅសាលារៀន"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"មួក​ទទួល​សញ្ញាប័ត្រ"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"សេះ​ក្មេង​ជិះ​លេង"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"កន្ត្រក​វិល"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"រថយន្ត​សម្រាប់​ពាក់​ជិះ​រំអិល"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"ដង​សន្ទូច និង​ត្រី"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"មីក្រូហ្វូន"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"ម៉ាស៊ីន​ថត​ភាព​យន្ត"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"ភាពយន្ត"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"កាស"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"ក្ដារ​លាយ​ពណ៌​វិចិត្រករ"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"មួក​​​សម្ដែង​សិល្បៈ"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"តង់​សៀក​"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"សំបុត្រ"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"បន្ទះកណ្ដឹង"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"សម្ដែង​សិល្បៈ"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"ហ្គេម​​វីដេអូ"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"វាយ​​​ចំគោលដៅ"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"ម៉ាស៊ីន​​​ដាក់​កាក់"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"ល្បែង​បុក​ប៊ីយ៉ា"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"ហ្គេម​ឡុកឡាក់"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"ប៊ូលីង"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"សន្លឹក​បៀរ​​មាន​ផ្កា"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"ណោត​តន្ត្រី"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"ណោត​តន្ត្រីច្រើន"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"ត្រែ"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"ហ្គីតា"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"ខ្ទង់​សម្រាប់​ចុច​តន្ត្រី"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"ត្រុំប៉ែត"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"វីយូឡុង"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"និមិត្តសញ្ញា​តន្ត្រី"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"អាវ​កីឡា​​មាន​ខ្សែ​ឆៀង"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"រ៉ាកែត និង​បាល់"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"ជិះ​ស្គី ​និង​ក្ដារ​​ស្គី​"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"បាល់​បោះ​ និង​វណ្ណ​មូល"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"ទង់ជាតិ​ប្រណាំង​ម៉ូតូ"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"អ្នក​ជិះ​​ក្ដារ​រំអិល​លើ​ព្រិល​"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"អ្នក​រត់"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"អ្នក​ជិះ​ទូក​រអិល​លើ​ទឹក"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"ពាន​រង្វាន់"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"​ប្រណាំង​សេះ"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"​បាល់​ទាត់​អាមេរិក"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"បាល់​អោប"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"អ្នក​ហែលទឹក"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"ការ​សាងសង់​​ផ្ទះ"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"ផ្ទះ​មាន​សួន​ច្បារ"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"អគារ​ការិយាល័យ"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"ការិយាល័យ​ប្រៃសណីយ៍​ជប៉ុន"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"ការិយាល័យ​ប្រៃសណីយ៍​អឺរ៉ុប"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"មន្ទីរពេទ្យ"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"ធនាគារ"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"ម៉ាស៊ីន​​អេធីអឹម"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"សណ្ឋាគារ"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"សណ្ឋាគារ​ក្ដី​ស្រឡាញ់​"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"ហាង​​ទំនិញ ២៤​ម៉ោង"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"សាលារៀន"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"ហាង​​ទំនិញធំៗ"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"រោងចក្រ"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"ចង្កៀង​គោម Izakaya"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"វិមាន​​ជប៉ុន"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"វិមាន​អឺរ៉ុប"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"កណ្ដុរ​ប្រែង"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"កណ្ដុរ​ប្រមះ"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"គោ"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"ក្របី​ទឹក"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"គោ"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"ខ្លា​រខិន"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"ទន្សាយ"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"ឆ្មា"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"នាគ"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"ក្រពើ"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"​ត្រី​បាឡែន"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"ខ្យង់ក្ដក់"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"ពស់"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"សេះ"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"ចៀម​ឈ្មោល"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"ពពែ"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"ចៀម"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"ស្វា"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"មាន់​ឈ្មោល"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"​មាន់"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"ឆ្កែ"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"ជ្រូក"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"ជ្រូក​ព្រៃ"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"ដំរី"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"មឹក"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"ខ្យង​គ្រែង"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"សង្កើច"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"ស្រមោច"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"ឃ្មុំ"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"អណ្ដើក​មាស"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"ត្រី"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"ត្រី​តំបន់​ត្រូពិក"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"ត្រី​ក្រពត"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"អណ្ដើក"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"កូនមាន់ញាស់"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"កូន​មាន់"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"មុខ​កូន​មាន់"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"បក្សី"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"ភេនឃ្វីន"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"ខ្លាឃ្មុំ"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"ឆ្កែ"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"អូដ្ឋ​​បូក​មួយ"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"អូដ្ឋ​បូក​ពីរ"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"ត្រី​ផ្សោត"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"មុខ​កណ្ដុរ"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"មុខ​​គោ"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"មុខ​ខ្លា"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"មុខ​ទន្សាយ"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"មុខ​ឆ្មា"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"មុខ​នាគ"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"ព្រុយ​ត្រី​បាឡែន"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"មុខ​សេះ"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"មុខ​ស្វា"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"មុខ​ឆ្កែ"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"មុខ​ជ្រូក"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"មុខ​កង្កែប"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"មុខ​កណ្ដុរ"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"មុខ​ចចក"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"​​មុខ​ខ្លាឃ្មុំ"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"មុខ​ខ្លាឃ្មុំ​ផេ​ន​ដា"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"ច្រមុះ​ជ្រូក"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"ក្រញាំ​​ជើង"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"ភ្នែក"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"ត្រចៀក"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"ច្រមុះ"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"មាត់"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"អណ្ដាត"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"ចង្អុល​ដៃ​ឡើង​លើ"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"ចង្អុល​ដៃ​​ចុះ​ក្រោម"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"ចង្អុល​ដៃ​ទៅ​ឆ្វេង"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"ចង្អុល​ដៃ​ទៅ​ស្ដាំ"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"កណ្ដាប់ដៃ"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"គ្រវី​បាត​ដៃ"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"សញ្ញា​អូខេ"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"​មេដៃ​ឡើង​លើ"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"​មេដៃ​ចុះ​ក្រោម"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"ទះ​ដៃ"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"លា​ដៃ​"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"មកុដ"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"មួក​​ស្ត្រី"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"វ៉ែនតា"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"ក្រ​វ៉ាត់​ករ​"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"អាវ​យឺត​​"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"ខោ​ខោវប៊យ"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"សំលៀក​បំពាក់"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"គី​ម៉ូណូ"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"ឈុត​ហែល​ទឹក"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"សំលៀកបំពាក់​នារី"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"កាបូប"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"កាបូប​ដៃ"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"ថង់"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"ស្បែកជើង​បុរស"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"ស្បែក​ជើង​កីឡា"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"ស្បែកជើង​កែង"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"ស្បែក​ជើង​ស៊ក​ស្រ្តី"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"​ស្បែក​ជើង​ក​វែង​ស្ត្រី"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"ដាន​ជើង"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"គណនី​ភ្ញៀវ"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"គណនី"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"ក្មេង​​ប្រុស"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"ក្មេង​ស្រី"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"បុរស​"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"ស្ត្រី​"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"គ្រួសារ"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"បុរស​​ និង​ស្ត្រី​កាន់ដៃ​គ្នា"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"បុរស​ពីរ​នាក់​កាន់​ដៃ​គ្នា"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"ស្ត្រី​​​ពីរ​កាន់​ដៃ​គ្នា"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"មន្ត្រី​ប៉ូលិស"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"ស្ត្រី​​ចង​សក់​ទីទុយ"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"កូនក្រមុំ​​ពាក់​​ស្បៃ​មុខ"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"មនុស្ស​​មាន​សក់​​ពណ៌​ទង់ដែង"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"បុរស​​ពុកមាត់​ឆ្មា"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"បុរស​ពាក់​ឈ្នួត"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"បុរស​​ចំណាស់"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"ស្ត្រី​ចំណាស់"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"ទារក"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"កម្មករ​សំណង់"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"ព្រះអង្គម្ចាស់​ក្សត្រី"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"សត្វ​ចម្លែក​ជប៉ុន"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"ម្រេញគង្វាល​ជប៉ុន"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"ខ្មោច"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"អប្សរា​​ទារក"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"មនុស្ស​ក្រៅ​ភព"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"សត្វ​ចម្លែក​ក្រៅ​​ភព"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"ប្រែត"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"លលាដ៍​ក្បាល"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"អ្នក​ផ្ដល់​ព័ត៌មាន"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"អ្នក​យាម"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"អ្នក​រាំ​"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"ក្រេម​លាប​បបូរ​មាត់"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"ថ្នាំ​លាប​​​ក្រចក"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"ម៉ាស្សា​មុខ"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"កាត់សក់"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"ស្លាក​សញ្ញា​កាត់សក់"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"ស៊ីរ៉ាំង"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"ថ្នាំ​គ្រាប់​"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"ស្នាម​ថើប"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"លិខិត​ស្នេហា​"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"រោទ៍"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"ត្បូង​ថ្ម"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"ថើប"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"បាច់​​ផ្កា"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"ប្ដី​ប្រពន្ធ​​ និង​រូប​បេះដូង"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"អាពាហ៍ពិពាហ៍"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"​សំឡេង​បេះដូង​លោត"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"ខូច​ចិត្ត"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"បេះដូង​​ពីរ"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"បេះដូង​​មាន​ពន្លឺ"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"បេះដូង​​លូតលាស់"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"បេះដូង​​ជាប់​ព្រួញ"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"បេះដូង​​ពណ៌​ខៀវ"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"បេះដូង​​ពណ៌​បៃតង"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"បេះដូង​​ពណ៌​លឿង"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"បេះដូង​​ពណ៌ស្វាយ"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"បេះដូង​ជាប់​ខ្សែ​បូ"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"បេះដូង​វិល"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"ការ​តុបតែង​បេះដូង"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"​រាង​ពេជ្រ​​មាន​​ចំណុច​​ខាង​ក្នុង"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"អំពូល​​អគ្គិសនី"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"និមិត្ត​សញ្ញា​កំហឹង"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"គ្រាប់បែក"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"និមិត្ត​សញ្ញា​​ដេក"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"និមិត្ត​សញ្ញា​​ប៉ះ​ទង្គិច​គ្នា"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"និមិត្ត​សញ្ញា​​ស្រក់​ញើស​"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"ដំណក់​ទឹក"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"និមិត្ត​សញ្ញា​​ដកឃ្លា"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"គំនរ​ធូលី"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"ដំឡើង​សាច់ដុំ​ដើមដៃ"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"និមិត្ត​សញ្ញា​​វិលមុខ"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"ប្រអប់​បញ្ចេញ​យោបល់"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"ប្រអប់​គំនិត"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"ផ្កា​​ពណ៌ស"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"និមិត្ត​សញ្ញា​​មួយ​រយ​ពិន្ទុ"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"កាបូប​​លុយ"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"ប្ដូរ​​រូបិយប័ណ្ណ"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"សញ្ញា​ដុល្លារ"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"កាត​​ឥណទាន"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"ក្រដាស​ប្រាក់​​ធនាគារ​មាន​សញ្ញា​​យ៉េន​​"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"លុយដុល្លារ"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"ក្រដាស​ប្រាក់​​ធនាគារ​មាន​សញ្ញា​អឺរ៉ូ"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"ក្រដាស​ប្រាក់​​ធនាគារ​មាន​សញ្ញា​​​ផោន"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"លុយ​មាន​ស្លាប"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"ក្រាហ្វិក​និន្នាការ​ឡើង​​មាន​​សញ្ញា​យ៉េន"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"កៅអី"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"កុំព្យូទ័រ​ផ្ទាល់ខ្លួន"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"វ៉ា​លី​"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"ឌីស​​តូច"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"ថា​ស​​ទន់"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"ថាស"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"ឌីវីឌី"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"ថត​​ឯកសារ"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"ថត​ឯកសារ​បើក"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"ទំព័រ​​កោង"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"ទំព័រ​បញ្ឈរ"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"ប្រតិទិន"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"ហែក​ប្រតិទិន​"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"​កាត​រៀប​តាម​អក្សរ"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"ក្រាហ្វិក​មាន​និន្នាការ​ឡើង"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"ក្រាហ្វិក​មាន​និន្នាការ​ចុះ"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"គំនូស​តាង​របារ"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"ក្ដារ​តម្បៀត​ខ្ទាស់"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"ម្ជុល"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"ម្ជុល​ក្បាល​មូល"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"ដង្កៀប​​ក្រដាស"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"បន្ទាត់​ត្រង់"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"បន្ទាត់​រៀង​ត្រីកោណ"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"ផ្ទាំង​​​ចំណាំ"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"បញ្ជី​កត់ត្រា"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"សៀវភៅ"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"សៀវភៅ​មាន​ក្រប​ពណ៌"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"សៀវភៅ​​បិទ"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"សៀវភៅ​បើក​​"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"សៀវភៅ​​ពណ៌​បៃតង"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"សៀវភៅ​​ពណ៌​ខៀវ"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"សៀវភៅ​​ពណ៌​ទឹកក្រូច"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"សៀវភៅ​"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"ស្លាកឈ្មោះ"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"ក្រដាស​រមូរ"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"កំណត់ចំណាំ"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"អ្នក​ទទួល​ទូរស័ព្ទ"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"ភេយ័រ"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"ម៉ាស៊ីន​​ទូរសារ"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"អង់តែន​​ផ្កាយ​រណប"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"អូប៉ាល័រ​ប្រកាស​សាធារណៈ"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"ឧបករណ៍​បំពង​សំឡេង"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"ថា​ស​​​ចេញ"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"ថា​ស​ចូល"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"កញ្ចប់​"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"និមិត្ត​សញ្ញា​អ៊ីមែល"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"ស្រោម​​សំបុត្រ​ចូល"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"ស្រោម​សំបុត្រ​​មាន​សញ្ញា​ព្រួញ​ពី​លើ"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"ប្រអប់​សំបុត្រ​បិទ​មាន​ទង់​ចុះក្រោម"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"ប្រអប់​សំបុត្រ​បិទ​មាន​ទង់​ឡើង​លើ"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"ប្រអប់​សំបុត្រ​បើក​មាន​ទង់​ឡើង​លើ"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"ប្រអប់​សំបុត្រ​បើក​មាន​ទង់ចុះក្រោម"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"ប្រអប់​ប្រៃសណីយ៍"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"ស្នែង​​ប្រៃសណីយ៍"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"កាសែត"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"ទូរស័ព្ទ​ចល័ត"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"ទូរស័ព្ទ​ចល័ត​មាន​សញ្ញា​ព្រួញ​ចូល​ពី​​ឆ្វេង"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"របៀប​​​ញ័រ"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"បិទ​ទូរស័ព្ទ​​ចល័ត"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"មិន​មាន​ទូរស័ព្ទ​​ចល័ត"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"អង់តែន​មាន​របារ"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"ម៉ាស៊ីន​ថត"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"ម៉ាស៊ីន​ថត​វីដេអូ"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"ទូរទស្សន៍"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"វិទ្យុ"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"ការ​សែត​វីដេអូ"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"ព្រួញ​រមួល​ទៅ​ស្ដាំ"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"ព្រួញ​រាង​ជា​រង្វង់​បើក​​​ស្រប​ទិស​ទ្រនិច​នាឡិកា​ទៅ​ឆ្វេង-ស្ដាំ"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"ព្រួញ​រាង​ជា​រង្វង់​បើក​​ស្រប​ទិស​ទ្រនិច​នាឡិកា​ទៅ​ឆ្វេង-ស្ដាំ​មាន​លេខ​ ១​ក្នុង​រង្វង់​នៅ​ពី​លើ"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"ព្រួញ​រាង​ជា​រង្វង់​បើក​​ស្រប​ទិស​ទ្រនិច​នាឡិកា​ចុះក្រោម-ឡើងលើ"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"ព្រួញ​រាង​ជា​រង្វង់​បើក​​ច្រាស​​ទិស​ទ្រនិច​នាឡិកា​ចុះក្រោម-ឡើងលើ"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"និមិត្ត​សញ្ញា​ពន្លឺ​​ទាប"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"និមិត្ត​សញ្ញា​​ពន្លឺ​ខ្ពស់"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"អូប៉ាល័រ​មាន​បន្ទាត់​កាត់"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"អូប៉ាល័រ"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"អូប៉ាល័រ​មាន​រលក​សំឡេង​មួយ"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"អូប៉ាល័រ​មាន​រលក​សំឡេង​បី"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"ថ្ម"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"ដុយ​អគ្គិសនី"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"កែវ​ពង្រីក​ចង្អុល​ខាង​ឆ្វេង"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"កែវ​ពង្រីក​ចង្អុល​ខាង​ស្ដាំ"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"ចាក់សោ​​​ដោយ​ប្រើ​​ប៊ិច​"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"បិទ​​សោ​ដោយ​ប្រើ​​​​កូនសោ"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"សោ"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"ចាក់សោ"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"បើក​សោ"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"កណ្ដឹង"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"កណ្ដឹង​មាន​បន្ទាត់​កាត់"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"​ចំណាំ"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"និមិត្ត​សញ្ញា​​តំណ"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"ប៊ូតុង​​មូល"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"ថយក្រោយ​មាន​ព្រួញ​ទៅ​ឆ្វេង​ខាង​លើ"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"បញ្ចប់​មាន​ព្រួញ​ទៅ​ឆ្វេង​ខាង​លើ"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"បើក​មាន​សញ្ញា​ឧទាន​​ជា​មួយ​នឹង​ព្រួញ​ទៅ​ឆ្វេង​​ខាង​លើ"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"ឆាប់ៗ​មាន​ព្រួញ​ទៅ​ស្ដាំ​ខាង​លើ"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"កំពូល​មាន​ព្រួញ​ឡើងលើ​នៅ​ខាង​លើ"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"​និមិត្ត​សញ្ញា​គ្មាន​នរណា​ម្នាក់​​អាយុ​​ក្រោម​ដប់ប្រាំ​បី"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"គ្រាប់​ចុច​ ១០"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"និមិត្ត​សញ្ញា​បញ្ចូល​សម្រាប់​អក្សរ​ឡាតាំង​ធំ"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"និមិត្ត​សញ្ញា​បញ្ចូល​សម្រាប់​អក្សរ​ឡាតាំង​តូច"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"និមិត្ត​សញ្ញា​បញ្ចូល​សម្រាប់​​លេខ​"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"ការ​បញ្ចូល​និមិត្តសញ្ញា"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"និមិត្ត​សញ្ញា​បញ្ចូល​សម្រាប់​អក្សរ​ឡាតាំង"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"ភ្លើង"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"ពិល​​អគ្គិសនី"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"ម៉ាឡេត"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"ញញួរ"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"ឡោ​ស៊ី​​"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"កាំបិត​​"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"កាំភ្លើង​ខ្លី"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"មីក្រូទស្សន៍"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"កែវ​យឹត"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"​បាល់​គ្រីស្តាល់"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"ផ្កាយ​ ៦ជ្រុងមាន​ចំណុចកណ្ដាល"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"និមិត្តសញ្ញា​ជប៉ុន​សម្រាប់​អ្នក​ចាប់ផ្ដើម"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"លំពែង​មុខ​បី"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"ប៊ូតុង​ការេ​ពណ៌​ខ្មៅ"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"ប៊ូតុង​ការ៉េ​ពណ៌​ស​"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"រង្វង់​ពណ៌​ក្រហម​​​ធំ"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"រង្វង់​ពណ៌​ខៀវ​ធំ"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"ពេជ្រ​ពណ៌​ទឹកក្រូច​ធំ"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"ពេជ្រ​ពណ៌​ខៀវ​​ធំ"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"ពេជ្រ​ពណ៌​ទឹកក្រូច​​តូច"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"ពេជ្រ​ពណ៌​ខៀវ​​តូច"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"ត្រីកោណ​ពណ៌​ក្រហម​កំពូល​ឡើងលើ"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"ត្រីកោណ​ពណ៌​ក្រហម​កំពូល​​ចុះ​ក្រោម"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"ត្រីកោណ​ពណ៌​ក្រហម​តូច​កំពូល​ឡើងលើ"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"ត្រីកោណ​ពណ៌​ក្រហម​​តូច​កំពូល​​ចុះ​ក្រោម"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"មុខ​នាឡិកា​ម៉ោង​មួយ"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"មុខ​នាឡិកា​ម៉ោង​ពីរ"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"មុខ​នាឡិកា​ម៉ោង​បី"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"មុខ​នាឡិកា​ម៉ោង​បួន"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"មុខ​នាឡិកា​ម៉ោង​​ប្រាំ"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"មុខ​នាឡិកា​ម៉ោង​ប្រាំមួយ"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"មុខ​នាឡិកា​ម៉ោង​ប្រាំពីរ"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"មុខ​នាឡិកា​ម៉ោង​ប្រាំបី"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"មុខ​នាឡិកា​ម៉ោង​ប្រាំ​បួន"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"មុខ​នាឡិកា​ម៉ោង​ដប់"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"មុខ​នាឡិកា​ម៉ោង​ដប់​មួយ"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"មុខ​នាឡិកា​ម៉ោង​ដប់​ពីរ"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"មុខ​នាឡិកា​ម៉ោង​មួយ​កន្លះ"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"មុខ​នាឡិកា​ម៉ោង​ពីរ​កន្លះ"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"មុខ​នាឡិកា​ម៉ោង​​បី​​កន្លះ"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"មុខ​នាឡិកា​ម៉ោង​​បួន​​កន្លះ"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"មុខ​នាឡិកា​ម៉ោង​ប្រាំ​កន្លះ"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"មុខ​នាឡិកា​ម៉ោង​​ប្រាំ​មួយ​កន្លះ"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"មុខ​នាឡិកា​ម៉ោង​ប្រាំ​ពីរ​កន្លះ"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"មុខ​នាឡិកា​ម៉ោង​​ប្រាំ​បី​កន្លះ"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"មុខ​នាឡិកា​ម៉ោង​​ប្រាំ​បួន​​​កន្លះ"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"មុខ​នាឡិកា​ម៉ោង​ដប់​កន្លះ"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"មុខ​នាឡិកា​ម៉ោង​ដប់​​មួយ​កន្លះ"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"មុខ​នាឡិកា​ម៉ោង​ដប់​ពីរ​​កន្លះ"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"ភ្នំ​ហ្វូជី"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"អគារ​ទី​ក្រុង​តូក្យូ"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"រូបសំណាក​​សេរីភាព"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"គំនូរ​ស្រមោល​​ជប៉ុន"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"ម៉ូយ៉ៃ"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"មុខ​ញញឹម​ខាំ​ធ្មេញ"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"មុខ​ញញឹម​ខាំ​ធ្មេញ​ជា​មួយ​ភ្នែក​បើក"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"មុខ​ទ​ទឹក​មាន​ភ្នែក​រីករាយ"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"មុខ​ញញឹម​បើក​មាត់"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"មុខ​ញញឹម​បើក​មាត់ និង​បើក​ភ្នែក"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"ញញឹម​មុខ​​បើក​មាត់ និង​ខ្វល់ខ្វាយ"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"ញញឹម​មុខ​​បើក​មាត់ និង​​បិទ​ភ្នែក​បន្តិច"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"មុខ​ញញឹម​មាន​រង្វង់​ខាង​លើ"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"មុខ​ញញឹម​​មាន​ស្នែង"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"មុខ​មិច​ភ្នែក"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"មុខ​ញញឹម​បើក​ភ្នែក"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"មុខ​បង្ហាញ​រសជាតិ​អាហារ​ឆ្ងាញ់"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"មុខ​​ធូរ​​ស្រាល"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"មុខ​ញញឹម​ជា​មួយ​ភ្នែក​រូប​បេះ​ដូង"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"មុខ​ញញឹម​ពាក់​វ៉ែនតា​ខ្មៅ"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"មុខ​ញញឹម​ចំអក"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"មុខ​​អព្យាក្រឹត"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"មុខ​គ្មាន​អារម្មណ៍"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"មុខ​អត់​សប្បាយ​ចិត្ត"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"មុខ​​​មាន​​ញើស"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"មុខគិត"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"មុខ​​យល់​ច្រឡំ"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"មុខ​​អាក្រក់"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"មុខ​ថើប"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"មុខ​បង្ហាញ​ការ​ថើប"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"មុខ​ថើប​បើក​ភ្នែក"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"មុខ​ថើប​បិទ​ភ្នែក"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"មុខ​លៀន​​អណ្ដាត"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"មុខ​លៀន​​អណ្ដាត ហើយ​មិច​ភ្នែក"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"មុខ​លៀន​អណ្ដាត ហើយ​​បិទ​ភ្នែក​បន្តិច"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"មុខ​ខកចិត្ត"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"មុខ​​ព្រួយ​បារម្ភ"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"មុខ​​ខឹង"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"មុខ​ក្និកក្នក់"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"មុខ​យំ"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"មុខ​លំបាក"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"មុខ​ជ័យ​ជំនះ"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"មុខ​ខកចិត្ត​ប៉ុន្តែ​ធូរស្រាល"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"មុខ​ក្រញូវ​បើកមាត់"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"មុខ​ខូច​ចិត្ត"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"មុខ​ភ័យ​ខ្លាច"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"មុខ​​នឿយហត់"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"មុខ​​ងងុយ​គេង"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"មុខ​អស់កម្លាំង​​"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"មុខ​ក្រញេវក្រញូវ​"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"មុខ​យំ​លឺៗ"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"មុខ​បើក​មាត់"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"មុខ​ស្ងៀមស្ងាត់"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"មុខ​បើក​មាត់​ ហើយ​មាន​ញើស"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"មុខ​ស្រែក​ដោយ​ភ័យ​ខ្លាច"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"មុខ​រ​ភ្ញាក់​ផ្អើល"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"មុខ​ក្រហម"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"មុខ​កំពុង​ដេក"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"មុខ​​កំពុង​វិលមុខ"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"មុខ​អត់មាន​មាត់"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"មុខ​ពាក់​ម៉ាស់"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"មុខ​ឆ្មា​ញញឹម​ខាំធ្មេញ​ ហើយ​បើក​ភ្នែក"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"មុខ​ឆ្មា​ស្រក​ទឹកភ្នែក"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"មុខ​ឆ្មា​ញញឹម​ ហើយ​បើក​មាត់"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"មុខ​ឆ្មា​ញញឹម​ជា​មួ​យ​ភ្នែក​រាង​បេះដូង"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"មុខ​ឆ្មា​ជា​មួយ​ការ​ញញឹម​ញាក់​មុខ"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"មុខ​ឆ្មា​ថើប​ហើយ​បិទ​ភ្នែក"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"មុខ​ឆ្មា​ក្និកក្នក់"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"មុខ​ឆ្មា​យំ"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"មុខ​ឆ្មា​នឿយ​ហត់"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"មុខ​គ្មាន​កាយវិការ​ល្អ"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"មុខ​មាន​កាយវិការ​យល់ព្រម"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"មនុស្ស​អោន​ខ្លួន​ខ្លាំង"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"ស្វា​បិទ​ភ្នែក"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"ស្វា​បិទ​ត្រចៀក"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"ស្វា​បិទ​មាត់"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"មនុស្ស​សប្បាយ​​លើក​ដៃ​មួយ"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"លើក​ដៃ​ទាំង​ពីរ​អបអរ"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"មនុស្ស​ចង​ចិញ្ចើម"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"មនុស្ស​មាន​មុខ​ក្និកក្នក់"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"មនុស្ស​អោប​ដៃ"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"គ្រាប់​​រ៉ុកកែត"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"ឧទ្ធម្ភាគចក្រ"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"ក្បាល​រថភ្លើង"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"ទូរ​​រថភ្លើង"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"រថភ្លើង​ល្បឿន​លឿន"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"រថភ្លើង​ល្បឿន​លឿន​​មាន​ច្រមុះ"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"រថភ្លើង​"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"មេត្រូ"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"រថភ្លើង​ប្រើ​​​ពន្លឺ"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"ស្ថានីយ"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"រថយន្ត​រត់​លើ​ផ្លូវ​ដែក"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"រថយន្ត​រត់​លើ​ផ្លូវ​ដែក"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"រថយន្តក្រុង"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"រថយន្ត​ក្រុង​ខាង​មុខ"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"រថយន្ត​ប្រើ​ចរន្ត​អគ្គិសនី"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"ចំណត​រថយន្ត​ក្រុង"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"រថយន្ត​ទេសចរណ៍​​​តូច"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"រថយន្ត​សង្គ្រោះ​បន្ទាន់"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"ម៉ាស៊ីន​ភ្លើង"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"រថយន្ត​ប៉ូលិស"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"រថយន្ត​ប៉ូលិស​ខាង​មុខ"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"តាក់ស៊ី"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"តាក់ស៊ី​ខាង​មុខ"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"រថយន្ត"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"រថយន្ត​ខាង​មុខ"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"រថយន្ត​​​សម្រាប់​កម្សាន្ត​"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"រថយន្ត​​ចែក​ចាយ"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"ឡាន​កាមីយ៉ុង"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"ត្រាក់ទ័រ"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"ប្រព័ន្ធ​ផ្លូវ​រថភ្លើង"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"ផ្លូវ​​រថភ្លើង​កាត់​​ភ្នំ"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"ផ្លូវ​រថភ្លើង​ផ្អាក​ដំណើរការ"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"ខ្សែ​កាប​ឆ្លង​ភ្នំុ"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"ផ្លូវ​រថភ្លើង​លើ​អាកាស"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"កប៉ាល់"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"ទូកចែវ"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"ទូក​ល្បឿន​លឿន"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"ភ្លើង​ចរាចរណ៍"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"ភ្លើង​ចរាចរណ៍​បញ្ឈរ"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"សញ្ញា​​សំណង់"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"រថយន្ត​​ប៉ូលិស​បើក​សារ៉ែន​វិល"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"បង្គោល​ទង់ជាតិ​រាង​ត្រីកោណ​"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"ទ្វារ"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"សញ្ញា​ហាម​ចូល"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"​សញ្ញា​ជក់​បារី"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"ហាម​ជក់​បារី"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"និមិត្តសញ្ញា​ដាក់​សំរាម​ក្នុង​ធុង"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"និមិត្តសញ្ញា​ហាម​ចោល​សំរាម"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"និមិត្ត​សញ្ញា​ទឹក​ចល័ត"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"និមិត្ត​សញ្ញា​​ទឹក​មិន​ចល័ត"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"កង់"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"ហាម​ជិះ​កង់"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"អ្នក​ជិះកង់"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"អ្នក​ជិះ​កង់​ឡើង​ភ្នំ"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"ថ្មើរជើង"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"មិន​សម្រាប់​ថ្មើរ​ជើង"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"កុមារ​​ឆ្លងកាត់"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"និមិត្ត​សញ្ញា​បុរស"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"និមិត្ត​សញ្ញា​ស្ត្រី"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"បន្ទប់ទឹក"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"និមិត្ត​សញ្ញា​ទារក"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"បង្គន់"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"បន្ទប់​ទឹក"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"ផ្កាឈូក​ងូត​ទឹក"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"​ងូតទឹក"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"អាង​​ងូត​ទឹក"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"ការ​ត្រួត​ពិនិត្យ​លិខិត​ឆ្លង​ដែន"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"គយ"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"ប្រកាស​​ឥវ៉ាន់"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"ឥវ៉ាន់​នៅ​សល់"</string>
+</resources>
diff --git a/java/res/values-km-rKH/strings-talkback-descriptions.xml b/java/res/values-km-rKH/strings-talkback-descriptions.xml
index 76bc35f84..0f0ac5600 100644
--- a/java/res/values-km-rKH/strings-talkback-descriptions.xml
+++ b/java/res/values-km-rKH/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"គ្មាន​អត្ថបទ​​​បាន​បញ្ចូល"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> កែ <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> ទៅ​ជា <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> អនុវត្ត​ការ​កែ​ស្វ័យ​ប្រវត្តិ"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"កូដ​គ្រាប់​ចុច %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"បើក Shift (​ប៉ះ​ដើម្បី​បិទ)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"បើក Caps lock (ប៉ះ​​ដើម្បី​បិទ)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"និមិត្ត​សញ្ញា​​ច្រើន​ទៀត"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"និមិត្តសញ្ញា"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"លុប"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"និមិត្តសញ្ញា"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"អក្សរ"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"មុន"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"បាន​បើក Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"បាន​បើក Caps lock"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"បាន​បិទ Shift"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"របៀប​និមិត្ត​សញ្ញា"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"របៀប​និមិត្ត​សញ្ញា​​ច្រើន​ទៀត"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"របៀប​អក្សរ"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"របៀប​ទូរស័ព្ទ"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"​របៀប​និមិត្ត​សញ្ញា​ទូរស័ព្ទ"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"ទីកន្លែង"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"និមិត្តសញ្ញា"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"សញ្ញា​អារម្មណ៍"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-km-rKH/strings.xml b/java/res/values-km-rKH/strings.xml
index 519aa44d0..c7b6f2b4f 100644
--- a/java/res/values-km-rKH/strings.xml
+++ b/java/res/values-km-rKH/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"ជម្រើស​​បញ្ចូល"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"ពាក្យ​បញ្ជា​កំណត់​ហេតុ​​ការ​ស្រាវជ្រាវ"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"រក​មើល​ឈ្មោះ​ទំនាក់ទំនង"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"កម្មវិធី​ពិនិត្យ​អក្ខរាវិរុទ្ធ​ប្រើ​ធាតុ​ពី​​ក្នុង​បញ្ជី​ទំនាក់ទំនង​របស់​អ្នក"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"ញ័រ​នៅ​ពេល​ចុច​គ្រាប់ចុច"</string>
@@ -29,7 +28,7 @@
<string name="popup_on_keypress" msgid="123894815723512944">"លេច​ឡើង​នៅ​​ពេល​ចុច​គ្រាប់​ចុច"</string>
<string name="general_category" msgid="1859088467017573195">"ទូទៅ"</string>
<string name="correction_category" msgid="2236750915056607613">"ការ​កែ​អត្ថបទ"</string>
- <string name="gesture_typing_category" msgid="497263612130532630">"បញ្ចូល​ដោយ​ប្រើ​កាយវិការ"</string>
+ <string name="gesture_typing_category" msgid="497263612130532630">"បញ្ចូល​ដោយ​ប្រើ​កាយវិការ​"</string>
<string name="misc_category" msgid="6894192814868233453">"ជម្រើស​ផ្សេងទៀត"</string>
<string name="advanced_settings" msgid="362895144495591463">"ការ​កំណត់​កម្រិត​ខ្ពស់"</string>
<string name="advanced_settings_summary" msgid="4487980456152830271">"ជម្រើស​សម្រាប់​អ្នក​ជំនាញ"</string>
@@ -39,7 +38,7 @@
<string name="show_language_switch_key_summary" msgid="7343403647474265713">"បង្ហាញ​នៅ​ពេល​ដែល​បើក​ភាសា​បញ្ចូល​ច្រើន"</string>
<string name="sliding_key_input_preview" msgid="6604262359510068370">"បង្ហាញ​ទ្រនិច​បង្ហាញ​ស្លាយ"</string>
<string name="sliding_key_input_preview_summary" msgid="6340524345729093886">"បង្ហាញ​​សញ្ញា​មើល​​ឃើញ​ខណៈ​ពេល​ដែល​រុញ​ពី​ឆ្វេង ឬ​​គ្រាប់​ចុច​​និមិត្ត​សញ្ញា"</string>
- <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"​សោ​លេចឡើង​បោះបង់​ការ​​ពន្យារពេល"</string>
+ <string name="key_preview_popup_dismiss_delay" msgid="6213164897443068248">"​សោ​លេចឡើង​បោះបង់​ការ​​ពន្យារពេល​"</string>
<string name="key_preview_popup_dismiss_no_delay" msgid="2096123151571458064">"គ្មាន​ការ​ពន្យារពេល"</string>
<string name="key_preview_popup_dismiss_default_delay" msgid="2166964333903906734">"លំនាំដើម"</string>
<string name="abbreviation_unit_milliseconds" msgid="8700286094028323363">"<xliff:g id="MILLISECONDS">%s</xliff:g> មិល្លី​វិនាទី"</string>
@@ -47,9 +46,11 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"ស្នើ​ឈ្មោះ​ទំនាក់ទំនង"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"ប្រើ​ឈ្មោះ​ពី​ទំនាក់ទំនង​សម្រាប់​ការ​​ស្នើ និង​​​កែ"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"ការ​ស្នើ​ផ្ទាល់​ខ្លួន"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"រយៈ​ពេល​ចុច​ដកឃ្លា​ពីរដង"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"ប៉ះ​ដកឃ្លា​ពីរ​​ដង​បញ្ចូល​​​រយៈ​ពេល​ដែល​អនុវត្ត​តាម​ដកឃ្លា"</string>
- <string name="auto_cap" msgid="1719746674854628252">"ការ​សរសេរ​ជា​អក្សរ​ធំ​​ស្វ័យប្រវត្តិ"</string>
+ <string name="auto_cap" msgid="1719746674854628252">"ការ​សរសេរ​ជា​អក្សរ​ធំ​​ស្វ័យប្រវត្តិ​"</string>
<string name="auto_cap_summary" msgid="7934452761022946874">"សរសេរ​ពាក្យ​ដំបូង​​​ជា​អក្សរ​ធំ​​នៃ​ប្រយោគ​នីមួយ​ៗ"</string>
<string name="edit_personal_dictionary" msgid="3996910038952940420">"វចនានុក្រម​ផ្ទាល់ខ្លួន"</string>
<string name="configure_dictionaries_title" msgid="4238652338556902049">"ផ្នែក​បន្ថែម​វចនានុក្រម"</string>
@@ -60,7 +61,7 @@
<string name="prefs_suggestion_visibility_show_only_portrait_name" msgid="3859783767435239118">"បង្ហាញ​នៅ​ក្នុង​របៀប​បញ្ឈរ"</string>
<string name="prefs_suggestion_visibility_hide_name" msgid="6309143926422234673">"លាក់​ជានិច្ច"</string>
<string name="prefs_block_potentially_offensive_title" msgid="5078480071057408934">"ទប់ស្កាត់​​ពាក្យ​​បំពាន"</string>
- <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"កុំ​ស្នើ​ឲ្យ​ពាក្យ​បំពាន​មាន​សក្ដានុពល"</string>
+ <string name="prefs_block_potentially_offensive_summary" msgid="2371835479734991364">"កុំ​ស្នើ​ឲ្យ​ពាក្យ​បំពាន​មាន​សក្ដានុពល​"</string>
<string name="auto_correction" msgid="7630720885194996950">"ការ​កែ​​​ស្វ័យប្រវត្តិ"</string>
<string name="auto_correction_summary" msgid="5625751551134658006">"ចន្លោះ​មិន​ឃើញ ​និង​សញ្ញា​​វណ្ណយុត្ត​កែ​ពាក្យ​ដែល​បាន​វាយ​ខុស​ស្វ័យប្រវត្តិ"</string>
<string name="auto_correction_threshold_mode_off" msgid="8470882665417944026">"បិទ"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"​​បញ្ចូល​ភាសា"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"ប៉ះ​ម្ដង​ទៀត​ ដើម្បី​រក្សា​ទុក"</string>
<string name="has_dictionary" msgid="6071847973466625007">"មាន​វចនានុក្រម"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"បើក​មតិត្រឡប់"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"ជំនួយ​​​ធ្វើ​ឲ្យ​​ប្រសើរ​ឡើង​​នៃ​កម្មវិធី​កែ​​វិធី​សាស្ត្រ​​បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ​ ដោយ​ផ្ញើ​ស្ថិតិ​​ប្រើ​ប្រាស់​ ​និង​របាយការណ៍​គាំង"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"រូបរាង​ក្ដារចុច"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"អង់គ្លេស (​អង់គ្លេស)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"អង់គ្លេស (សហរដ្ឋ​អាមេរិក)"</string>
@@ -118,12 +117,11 @@
<string name="enable" msgid="5031294444630523247">"បើក"</string>
<string name="not_now" msgid="6172462888202790482">"មិនមែន​ឥឡូវ"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"មាន​រចនាប័ទ្ម​បញ្ចូល​ដូច​គ្នា​ដូច​ហើយ៖ <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"របៀប​ការ​សិក្សា​ដែល​អាច​ប្រើ​បាន"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"ពន្យារពេល​​​ចុច​គ្រាប់​ចុច​ឲ្យ​​យូរ"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ថិរវេលា​​ញ័រ​​ពេល​ចុច​គ្រាប់ចុច"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"កម្រិត​សំឡេង​ពេល​ចុច​គ្រាប់​ចុច"</string>
<string name="prefs_read_external_dictionary" msgid="2588931418575013067">"អាន​ឯកសារ​វចនានុក្រម​ខាង​ក្រៅ"</string>
- <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"គ្មាន​ឯកសារ​វចនានុក្រម​នៅ​ក្នុង​ថត​ទាញ​យក"</string>
+ <string name="read_external_dictionary_no_files_message" msgid="4947420942224623792">"គ្មាន​ឯកសារ​វចនានុក្រម​នៅ​ក្នុង​ថត​ទាញ​យក​​"</string>
<string name="read_external_dictionary_multiple_files_title" msgid="7637749044265808628">"ជ្រើស​ឯកសារ​វចនានុក្រម​ ដើម្បី​ដំឡើង"</string>
<string name="read_external_dictionary_confirm_install_message" msgid="4782116251651288054">"ពិត​ជា​ដំឡើង​ឯកសារ​នេះ​សម្រាប់ <xliff:g id="LANGUAGE_NAME">%s</xliff:g>?"</string>
<string name="error" msgid="8940763624668513648">"មាន​កំហុស"</string>
@@ -154,7 +152,7 @@
<string name="dictionary_provider_name" msgid="3027315045397363079">"កម្មវិធី​ផ្ដល់​វចនានុក្រម"</string>
<string name="dictionary_service_name" msgid="6237472350693511448">"សេវាកម្ម​​វចនានុក្រម"</string>
<string name="download_description" msgid="6014835283119198591">"ព័ត៌មាន​បច្ចុប្បន្នភាព​វចនានុក្រម"</string>
- <string name="dictionary_settings_title" msgid="8091417676045693313">"ផ្នែក​បន្ថែម​វចនានុក្រម"</string>
+ <string name="dictionary_settings_title" msgid="8091417676045693313">"ផ្នែក​បន្ថែម​វចនានុក្រម​​"</string>
<string name="dictionary_install_over_metered_network_prompt" msgid="3587517870006332980">"វចនានុក្រម​​​​​អាច​ប្រើ​បាន"</string>
<string name="dictionary_settings_summary" msgid="5305694987799824349">"ការ​កំណត់​សម្រាប់​វចនានុក្រម"</string>
<string name="user_dictionaries" msgid="3582332055892252845">"វចនានុក្រម​​​អ្នក​ប្រើ"</string>
@@ -170,10 +168,10 @@
<string name="message_updating" msgid="4457761393932375219">"ពិនិត្យមើល​បច្ចុប្បន្នភាព"</string>
<string name="message_loading" msgid="5638680861387748936">"កំពុង​ផ្ទុក..."</string>
<string name="main_dict_description" msgid="3072821352793492143">"វចនានុក្រម​ចម្បង"</string>
- <string name="cancel" msgid="6830980399865683324">"បោះ​បង់"</string>
+ <string name="cancel" msgid="6830980399865683324">"បោះ​បង់​"</string>
<string name="go_to_settings" msgid="3876892339342569259">"ការ​កំណត់"</string>
<string name="install_dict" msgid="180852772562189365">"ដំឡើង"</string>
- <string name="cancel_download_dict" msgid="7843340278507019303">"បោះ​បង់"</string>
+ <string name="cancel_download_dict" msgid="7843340278507019303">"បោះ​បង់​"</string>
<string name="delete_dict" msgid="756853268088330054">"លុប"</string>
<string name="should_download_over_metered_prompt" msgid="1583881200688185508">"ភាសា​ដែល​បាន​ជ្រើស​នៅ​លើ​ឧបករណ៍​ចល័ត​មាន​វចនានុក្រម​អាច​ប្រើ​បាន។&lt;br/&gt; យើង​ផ្ដល់​អនុសាសន៍​ឲ្យ &lt;b&gt;ទាញ​យក&lt;/b&gt; វចនានុក្រម​ភាសា <xliff:g id="LANGUAGE_NAME">%1$s</xliff:g> ដើម្បី​បង្កើន​បទពិសោធន៍​វាយ​បញ្ចូល​របស់​អ្នក។&lt;br/&gt; &lt;br/&gt; ការ​ទាញ​យក​អាច​ចំណាយ​ពេល​ប្រហែល​ពីរ​នាទី​នៅ​តាម 3G។ ការ​គិត​ថ្លៃ​អាច​អនុវត្ត​ប្រសិន​បើ​អ្នក​មិន​ប្រើ &lt;b&gt;ផែនការ​ទិន្នន័យ​គ្មាន​ដែន​កំណត់&lt;/b&gt;.&lt;br/&gt; បើ​អ្នក​មិន​ប្រាកដ​​ថា​ផែនការ​ណា​មួយ​ដែល​អ្នក​មាន យើង​ផ្ដល់​អនុសាសន៍​ឲ្យ​​ភ្ជាប់​វ៉ាយហ្វាយ ដើម្បី​ចាប់ផ្ដើម​ទាញ​យក​ដោយ​ស្វ័យ​ប្រវត្តិ។&lt;br/&gt; &lt;br/&gt; ជំនួយ៖ អ្នក​អាច​ទាញ​យក និង​លុប​វចនានុក្រម​ដោយ​ចូល​ទៅ​ &lt;b&gt;ភាសា &amp; ការ​បញ្ចូល&lt;/b&gt; នៅ​ក្នុង​ម៉ឺនុយ &lt;b&gt;ការ​កំណត់&lt;/b&gt; សម្រាប់​ឧបករណ៍​ចល័ត។"</string>
<string name="download_over_metered" msgid="1643065851159409546">"ទាញ​យក​ឥឡូវ​នេះ (<xliff:g id="SIZE_IN_MEGABYTES">%1$.1f</xliff:g> មេកាបៃ)"</string>
@@ -191,7 +189,7 @@
<string name="user_dict_settings_add_word_option_name" msgid="6665558053408962865">"ពាក្យ៖"</string>
<string name="user_dict_settings_add_shortcut_option_name" msgid="3094731590655523777">"ផ្លូវកាត់​៖"</string>
<string name="user_dict_settings_add_locale_option_name" msgid="4738643440987277705">"ភាសា៖"</string>
- <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"វាយ​បញ្ចូល​ពាក្យ"</string>
+ <string name="user_dict_settings_add_word_hint" msgid="4902434148985906707">"វាយ​បញ្ចូល​ពាក្យ​"</string>
<string name="user_dict_settings_add_shortcut_hint" msgid="2265453012555060178">"ផ្លូវកាត់​ជា​ជម្រើស"</string>
<string name="user_dict_settings_edit_dialog_title" msgid="3765774633869590352">"កែ​ពាក្យ"</string>
<string name="user_dict_settings_context_menu_edit_title" msgid="6812255903472456302">"កែ"</string>
diff --git a/java/res/values-ko/strings-action-keys.xml b/java/res/values-ko/strings-action-keys.xml
index 04febeeea..34cd8a21d 100644
--- a/java/res/values-ko/strings-action-keys.xml
+++ b/java/res/values-ko/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"이전"</string>
<string name="label_done_key" msgid="7564866296502630852">"완료"</string>
<string name="label_send_key" msgid="482252074224462163">"전송"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"중지"</string>
<string name="label_wait_key" msgid="5891247853595466039">"대기"</string>
</resources>
diff --git a/java/res/values-ko/strings-talkback-descriptions.xml b/java/res/values-ko/strings-talkback-descriptions.xml
index 6142c6a3b..d5d71f935 100644
--- a/java/res/values-ko/strings-talkback-descriptions.xml
+++ b/java/res/values-ko/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"입력한 텍스트 없음"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g>을(를) 누르면 <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>을(를) <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>(으)로 수정합니다."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g>을(를) 누르면 자동 수정됩니다."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"키 코드 %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift 키"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift 사용(사용하지 않으려면 탭하세요.)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock 사용(사용하지 않으려면 탭하세요.)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"기호 더보기"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift 키"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"기호"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift 키"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"삭제"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"기호"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"문자"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"이전"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift 사용"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock 사용"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift 사용 중지됨"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"기호 모드"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"기호 더보기 모드"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"문자 모드"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"다이얼 모드"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"전화 기호 모드"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"장소"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"기호"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"이모티콘"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ko/strings.xml b/java/res/values-ko/strings.xml
index 4037abd02..3eff38c9d 100644
--- a/java/res/values-ko/strings.xml
+++ b/java/res/values-ko/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"입력 옵션"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"로그 명령 탐색"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"연락처 이름 조회"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"맞춤법 검사기가 주소록의 항목을 사용합니다."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"키를 누를 때 진동 발생"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"주소록 이름 활용"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"추천 및 수정에 주소록의 이름 사용"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"맞춤 추천 검색어"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"더블스페이스 마침표"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"스페이스바를 두 번 탭하면 마침표와 공백 한 개가 삽입됩니다."</string>
<string name="auto_cap" msgid="1719746674854628252">"자동 대문자화"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"입력 언어"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"저장하려면 다시 터치"</string>
<string name="has_dictionary" msgid="6071847973466625007">"사전 사용 가능"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"사용자 의견 사용"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"사용 통계 및 오류 보고서를 자동으로 전송하여 입력 방법 편집기의 개선에 도움을 줍니다."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"키보드 테마"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"영어(영국)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"영어(미국)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"사용"</string>
<string name="not_now" msgid="6172462888202790482">"나중에"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"같은 입력 스타일이 다음과 같이 이미 존재합니다. <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"가용성 연구 모드"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"키 길게 누르기 지연"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"키를 누를 때 진동 시간"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"키를 누를 때 소리 볼륨"</string>
diff --git a/java/res/values-ky/strings.xml b/java/res/values-ky/strings.xml
index 3758c2df1..8165a3c7d 100644
--- a/java/res/values-ky/strings.xml
+++ b/java/res/values-ky/strings.xml
@@ -126,9 +126,7 @@
<skip />
<!-- no translation found for has_dictionary (6071847973466625007) -->
<skip />
- <!-- no translation found for prefs_enable_log (6620424505072963557) -->
<skip />
- <!-- no translation found for prefs_description_log (5827825607258246003) -->
<skip />
<!-- no translation found for keyboard_layout (8451164783510487501) -->
<skip />
@@ -138,7 +136,6 @@
<skip />
<!-- no translation found for subtype_no_language_qwerty (2956121451616633133) -->
<skip />
- <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
<skip />
<!-- no translation found for prefs_keypress_vibration_duration_settings (1829950405285211668) -->
<skip />
diff --git a/java/res/values-land/config.xml b/java/res/values-land/config.xml
index 43ae068f2..37bf22fb0 100644
--- a/java/res/values-land/config.xml
+++ b/java/res/values-land/config.xml
@@ -58,6 +58,8 @@
<fraction name="config_key_shifted_letter_hint_ratio_5row">48%</fraction>
<dimen name="config_suggestions_strip_height">36dp</dimen>
+ <dimen name="config_suggestions_strip_horizontal_margin">54dp</dimen>
+ <dimen name="config_suggestions_strip_edge_key_width">54dp</dimen>
<dimen name="config_more_suggestions_row_height">36dp</dimen>
<integer name="config_max_more_suggestions_row">2</integer>
<fraction name="config_min_more_suggestions_width">60%</fraction>
diff --git a/java/res/values-lo-rLA/strings-action-keys.xml b/java/res/values-lo-rLA/strings-action-keys.xml
index 08dc983e0..239930583 100644
--- a/java/res/values-lo-rLA/strings-action-keys.xml
+++ b/java/res/values-lo-rLA/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"ກ່ອນໜ້າ"</string>
<string name="label_done_key" msgid="7564866296502630852">"Done"</string>
<string name="label_send_key" msgid="482252074224462163">"ສົ່ງ"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"ຢຸດຊົ່ວຄາວ"</string>
<string name="label_wait_key" msgid="5891247853595466039">"ລໍຖ້າ"</string>
</resources>
diff --git a/java/res/values-lo-rLA/strings-emoji-descriptions.xml b/java/res/values-lo-rLA/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..0747fa629
--- /dev/null
+++ b/java/res/values-lo-rLA/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"ເຄື່ອງ​ໝາຍ​ລິຂະສິດ"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"ເຄື່ອງໝາຍ​ຈົດທະບຽນ"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Double exclamation mark"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Exclamation question mark"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Trade mark sign"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Information source"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Left right arrow"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Up down arrow"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"North west arrow"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"North east arrow"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"South east arrow"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"South west arrow"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Leftwards arrow with hook"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Rightwards arrow with hook"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"ເບິ່ງ"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Hourglass"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Black right-pointing double triangle"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Black left-pointing double triangle"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Black up-pointing double triangle"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Black down-pointing double triangle"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"ໂມງປຸກ"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Hourglass with flowing sand"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Circled latin capital letter m"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Black small square"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"White small square"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Black right-pointing triangle"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Black left-pointing triangle"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"White medium square"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Black medium square"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"White medium small square"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Black medium small square"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Black sun with rays"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Cloud"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Black telephone"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Ballot box with check"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Umbrella with rain drops"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Hot beverage"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"White up pointing index"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"White smiling face"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Aries"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Taurus"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Gemini"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"ມະເຮັງ"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Leo"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Virgo"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Libra"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Scorpius"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Sagittarius"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Capricorn"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Aquarius"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Pisces"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Black spade suit"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Black club suit"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Black heart suit"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Black diamond suit"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Hot springs"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Black universal recycling symbol"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Wheelchair symbol"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Anchor"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Warning sign"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"High voltage sign"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Medium white circle"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Medium black circle"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Soccer ball"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"ເບສບອລ"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Snowman without snow"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Sun behind cloud"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Ophiuchus"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"No entry"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Church"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Fountain"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Flag in hole"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Sailboat"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Tent"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Fuel pump"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Black scissors"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"White heavy check mark"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Airplane"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Envelope"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Raised fist"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Raised hand"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Victory hand"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Pencil"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Black nib"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Heavy check mark"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Heavy multiplication x"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Sparkles"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Eight spoked asterisk"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Eight pointed black star"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Snowflake"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Sparkle"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Cross mark"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Negative squared cross mark"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Black question mark ornament"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"White question mark ornament"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"White exclamation mark ornament"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Heavy exclamation mark symbol"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"ຫົວໃຈ​ສີ​ດຳ​ໜັກ"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Heavy plus sign"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Heavy minus sign"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Heavy division sign"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Black rightwards arrow"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Curly loop"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Double curly loop"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Arrow pointing rightwards then curving upwards"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Arrow pointing rightwards then curving downwards"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Leftwards black arrow"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Upwards black arrow"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Downwards black arrow"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Black large square"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"White large square"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"White medium star"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Heavy large circle"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Wavy dash"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Part alternation mark"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Circled ideograph congratulation"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Circled ideograph secret"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"ໄພ້​ນົກກະຈອກ​ເທດ​ມັງ​ກອນ​ແດງ"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"ກຳລັງ​ຫຼິ້ນ​ໄພ້​ໂຈກເກີ​ສີ​ດຳ"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"ເລືອດ​ກຣຸບ A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"ເລືອດ​ກຣຸບ B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"ເລືອດ​ກຣຸບ O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"ບ່ອນ​ຈອດ​ລົດ"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"ເລືອດ​ກຣຸບ AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"CL ສີ່​ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Cool ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Free ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"ID ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"New ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"N G ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"OK ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"SOS ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"UP! ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"VS ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"ບໍລິການ ແບບ​ກະຕະກະນະ​ສີ່​ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"ບໍລິການ ແບບ​ກະຕະກະນະ​ສີ່​ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Squared ideograph charge-free"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Squared ideograph reserved-seat"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Squared ideograph prohibitation"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Squared ideograph vacancy"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Squared ideograph acceptance"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Squared ideograph full occupancy"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Squared ideograph paid"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Squared ideograph monthly"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Squared ideograph application"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Squared ideograph discount"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Squared ideograph in business"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Circled ideograph advantage"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Circled ideograph accept"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"ພະ​ຍ​ຸ​ໝຸນ​ໄຊ​ໂຄລນ"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"ໝອກ​ຄວັນ"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"​ຄັນ​ຮົ່ມ​ປິດ"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"​ຄ່ຳ​ຄືນ​ກັບ​ແສງ​ດາວ"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"​ຕາ​ເວັນ​ຂຶ້ນ​ຢູ່​ພູ"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"​ຕາ​ເວັນ​ຂຶ້ນ"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"​ເມືອງ​ໃນ​ຍາມ​​​ໃກ້​ຄ່ຳ"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"​ຕາ​ເວັນ"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"ຮຸ້ງ"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"ຂົວ​ໃນ​ຍາມ​ຄ່ຳ​ຄືນ"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"​ຄື້ນ​ນ້ຳ"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"ພູ​ເຂົາ​ໄຟ"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"ທາງ​ຊ້າງ​ເຜືອກ"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"ໜ່ວຍ​ໂລກ​ຢູ​ໂຣບ​ອາ​ຟຣິ​ກາ"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"​ໜ່ວຍ​ໂລກ​ອາ​ເມ​ລິ​ກາ"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"​ໜ່ວຍ​ໂລກ​ເອ​ເຊຍອອສ​ເຕຣ​ເລຍ"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"ໜ່ວຍ​ໂລກ​ມີ​ເສັ້ນ​ຕັດ"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"ສັນ​ຍາ​ລັກ​​ເດືອນ​ມືດ"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"ສັນ​ຍາ​ລັກ​ເດືອນບໍ່​ເຕັມ​ດວງ"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"ສັນ​ຍາ​ລັກ​ເດືອນ​ເຄິ່ງດວງ​ທຳ​ອິດ"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"ສັນ​ຍາ​ລັກ​ເດືອນ​ຂຶ້ນ"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"​ສັນ​ຍາ​ລັກ​ເດືອນ​ເຕັມ​ດວງ"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"ສັນ​ຍາ​ລັກ​ເດືອນ​ໃກ້​ເຕັມ​ດວງ"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"ສັນ​ຍາ​ລັກ​ເດືອນ​ເຄິ່ງ​ດວງ​​ທ້າຍ"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"ສັນ​ຍາ​ລັກ​ເດືອນ​ສ້ຽວ"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"​ເດືອນ​ສ້ຽວ"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"ເດືອນ​ມືດ​ມີ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"ເດືອນ​ເຄິ່ງດວງ​ທຳ​ອິດ​ມີ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"ສັນ​ຍາ​ລັກ​ເດືອນ​ເຄິ່ງ​ດວງ​​ທ້າຍ​ມີ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"​ເດືອນ​ເຕັມ​ດວງ​ມີ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"​ຕາ​ເວັນ​ມີ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"ດາວ​ເຮືອງ​ແສງ"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"​ດາວ​ຕົກ"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"​ລູກ​ເກົາ​ລັດ"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"​ກ້າ​ໄມ້"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"ຕົ້ນ​ໄມ້​ບໍ່​ຜັດ​ໃບ"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"​ຕົ້ນ​ໄມ້​ຜັດໃບ​"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"​ຕົ້ນ​ປາມ"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"​ກະ​ບອງ​ເພັດ"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"​ທິວ​ລິບ"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"ດອກ​ເຊີ​ຣີ"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"​ດອກ​ກຸ​ຫລາບ"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"​ສະ​ກຸນ​ຊະ​ບາ"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"ດອກ​ຕາ​ເວັນ"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"ດອກ​ໄມ້​ບານ"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"ຕົ້ນ​ສາ​ລີ"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"​ຕົ້ນ​ເຂົ້າ"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"​ສະ​ໝຸນ​ໄພ"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"ໂຄລ​ເວີ​ສີ່​ໃບ"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"​ໃບ​ເມ​ເປີ້ນ"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"ໃບ​ໄມ້ຫຼົ່ນ"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"ໃບ​ໄມ້​ປິວ​ຕາມ​ລົມ"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"​ເຫັດ"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"​ໝາກ​ເຫຼັ່ນ"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"​ໝາກ​ເຂືອ"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"​ອະງຸ່ນ"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"ໝາກ​ໂມ"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"ໝາກ​ໂມ"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"ສົ້ມ​ຂຽວ​ຫວານ"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"ໝາກ​ນາວ"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"​​ໝາກກ້ວຍ"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"​ໝາກ​ນັດ"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"​ໝາກ​ໂປ່ມ​ແດງ"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"​ໝາກ​ໂປ່ມ​ຂຽວ"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"ລູກ​ສາ​ລີ່"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"​ລູກ​ພີດ"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"​ເຊີ​ຣີ"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"​ສະ​ຕຣໍ​ເບີ​ຣີ"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"​ແຮມ​ເບີ​ເກີ"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"​ພິດ​ຊ່າ​ປ່ຽງ​ນຶ່ງ"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"ຊີ້ນ​ຕິດ​ກະ​ດູກ"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"​ຂາ​ສັດ​ປີກ"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"ເຂົ້າ​ໜົມ​ເຂົ້າ"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"ເຂົ້າ​ປັ້ນ"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"​ເຂົ້າ​ສຸກ"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"ເຂົ້າ​ແກງ​ກະ​ຫລີ່"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"​ຖ້ວຍ​ຮ້ອນ"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"​ສະ​ປາ​ເກັດ​ຕີ"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"​ເຂົ້າ​ຈ​ີ່"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"​ມັນຝຣັ່ງ​ທອດ"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"​ມັນ​ຝຣັ່ງ​ຫວານ​ອົບ"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"ດັງ​ໂງະ"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"ໂອ​ເດັ້ງ"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"​ຊູ​ຊິ"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"​ກຸ້ງ​ທອດ"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"ເຄັກ​ປາ​ແບບ​ໝຸນໆ"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"ກະ​ແລ່ມ​ນຸ້ມ"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"ນ້ຳ​ແຂງ​ໃສ"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"ກະ​ແລ່ມ"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"​ໂດ​ນັດ"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"​ຄຸ​ກ​ກີ້"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"​ຊັອກ​ໂກ​ແລັດບາ"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"ແຄນດີ້"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"​ໂລ​ລິ​ປັອບ"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"​ຄັ​ສ​ຕາດ"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"ໝໍ້​ນ້ຳ​ເຜິ້ງ"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"ຊັອດ​ເຄັກ"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"ເບັນ​ໂຕ"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"ໝໍ້​ອາ​ຫານ"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"​ຄົວ​ກິນ"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"​ມີດ​ແລະ​ສ້ອມ"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"ຖ້ວຍ​ຊາ​ແບບ​ບໍ່​ມີ​ດ້າມ​ຈັບ"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"ຈອກ​ແລະ​​ເຫຼົ້າສາ​ເກ"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"​ຈອກວາຍ"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"​ຈອກ​ຄັອກ​ເທວ"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"ເຄື່ອງ​ດື່ມ​ເຂດ​ຮ້ອນ"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"ແກ້ວ​ເບຍ"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"ຕຳ​ແກ້ວ​ເບຍ"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"​​​ຕຸກ​ນົມ​ແອ​ນ້ອຍ"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"​ຣິບບອນ"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"​ຂອງ​ຂວັນ​ຫໍ່​ໄວ້"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"​ເຄັກ​ວັນ​ເກີດ"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"ແຈັກ-ໂອ-ແລນເທິນ"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"​ຕົ້ນ​ຄ​ຣິສ​ມາ​ສ"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"ຊານ​ຕາ​ຄລອສ"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"ບັ້ງໄຟດອກ"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"ດອກ​ໄມ້​ໄຟ"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"​ບານ​ລູນ"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"ປາ​​ຕີ້​ປັອບ​ເປີ"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"ບານ​ຄອນ​ເຟັດ​ຕີ"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"ຕົ້ນ​ທາ​ນາ​ບາ​ຕະ"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"ທຸງ​ໄຂວ່​ກັນ"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"ການ​ຕົກ​ແຕ່ງ​ຕົ້ນ​ພາຍ"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"ຕຸກກະຕາ​ຍີ່ປຸ່ນ"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"ທຸງ​ປາ​ຄາຣ໌ບ"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"ກະ​ດິ່ງ​ລົມ"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"ພິ​ທີ​ຊົມ​ເດືອນ"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"ກະ​ເປົາ​ໂຮງ​ຮຽນ"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"​ໝວກສຳ​ເລັດ​ການ​ສຶກ​ສາ"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"​ມ້າ​ໝຸນ"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"ຊິງ​ຊ້າ​ສະ​ຫວັນ"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"​ລົດ​ໄຟ​ເຫາະ"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"​ເບັດ​ຕຶກ​ປາ​ກັບ​ປາ"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"ໄມໂຄຣໂຟນ"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"​ກ້ອງ​ຖ່າຍ​ໜັງ"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"​ໂຮງ​ຮູບ​ເງົາ"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"​ຫູ​ຟັງ"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"ຈານ​ສີ"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"ໝວກ​ຊົງ​ສູງ"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"ເຕັ້ນ​ລະ​ຄອນ​ສັດ"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"​ປີ້"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"ແຄລັບ​ເປີ​ບອດ"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"​ສິນ​ລະ​ປະ​ການ​ສະ​ແດງ"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"ວິ​ດີ​ໂອ​ເກມ"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"ຍິງ​ເຂົ້າ​ເປົ້າ"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"​ສະ​ລັອດ​ແມັດ​ຊີນ"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"ສະນຸກເກີ"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"ລູກ​ເຕົ໋າ"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"ໂບລິງ"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"ໄພ່​ດອກ​ໄມ້"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"​ໂນດ​ດົນ​ຕີ"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"​ໂນດ​ດົນ​ຕີຫຼາຍ​ອັນ"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"​ແຊັກ​ໂຊ​ໂຟນ"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"ກີຕ້າ"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"ແປ້ນ​ພິມ​ດົນ​ຕີ"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"ແຕ"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"​ໄວ​ໂອ​ລິນ"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"ສະ​ກໍ​ດົນ​ຕີ"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"ເສື້ອ​ແລ່ນ​ກັບ​ສາຍ​ພາຍ"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"ໄມ້​ແລະ​ລູກ​ເທນນິສ"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"ສະ​ກີ​ແລະ​ເກີບ​ສະ​ກີ"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"​ບານ​ບ້​ວງແລະ​ບ່ວງ"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"ທຸງ​ເສັ້ນ​ໄຊ"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"ສະ​ໂນບອດ​ເດີ"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"​ນັກ​ແລ່ນ"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"​ນັກ​ເຊີບ"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"​ຮາງວັນ"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"​ການ​ແຂ່ງ​ມ້າ"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"​ອາ​ເມ​ລິ​ກັນ​ຟຸດບອນ"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"​ຣັກ​ບີ"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"​ນັກ​ລອຍ​ນ້ຳ"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"​​ປຸກ​ເຮືອນ"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"​ເຮືອນ​ພ້ອມ​ສວນ"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"​ອາ​ຄານ​ສຳ​ນັກ​ງານ"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"​ຫ້ອງ​ການ​ໄປ​ສະ​ນີ​ຍີ່​ປຸ່ນ"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"​ຫ້ອງ​ການ​ໄປ​ສະ​ນີ​ຢູ​ໂຣບ"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"​ໂຮງ​ໝໍ"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"​ທະ​ນາ​ຄານ"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"ເອ​ທີ​ເອັມ"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"​ໂຮງ​ແຮມ"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"ມ່ານ​ຮູດ"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"​ຮ້ານ​ສະ​ດວກ​ຊື້"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"ໂຮງຮຽນ"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"​ຫ້າງ​ສັບ​ພະ​ສິນ​ຄ້າ"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"​ໂຮງ​ງານ"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"​ໂຄມ​ໄຟ​ອິ​ຊາ​ກາ​ຢະ"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"​ຜາ​ສາດ​ຍີ່​ປຸ່ນ"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"​ຜາ​ສາດ​ຢູ​ໂຣບ"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"​ໜູ"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"ໜູ"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Ox"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"ຄວາຍ"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"ງົວ"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"​ເສືອ​ດາວ"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"​ກະ​ຕ່າຍ"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"ແມວ"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"​ມັງ​ກອນ"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"​ແຂ້"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"​ວານ"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"​ຫອຍ"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"​ງູ"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"​ມ້າ"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"ແກະ"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"​ແບ້"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"​ແກະ"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"ລິງ"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"​ໄກ່​ໂຕ​ຜູ້"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"​ໄກ່"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"​ໝາ"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"​ໝູ"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"​ໝູ​ປ່າ"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"​ຊ້າງ"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"​ປາ​ເໝິກ"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"ເປືອກ​ຫອຍ​ກຽວ"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"​ແມງ​ໄມ້"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"​ມົດ"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"​ເຜິ້ງ"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"ແມງ​ເຕົ່າ​ທອງ"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"​ປາ"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"​ປາ​ເຂດ​ຮ້ອນ"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"​ປາ​ປັກ​ເປົ້າ"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"​ເຕົ່າ"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"​ໄຂ່​ຟັກ"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"​ໄກ່​ນ້ອຍ"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"​ໜ້າ​ໄກ່​ນ້ອຍ"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"​ນົກ"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"ເພນກວິນ"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"​ໂຄ​ອາ​ລາ"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"​ພຸນ​ເດິນ"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"ອູດ​ອາ​ຣາ​ບຽນ"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"ອູດ​ແບັກ​ທຣຽນ"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"​ໂລ​ມາ"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"​ໜ້າ​ໜູ"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"​ໜ້າ​ງົວ"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"​ໜ້າ​ເສືອ"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"​ໜ້າ​ກະ​ຕ່າຍ"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"​ໜ້າ​ແມວ"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"​ໜ້າ​ມັງ​ກອນ"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"​ວານ​ພົ່ນ​ນ້ຳ"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"​ໜ້າ​ມ້າ"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"​ໜ້າ​ລິງ"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"​ໜ້າ​ໝາ"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"​ໜ້າ​ໝູ"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"​ໜ້າ​ກົບ"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"ໜ້າ​ໜູ​ແຮມສະເຕີ"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"​ໜ້າ​ໝາ​ປ່າ"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"​ໜ້າ​ໝີ"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"​ໜ້າ​ແພນ​ດ້າ"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"​ດັງ​ໝູ"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"ຮອຍ​ຕີນ"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"​ຕາ"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"​ຫູ"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"​ດັງ"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"​ປາກ"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"​ລິ້ນ"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"ຫຼັງ​ມື​ຊີ້​ຂຶ້ນ​ເທິງ"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"ຫຼັງ​ມື​ຊີ້​ລົງ​ລຸ່ມ"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"ຫຼັງ​ມື​ຊີ້​ໄປ​ຊ້າຍ"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"ຫຼັງ​ມື​ຊີ້​ໄປ​ຂວາ"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"ກຳ​ປັ້ນ"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"ມື​ໂບກ​ໄປ​ມາ"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"​ມື​ເຮັດ​ທ່າ​ໂອ​ເຄ"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"ຍົກ​ໂປ້​ໃຫ້"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"​ຊິ້ວ​ນີ້​ໂປ້​ລົງ"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"​ຕົບ​ມື"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"ແບ​ມື​ອອກ"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"​ມຸງ​ກຸດ"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"​ໝວກ​ຜູ່​ຍິງ"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"​ແວ່ນ​ຕາ"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"​ເນັກ​ໄທ"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"​ເສືອ​ຢືນ"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"​​ໂສ້ງຢີນ"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"​ຊ​ຸດ​ເດຣສ"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"​ກິ​ໂມ​ໂນ"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"​ບິ​ກີ​ນີ"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"​ເສື້ອ​ຜ້າ​ຜູ່​ຍິງ"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"ກະ​ເປົາ​"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"ກະ​ເປົາ"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"​ກະ​ເປົາ"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"​ເກີບ​ຜູ່​ຊາຍ"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"​ເກີບກ​ິ​ລ​າ"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"ເກີບ​ສົ້ນ​ສູງ"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"​ເກີບ​ຜູ່​ຍິງ"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"​ເກີດ​ບູດ​ຜູ່​ຍິງ"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"​ຮອຍ​ຕີນ"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"ຄົນ​ເປັນ​ເງົາ"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"ຄົນ​ເປັນ​ເງົາ"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"​ຜູ່​ຊ​າຍ"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"​ຜ​ູ່​ຍິງ"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"​ຜູ່​ຊາຍ"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"​ຜູ່​ຍິງ"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"ຄອບຄົວ"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"​ຊາຍ​ຍິງ​ຈູງ​ມື​ກັນ"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"​ຊ​າຍ​ສອງ​ຄົນ​ຈູງ​ມື​ກັນ"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"​ຍິງ​ສອງ​ຄົນ​ຈູງ​ມື​ກັນ"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"​ເຈົ້າ​ໜ້າ​ທີ່​ຕຳຫຼວດ"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"ຜູ່​ຍິງ​ໃສ່​ຫູ​ກະ​ຕ່າຍ"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"​ເຈົ້າ​ສາວ​ມີ​ຜ້າ​ຄຸມ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"ຄົນ​ຜົມ​​ສີບລອນ"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"ຄົນ​ໃສ່​ໝວກ​​ກົວ​ປ​ີ​ເໝົາ"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"ຄົນ​ໃສ່​ຜ້າ​ໂພກ​ຫົວ"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"ຄົນ​ອາ​ຍຸຫຼາຍກວ່າ"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"​ຜູ່​ຍິງ​ອາ​ຍຸຫຼາຍກວ່າ"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"​ແອ​ນ້ອຍ"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"​ຄົນ​ເຮັດ​ວຽກ​ກໍ່​ສ້າງ"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"ເຈົ້າ​ຍິງ"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"ຍັກ​ຍີ່​ປຸ່ນ"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"ກລອບ​ບິນ​ຍີ່​ປຸ່ນ"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"​ຜີ"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"ທູດ​​ແອ​ນ້ອຍສະ​ຫວັນ"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"ມະ​ນຸດ​ຕ່າງ​ດາວ"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"​ສັດ​ປະ​ຫລາດ​ຕ່າງ​ດາວ"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"ອິມປ໌"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"​ຫົວ​ກະ​ໂຫຼກ"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"​ພະ​ນັກ​ງານ​ບໍ​ລິ​ການ​ຂໍ້​ມູນ"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"​ຍາມ"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"​ນັກ​ເຕັ້ນ"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"​ລິ​ບ​ສະ​ຕິກ"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"​ຢາ​ທາ​ເລັບ"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"​ນວດ​ໜ້າ"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"ຕັດ​ຜົມ"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"ເສົາ​ຮ້ານ​ຕັດ​ຜົມ"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"​ເຂັມ​ສີດ​ຢາ"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"​ຢາ​ເມັດ"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"​ຮອຍ​ຈູບ"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"​ຈົດ​ໝາຍ​ຮັກ"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"​ແຫວນ"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"​ຫິນ​ອັນ​ຍະ​ມະ​ນີ"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"ຈູບ"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"​ຊໍ່​ດອກ​ໄມ້"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"​ຄ​ູ່​ຮັກ​ກັບ​ຫົວ​ໃຈ"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"ການ​ແຕ່ງດອງ"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"​ຫົວ​ໃຈ​ເຕັ້ນ"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"​ອົກ​ຫັກ"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"​ສອງ​ໃຈ"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"​ຫົວ​ໃຈ​ເປັນ​ປະ​ກາຍ"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"​ຫົວ​ໃຈ​ຂະ​ຫຍາຍ"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"​ລູກ​ສອນ​ປັກ​ຫົວ​ໃຈ"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"​ໃຈ​ສີ​ຟ້າ"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"​ໃຈ​ສີ​ຂຽວ"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"​ໃຈ​ສີ​ເຫຼືອງ"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"​ໃຈ​ສີ​ມ່ວງ"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"​ຫົວ​ໃຈ​ກັບ​ຣິບບອນ"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"​ຫົວ​ໃຈ​ວົງ​ມົນ"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"​ຕົກ​ແຕ່ງ​ຫົວ​ໃຈ"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"​ຮູບ​ເພັດ​ມີ​ຈຸດ​ທາງ​ກາງ"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"ຫຼອດ​ໄຟ"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"​ສັນ​ຍາ​ລັກ​ໃຈ​ຮ້າຍ"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"​ລະ​ເບີດ"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"​ສັນ​ຍາ​ລັກ​ນອນຫຼັບ"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"​ສັນ​ຍາ​ລັກ​ປະ​ທະ​ກັນ"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"​ສັນ​ຍາ​ລັກເຫື່ອ​ກະ​ຈາຍ"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"​ຢົດ​ນ້ຳ"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"​ສັນ​ຍາ​ລັກ​ແລ່ນ"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"ກອງ​ອຸດ​ຈາ​ລະ"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"ເບັ່ງ​ກ້າມ"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"​ດາວ​ໝຸນ"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"ບອນ​ລູນ​ຄຳ​ເວົ້າ"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"​ບອນ​ລູນ​ຄວາມ​ຄິດ"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"ດອກ​ໄມ້​ຂາວ"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"​ສັນ​ຍາ​ລັກ​ຮ້ອຍ"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"​ຖົງ​ເງິນ"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"​ອັດ​ຕາ​ແລກ​ປ່ຽນ"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"​ສັນ​ຍາ​ລັກ​ໂດ​ລ່າ​ແບບ​ໜາ"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"ບັດເຄຣດິດ"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"​ທະ​ນະ​ບັດ​ເງິນ​ເຢນ"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"ທັນນະບັດ​ຮູບ​ເງິນ​ໂດລ່າ"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"​​ທະ​ນະ​ບັດ​ເງິນ​ຢູ​ໂຣ"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"​ທະ​ນະ​ບັດ​ເງິນ​ພາວດ໌"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"ເງິນ​ຕິດ​ປີກ"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"​ແຜນ​ວາດ​ຊີ້​ຂຶ້ນ​ມີ​ຮູບ​ເງິນ​ເຢນ"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"​ບ່ອນ​ນັ່ງ"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"​ຄອມ​ພິວ​ເຕີ​ສ່ວນ​ບຸກ​ຄົນ"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"​ກະ​ເປົາ​ເດີນ​ທາງ"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"​ມິ​ນິ​ດິສ"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"ຟລັອບ​ປີ້​ດິສ"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"​ອັອບ​ຕິ​ຄອນ ດິ​ສ"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"​ດີ​ວີ​ດີ"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"​ໄຟລ໌​ໂຟນ​ເດີ"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"ເປີດ​ໂຟນເດີ​ໄຟລ໌"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"​ເຈ້ຍ​ມ້ວນ​ທາງ​ລຸ່ມ"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"​ເຈ້ຍ​ຫງາຍ​ໜ້າ​ຂຶ້ນ"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"ປະຕິທິນ"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"​ປະ​ຕ​ິ​ທິນ​ຖືກ​ຈີກ"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"​ດັດ​ຊະ​ນີ​ບັດ"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"ແຜນ​ວາດ​ຊີ້​ຂຶ້ນ"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"​ແຜນ​ວາດ​ຊີ້​ລົງ"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"​ແຜນ​ວາດ​​ແບບບາ"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"​ຄລິບບອດ"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"​ເຂັມ​ມຸດ"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"​ເຂັມ​ມຸດ​ຫົວ​ມົນ"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"ອັນ​ໜີບ​ເຈ້ຍ"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"​​ໄມ້ບັນ​ທັດ"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"​ໄມ້​ບັດ​ທັດ​ສາມຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"​ແຖບ​ບຸກ​ມາກ"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"ປຶ້ມ​ບັນ​ຊີ"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"ສະມຸດບັນທຶກ"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"ສະ​ມຸດ​ບັນ​ທຶກ​ແບບ​ມີ​ປົກ​ຕົບ​ແຕ່ງ"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"​ປຶ້ມ​ທີ່​ປິດ​ໄວ້"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"​ປຶ້ມ​ທີ່​ເປີດ​ໄວ້"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"​ປຶ້ມ​ຂຽວ"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"​ປຶ້ມ​ຟ້າ"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"​ປຶ້ມ​ສົ້ມ"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"ປຶ້ມ"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"​ປ້າຍ​ຊື່"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"ເລື່ອນ"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"​ບັນ​ທຶກ"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"​ຫູ​ໂທ​ລະ​ສັບ"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"ເພກເຈີ"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"​ເຄື່ອງ​ແຟັກ"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"ຈານ​ດາວ​ທຽມ"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"​ໂທ​ລະ​ໂຄ່ງ"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"ໂທ​ລະ​ໂຂ່ງ"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"ຖາດ​ຂາ​ອອກ"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"​ຖາດ​ຂາ​ເຂົ້າ"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"ພັດສະດຸ"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"​ສັນ​ຍາ​ລັກ​ອີ​ເມວ"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"ຈົດ​ໝາຍ​ເຂົ້າ"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"​ຈົດ​ໝາຍ​ມີ​ລູກ​ສອນ​ຢູ່​ທາງ​ເທິງ"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"ກ່ອງ​ຈົດ​ໝາຍ​ປິດ​ໄວ້ມີ​ທຸງ​ທາງ​ລຸ່ມ"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"​ກ່ອງ​ຈົດ​ໝາຍ​ປິດ​ໄວ້​ມີ​ທຸງ​ສະ​ບັດ"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"​ກ່ອງ​ຈົດ​ໝາຍ​​ເປິດ​ໄວ້​ມີ​ທຸງ​ສະ​ບັດ"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"ກ່ອງ​ຈົດ​ໝາຍ​ເປິດ​ໄວ້ມີ​ທຸງ​ທາງ​ລຸ່ມ"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"ຕູ້​ໄປ​ສະ​ນີ"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"ແຕ​ໄປ​ສະ​ນີ"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"​ໜັງ​ສື​ພິມ"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"​ໂທ​ລະ​ສັບ​​ມື​ຖື"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"ໂທ​ລະ​ສັບ​ມື​ຖື​ມີ​ລູກ​ສອນ​ຊີ້​ໄປ​ທາງ​ຂວາ​ຢູ່​ທາງ​ຊ້າຍ"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"​ໂໝດ​ສັ່ນ"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"​ໂທ​ລະ​ສັບ​ມື​ຖື​ປິດ"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"ບໍ່​ມີ​ໂທ​ລະ​ສັບ​ມື​ຖື"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"ຂີດ​ສັນ​ຍານ​ໂທ​ລະ​ສັບ"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"ກ້ອງຖ່າຍຮູບ"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"ກ້ອງວິ​ດີ​ໂອ"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"​ໂທ​ລະ​ພາບ"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"ວິທະຍຸ"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"​ກະ​ແຊັດ​ວິ​ດີ​ໂອ"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"ລູກ​ສອນ​ໄຂວ່​ກັນ"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"ລູກ​ສອນ​ໝຸນ​ວົນ​​ຕາມ​ເຂັມ​ໂມງ"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"ລູກ​ສອນ​ໝຸນ​ຕາມ​ເຂັມ​ໂມງ​ມີ​ເລກ​ສູນ​ໃນ​ວົງ​ມົນ​ຢູ່​ຊ້າຍ​ລຸ່ມ"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"ລູກ​ສອນ​ໝຸນ​ຕາມ​ເຂັມ​ໂມງ​ລວງ​ຕັ້ງ"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"​ລູກ​ສອນ​ໝຸນ​ທວນ​ເຂັມ​ໂມງ​ໃນ​ຂອບ​ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"ສັນ​ຍາ​ລັກ​ຄວາມ​ແຈ້ງ​ຕ່ຳ"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"ສັນ​ຍາ​ລັກ​ຄວາມ​ແຈ້ງ​​ສູງ"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"ລຳ​ໂພງ​ມີ​ຂີດ​ຂ້າ"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"ລຳໂພງ"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"ລຳ​ໂພງ​ມີ​ຄື້ນ​ສຽງ​ອັນ​ນຶ່ງ"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"ລຳ​ໂພງ​ມີ​ຄື້ນ​ສຽງ​​ສາມ​ອັນ"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"ແບັດເຕີຣີ"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"​​ປລັກ​ໄຟ​ຟ້າ"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"ແວ່ນ​ຂະ​ຫຍາຍ​ສ່ອງ​ໄປ​ທາງ​ຊ້າຍ"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"ແວ່ນ​ຂະ​ຫຍາຍ​ສ່ອງ​ໄປ​ທາງ​ຂວາ"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"​ລັອກ​ມີ​ປາກ​ກາ"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"ລັອກ​ທີ່​ປິດ​ໄວ້​ພ້ອມ​ກະ​ແຈ"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"​ກະ​ແຈ"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"ລັອກ"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"​​ລັອກ​ທີ່​ເປີດ​ໄວ້"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"​ກະ​ດິ່ງ"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"​ກະ​ດິ່ງ​ມີ​ຂີດ​ຂ້າ"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"ບຸກມາກ"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"​ສັນ​ຍາ​ລັກ​ລິ້ງ"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"​ປຸ່ມ​ເຄື່ອງ​ໝາຍ​ເລືອກ"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"ລູກ​ສອນ​ຊີ້​ໄປ​ທາງ​ຊ້າຍ​ມີ​ຄຳ​ວ່າ​ Back"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"​ລູກ​ສອນ​ຊີ້​ໄປ​ທາງ​ຊ້າຍ​ມີ​ຄຳ​ວ່າ​ End"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"ຄຳ​ວ່າ On ມີ​ເຄື່ອງ​ໝາຍ​ທ​້ວງ​ກັບ​ລູກ​ສອນ​ຊີ້​ໄປ​ທາງ​ຊ້າຍ​ແລະ​ຂວາ​ຢູ່​ເທິງ"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"​ຄຳ​ວ່າ Soon ມີ​ລູກ​ສອນ​ຊີ້​ໄປ​ທາງ​ຂວາ​ຢູ່​ເທິງ"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"​ຄຳ​ວ່າ Top ມີ​ລູກ​ສອນ​ຊີ້​ໄປ​ທາງ​ເທິງ​ຢູ່​ເທິງ"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"ສັນ​ຍາ​ລັກ​ຫ້າມ​ຕ່ຳ​ກວ່າ​ສິບ​ແປດ"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"ເລກ​ສິບ​ໃນ​ຂອບ​ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"ABCD ໃນ​ຂອບ​ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"abcd ໃນ​ຂອບ​ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"ໂຕ​ເລກໃນ​ຂອບ​ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"ໃສ່​ສັນຍາລັກ​ເພື່ອ​ສັນຍາລັກ"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"ໂຕ​ອັກ​ສອນ​ລາ​ຕິນໃນ​ຂອບ​ສີ່ຫຼ່ຽມ"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"ໄຟ"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"​ໄຟ​ສາຍ"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"​ປະ​ແຈ"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"​ຄ້ອນ"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"ນັອດ"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"ມີດ"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"​ປືນ​ສັ້ນ"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"​ກ້ອງ​ຈຸ​ລະ​ທັດ"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"​ກ້ອງ​ສ​່ອງ"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"ບານ​ຄ​ຣິສ​ຕັນ"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"ດາວ​ຫົກ​ຫຼ່ຽມ​ມີ​ຈ້ຳ​ທາງ​ກາງ"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"ສັນ​ຍາ​ລັກ​ພາ​ສາ​ຍີ່​ປຸ່ນ​ສຳ​ລັບ​ຜູ່​ເລີ່ມ​ຕົ້ນ"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"ສັນ​ຍາ​ລັກ​ສາມ​ງ່າມ"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"ປຸ່ມ​ສີ່ຫຼ່ຽມ​ສີ​ດຳ"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"ປຸ່ມ​ສີ່ຫຼ່ຽມ​ສີ​​ຂາວ"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"​ວົງ​ມົນ​​ໃຫຍ່ສີ​ແດງ"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"​ວົງ​ມົນ​​ໃຫຍ່ສີ​​ຟ້າ"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"ເພັດ​ເມັດ​ໃຫຍ່​ສີ​ສົ້ມ"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"ເພັດ​ເມັດ​ໃຫຍ່​ສີ​​ຟ້າ"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"ເພັດ​ເມັດ​ນ້ອຍ​ສີ​ສົ້ມ"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"ເພັດ​ເມັດ​ນ້ອຍ​ສີ​​ຟ້າ"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"ສາມຫຼ່ຽມ​ສີ​ແດງ​ຊີ​ຂຶ້ນ"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"ສາມຫຼ່ຽມ​ສີ​ແດງ​ຊີ​​ລົງ"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"ສາມຫຼ່ຽມ​ນ້ອຍສີ​ແດງ​ຊີ​ຂຶ້ນ"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"ສາມຫຼ່ຽມ​ນ້ອຍສີ​ແດງ​ຊີ​ລົງ"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​ນຶ່ງ​ໂມງ"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສອງໂມງ"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສາມໂມງ"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສີ່ໂມງ"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ຫ້າໂມງ"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ຫົກໂມງ"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ເຈັດໂມງ"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ແປດໂມງ"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ເກົ້າໂມງ"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສິບໂມງ"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສິບ​ເອັດໂມງ"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສິບ​ສອງໂມງ"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​ນຶ່ງ​ໂມງ​​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສອງ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສາມ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສີ່​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ຫ້າ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ຫົກ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ເຈັດ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ແປດ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​​ເກົ້​າໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​ສິບ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສິບ​ເອັດ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"ໂມງ​ພ້ອມ​ເຂັມ​ຊີ້​ໄປ​ເວ​ລາ​​ສິບ​ສອງ​ໂມງ​ເຄິ່ງ"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"​ພູ​ເຂົາ​ໄຟ​ຟູ​ຈິ"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"​ຫໍ​ຄອຍ​ໂຕ​ກຽວ"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"​ເທ​ພີ​ເສ​ລີ​ພາບ"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"ເງົາ​ປະ​ເທດ​ຍີ່​ປຸ່ນ"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"ໂມ​ອາຍ"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"ໜ້າ​ຍິ້ມ​ເຫັນ​ແຂ້ວ"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"ໜ້າ​ຕາຍິ້ມ​ເຫັນ​ແຂ້ວ"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"ໜ້າ​ພ້ອມດ້ວຍ​ນ້ຳ​ຕາ​ແຫ່ງ​ຄວາມ​ສຸກ"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"​ໜ້າ​ຍິ້ມ​ພ້ອມ​ກັບ​ອ້າ​ປາກ"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"​ໜ້າ​ຕາຍິ້ມ​ພ້ອມ​ກັບ​ອ້າ​ປາກ"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"​ໜ້າ​ຕາຍິ້ມ​ພ້ອມ​ກັບ​ເຫື່ອ​ຕົກ"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"​ໜ້າ​ຕາຍິ້ມ​ພ້ອມ​ກັບ​​ຫຼັບ​ຕາ"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"ໜ້າ​ຍິ້ມ​ພ້ອມ​ມີ​ວົງ​ແຫວນ​ເທິງ​ຫົວ"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"ໜ້າ​ຍິ້ມ​ມີ​ເຂົາ"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"ໜ້າ​ຍິ້ມ​ກະ​ພິບ​ຕາ​ຂ້າງ​ນຶ່ງ"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"ໜ້າ​ຕາ​ຍິ້ມ​ແຍ້ມ"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"​ໜ້າ​ຍິ້ມ​ລິ້ນ​ເລຍ​ສົບ"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"​ໜ້າ​ຜ່ອນ​ຄາຍ"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"ໜ້າ​ຍິ້ມ​ພ້ອມ​ຕາ​ເປັນ​ຫົວ​ໃຈ"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"​ໜ້າ​ຍິ້ມ​ໃສ່​ແວ່ນ​ຕາ"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"ໜ້າຍິ້ມ​​ມີ​ເລດ​ສະ​ໄນ"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"​ໜ້າ​​ຊື່ໆ"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"ໜ້າບໍ່​ມີ​ຄວາມ​ຮູ້​ສຶກ"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"ໜ້າບໍ່​​ຕະ​ຫລົກ"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"ໜ້າ​ມີ​ເຫື່ອ​ໄຫຼ"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"ໜ້າ​ໝົ່ນ​ໝອງ"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"​ໜ້າ​ສັບ​ສົນ"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"​ໜ້າ​ຜູ່​ຮ້າຍ"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"​ໜ້າ​ຈູບ"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"ໜ້າ​ເປົ່າ​ຈູບ"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"​ໜ້າ​ຈູບ​ພ້ອມ​ກັບ​ຍິ້ມ"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"ໜ້າ​ຍິ້ມ​ພ້ອມ​ກັບຫຼັບ​ຕາ"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"ໜ້າ​​ແລບ​ລິ້ນ"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"ໜ້າ​ແລບ​ລິ້ນຫຼັບ​ຕາ​ຂ້າງ​ນຶ່ງ"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"ໜ້າ​ແລບ​ລິ້ນ​ຫຼັບ​ຕາ​ສອງ​ຂ້າງ"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"​ໜ້າ​ຜິດ​ຫວັງ"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"​ໜ້າ​ເປັນ​ກັງ​ວົນ"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"​​ໜ້າ​ໃຈ​ຮ້າຍ"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"ໜ້າ​ມຸ້ຍ"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"​ໜ້າ​ຮ້ອງ​ໄຫ້"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"ໜ້າ​ຂະ​ໝວດ"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"ໜ້າ​ໃຈ​ຮ້າຍ​ລົມ​ອອກ​ດັງ"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"ໜ້າ​ຜິດ​ຫວັງ​ແຕ່​​ໂລ່ງ​ໃຈ"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"ໜ້າ​ມຸ້ຍ​ອ້າ​ປາກ"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"ໜ້າ​ເຈັບ​ປວດ"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"​ໜ້າ​ຢ້ານ"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"ໜ້າ​​ເມື່ອຍ​ສຸດ​ຂີດ"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"​​ໜ້າ​ເຫງົາ​ນອນ"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"​ໜ້າ​ເມື່ອຍ"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"ໜ້າ​ຍິ້ມ​ແຫ້ງໆ"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"​ໜ້າ​ຮ້ອງ​ໄຫ້​ສຽງ​ດັງ"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"​ໜ້າ​ອ້າ​ປາກ"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"ໜ້າ​ຕະ​ລຶງ​ງຽບ"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"ໜ້າ​ອ້າ​ປາກ​ມີ​ເຫື່ອ​ຕົກ"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"ໜ້າ​ຮ້ອງ​​ດ້ວຍ​ຄວາມ​ຢ້ານ"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"ໜ້າ​ປະຫຼາດ​ໃຈ"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"ໜ້າ​ແດງ"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"​ໜ້າ​ເຫງົາ​ນອນ"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"ໜ້າ​ວິງວຽນ"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"​ໜ້າບໍ່​ມີ​ປາກ"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"​ໜ້າ​ໃສ່​ຜ້າ​ປິດ​ປາກ"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"​ໜ້າແມວ​ຍິ້ມ"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"​ໜ້າ​ແມວ​ຍິ້ມ​ພ້ອມ​ນ້ຳ​ຕາ​ແຫ່ງ​ຄວາມ​ສຸກ"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"​ໜ້າ​ແມວ​ຍິ້ມ​ພ້ອມ​ກັບ​ອ້າ​ປາກ"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Smiling cat face with heart-shaped eyes"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Cat face with wry smile"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Kissing cat face with closed eyes"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Pouting cat face"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Crying cat face"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Weary cat face"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Face with no good gesture"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Face with ok gesture"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Person bowing deeply"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"See-no-evil monkey"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Hear-no-evil monkey"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Speak-no-evil monkey"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Happy person raising one hand"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"ຄົນ​ຍົກ​ມື​ຂຶ້ນ​ສະ​ຫຼອງ"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Person frowning"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Person with pouting face"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Person with folded hands"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Rocket"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Helicopter"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Steam locomotive"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Railway car"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"High-speed train"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"High-speed train with bullet nose"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Train"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metro"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Light rail"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Station"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Tram"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Tram car"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Bus"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Oncoming bus"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Trolleybus"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Bus stop"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Minibus"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulance"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Fire engine"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Police car"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Oncoming police car"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Taxi"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Oncoming taxi"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Automobile"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Oncoming automobile"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Recreational vehicle"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Delivery truck"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"ລົດ​ບັນ​ທຸກ​ພ່ວງ"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Tractor"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Monorail"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Mountain railway"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Suspension railway"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Mountain cableway"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Aerial tramway"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Ship"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Rowboat"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Speedboat"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"ໄຟ​ສັນຍານ​ຈະລາຈອນ​ລວງ​ນອນ"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Vertical traffic light"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Construction sign"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Police cars revolving light"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Triangular flag on post"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Door"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"No entry sign"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Smoking symbol"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"ສັນຍາລັກ​ຫ້າມ​ສູບຢາ"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Put litter in its place symbol"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Do not litter symbol"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Potable water symbol"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Non-potable water symbol"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Bicycle"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"No bicycles"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Bicyclist"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Mountain bicyclist"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Pedestrian"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"No pedestrians"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Children crossing"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Mens symbol"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Womens symbol"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Restroom"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Baby symbol"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Toilet"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"Water closet"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Shower"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Bath"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Bathtub"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Passport control"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Customs"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Baggage claim"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Left luggage"</string>
+</resources>
diff --git a/java/res/values-lo-rLA/strings-talkback-descriptions.xml b/java/res/values-lo-rLA/strings-talkback-descriptions.xml
index 681a21370..c6140fda9 100644
--- a/java/res/values-lo-rLA/strings-talkback-descriptions.xml
+++ b/java/res/values-lo-rLA/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"ບໍ່ມີ​ການໃສ່​ຂໍ້ຄວາມ"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ແກ້​ໄຂ​ <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> ເປັນ <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ດຳ​ເນີນ​ການ​ແກ້​ໄຂ​ອັດ​ຕະ​ໂນ​ມັດ"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"ລະຫັດ​ກະແຈ %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift ເປີດ​ນຳໃຊ້ຢູ່ (ກົດ​ເພື່ອ​ປິດນຳໃຊ້)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock ເປີດຢູ່ (ກົດ​ເພື່ອ​ປິດນຳໃຊ້)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"​ສັນ​ຍາ​ລັກ​ເພີ່ມ​ເຕີມ"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"​ສັນ​ຍາ​ລັກ"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"ລຶບ"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"ສັນຍາລັກ"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"ໂຕອັກ​ສອນ"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"ກ່ອນໜ້ານີ້"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift ເປີດ​ນຳໃຊ້ຢູ່"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock ເປີດນຳໃຊ້ຢູ່"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift ປິດ​ນຳໃຊ້ຢູ່"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"ໂຫມດ​ສັນຍາລັກ"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"ໂໝດ​ສັນ​ຍາ​ລັກ​ເພີ່ມ​ເຕີມ"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"ໂຫມດ​ໂຕອັກ​ສອນ"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"ໂຫມດ​ໂທລະສັບ"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"ໂຫມດ​ສັນຍາລັກ​ໂທລະສັບ"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"ສະຖານທີ່"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"ສັນຍາລັກ"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"​ອີ​ໂມ​ຕິ​ຄອນ"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-lo-rLA/strings.xml b/java/res/values-lo-rLA/strings.xml
index 76fe5e042..bca49e573 100644
--- a/java/res/values-lo-rLA/strings.xml
+++ b/java/res/values-lo-rLA/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"ຕົວເລືອກການປ້ອນຂໍ້ມູນ"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Research Log Commands"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"ເບິ່ງທີ່ຊື່ຂອງລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"ໂຕຊ່ວຍສະກົດໃຊ້ຂໍ້ມູນຈາກລາຍການຂອງລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານ"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"ສັ່ນເຕືອນເມື່ອພິມ"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"ແນະນຳລາຍຊື່ຜູ່ຕິດຕໍ່"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"ໃຊ້ຊື່ຈາກລາຍຊື່ຜູ່ຕິດຕໍ່ສຳລັບການແນະນຳ ແລະ ການຊ່ວຍແກ້ຄຳ"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"ຄຳແນະນຳຕາມການນຳໃຊ້ຂອງທ່ານ"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"ຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດ"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"ກົດທີ່ປຸ່ມຍະຫວ່າງສອງເທື່ອເພື່ອໃສ່ຈ້ຳເມັດແລ້ວຕາມດ້ວຍການຍະຫວ່າງ"</string>
<string name="auto_cap" msgid="1719746674854628252">"ເຮັດໂຕພິມໃຫຍ່ອັດຕະໂນມັດ"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"ພາສາການປ້ອນຂໍ້ມູນ"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"ກົດອີກຄັ້ງເພື່ອບັນທຶກ"</string>
<string name="has_dictionary" msgid="6071847973466625007">"ມີວັດຈະນານຸກົມ"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"ເປີດນຳໃຊ້ຄຳຕິຊົມຈາກຜູ່ໃຊ້"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"ຊ່ວຍເພີ່ມປະສິດທິພາບໂຕແກ້ໄຂການປ້ອນຂໍ້ມູນ ໂດຍການສົ່ງສະຖິຕິການນຳໃຊ້ ແລະການລາຍການຂໍ້ຜິດພາດໂດຍອັດຕະໂນມັດ"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"ສີສັນແປ້ນພິມ"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"ອັງກິດ (ສະຫະລາດຊະອານາຈັກ)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"ອັງກິດ (ສະຫະລັດຯ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"ເປີດນຳໃຊ້"</string>
<string name="not_now" msgid="6172462888202790482">"ບໍ່ແມ່ນຕອນນີ້"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"ຮູບແບບການປ້ອນຂໍ້ມູນທີ່ຄືກັນມີຢູ່ແລ້ວ: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"ໂໝດການສຶກສາ Usability"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"ໄລຍະເວລາຂອງການກົດປຸ່ມ"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ໄລຍະເວລາຂອງການສັ່ນໃນການກົດປຸ່ມ"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"ລະດັບສຽງຂອງການກົດປຸ່ມ"</string>
diff --git a/java/res/values-lt/strings-action-keys.xml b/java/res/values-lt/strings-action-keys.xml
index 39b3894be..20d5ca04d 100644
--- a/java/res/values-lt/strings-action-keys.xml
+++ b/java/res/values-lt/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Anks."</string>
<string name="label_done_key" msgid="7564866296502630852">"Atl."</string>
<string name="label_send_key" msgid="482252074224462163">"Siųs."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pris."</string>
<string name="label_wait_key" msgid="5891247853595466039">"Lauk."</string>
</resources>
diff --git a/java/res/values-lt/strings-talkback-descriptions.xml b/java/res/values-lt/strings-talkback-descriptions.xml
index 07119cb65..4e7f6afef 100644
--- a/java/res/values-lt/strings-talkback-descriptions.xml
+++ b/java/res/values-lt/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nėra įvesto teksto"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> pataiso <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> į <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> atlieka automatinį taisymą"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Klavišo kodas %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Klavišas „Shift“"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Klavišas „Shift“ įjungtas (palieskite, kad išjungtumėte)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Įjungtos didžiosios raidės (palieskite, kad išjungtumėte)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Daugiau simbolių"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Klavišas „Shift“"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simboliai"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Klavišas „Shift“"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Ištrinti"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simbolių klavišas"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Raidžių klavišas"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Ankstesnis"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Klavišas „Shift“ įgalintas"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Didžiųjų raidžių klavišas įgalintas"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Klavišas „Shift“ išjungtas"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Simbolių režimas"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Daugiau simbolių režimas"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Raidžių režimas"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefonų numerių režimas"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefonų numerių simbolių režimas"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Vietos"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simboliai"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Jaustukai"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-lt/strings.xml b/java/res/values-lt/strings.xml
index c049a165e..01ec1bea7 100644
--- a/java/res/values-lt/strings.xml
+++ b/java/res/values-lt/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Įvesties parinktys"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Tyrinėti žurnalo komandas"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kontaktų vardų paieška"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Rašybos tikrinimo progr. naudoja įrašus, esančius kontaktų sąraše"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibruoti, kai paspaudžiami klavišai"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Siūlyti kontaktų vardus"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Siūlant ir taisant naudoti vardus iš „Kontaktų“"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Suasmeninti pasiūlymai"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Tšk. ir tarp. pal. dukart"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dukart palietus tarpo klavišą įterpiamas taškas ir tarpas."</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatinis didžiųjų raidžių rašymas"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Įvesties kalbos"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Jei norite išsaugoti, palieskite dar kartą"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Žodynas galimas"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Įgalinti naudotojų atsiliepimus"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Padėkite patobulinti šią įvesties metodo redagavimo priemonę automatiškai siųsdami naudojimo statistiką ir strigčių ataskaitas"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klaviatūros tema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglų k. (JK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglų k. (JAV)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Įgalinti"</string>
<string name="not_now" msgid="6172462888202790482">"Ne dabar"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Toks pat įvesties stilius jau yra: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tinkamumo tyrimo režimas"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Klavišo ilgo paspaudimo delsa"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrav. paspaudus mygt. trukmė"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Garso paspaudus mygt. garsumas"</string>
diff --git a/java/res/values-lv/strings-action-keys.xml b/java/res/values-lv/strings-action-keys.xml
index c2fbda26b..a3ada38a6 100644
--- a/java/res/values-lv/strings-action-keys.xml
+++ b/java/res/values-lv/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Iepr."</string>
<string name="label_done_key" msgid="7564866296502630852">"Gatavs"</string>
<string name="label_send_key" msgid="482252074224462163">"Sūtīt"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauze"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Gaidīt"</string>
</resources>
diff --git a/java/res/values-lv/strings-talkback-descriptions.xml b/java/res/values-lv/strings-talkback-descriptions.xml
index eb32e9dcc..e68d83afb 100644
--- a/java/res/values-lv/strings-talkback-descriptions.xml
+++ b/java/res/values-lv/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Teksts nav ievadīts"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Nospiežot taustiņu <xliff:g id="KEY_NAME">%1$s</xliff:g>, “<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>” tiek labots uz “<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>”."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Taustiņam <xliff:g id="KEY_NAME">%1$s</xliff:g> ir automātiskas labošanas funkcija."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Taustiņu kods %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Pārslēgšanas taustiņš"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Pārslēgšanas režīms ir iespējots (pieskarieties, lai atspējotu)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Burtslēgs ir iespējots (pieskarieties, lai atspējotu)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Citi simboli"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Pārslēgšanas taustiņš"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simboli"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Pārslēgšanas taustiņš"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Dzēšanas taustiņš"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simboli"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Burti"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Atpakaļ"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Pārslēgšanas režīms ir iespējots"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Burtslēgs ir iespējots"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Pārslēgšanas režīms ir atspējots"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Simbolu režīms"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Citu simbolu režīms"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Burtu režīms"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Tālruņa režīms"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Tālruņa simbolu režīms"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Vietas"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simboli"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emocijzīmes"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-lv/strings.xml b/java/res/values-lv/strings.xml
index 901c3486f..bc4e3e1ea 100644
--- a/java/res/values-lv/strings.xml
+++ b/java/res/values-lv/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Ievades opcijas"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Izpētes žurnāla komandas"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Meklēt kontaktp. vārdus"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Pareizrakst. pārbaudītājs lieto ierakstus no kontaktp. saraksta."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrēt, nospiežot taustiņu"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Ieteikt kontaktp. vārdus"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Izmantot kontaktpersonu vārdus kā ieteikumus un labojumus"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Personalizēti ieteikumi"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dubultpiesk. = punkts"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Divreiz pieskaroties atst. taustiņam, ievada punktu un atstarpi."</string>
<string name="auto_cap" msgid="1719746674854628252">"Automātiska lielo burtu lietošana"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Ievades valodas"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Pieskarieties vēlreiz, lai saglabātu."</string>
<string name="has_dictionary" msgid="6071847973466625007">"Ir pieejama vārdnīca."</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Iespējot lietotāju atsauksmes"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Palīdziet uzlabot šo ievades metodes redaktoru, automātiski nosūtot lietojuma statistiku un avāriju pārskatus."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastatūras motīvs"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Angļu valoda (Lielbritānija)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Angļu valoda (ASV)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Iespējot"</string>
<string name="not_now" msgid="6172462888202790482">"Vēlāk"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Šāds ievades stils jau pastāv: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Lietojamības izpētes režīms"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Taustiņa ilgās nosp. noildze"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Taust. nosp. vibrācijas ilgums"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Taustiņu nosp. skaņas skaļums"</string>
diff --git a/java/res/values-mk/strings.xml b/java/res/values-mk/strings.xml
index 1588534c9..ab2f2625a 100644
--- a/java/res/values-mk/strings.xml
+++ b/java/res/values-mk/strings.xml
@@ -22,7 +22,6 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- no translation found for english_ime_input_options (3909945612939668554) -->
<skip />
- <!-- no translation found for english_ime_research_log (8492602295696577851) -->
<skip />
<!-- no translation found for use_contacts_for_spellchecking_option_title (5374120998125353898) -->
<skip />
@@ -140,9 +139,7 @@
<skip />
<!-- no translation found for has_dictionary (6071847973466625007) -->
<skip />
- <!-- no translation found for prefs_enable_log (6620424505072963557) -->
<skip />
- <!-- no translation found for prefs_description_log (7525225584555429211) -->
<skip />
<!-- no translation found for keyboard_layout (8451164783510487501) -->
<skip />
@@ -198,7 +195,6 @@
<skip />
<!-- no translation found for custom_input_style_already_exists (8008728952215449707) -->
<skip />
- <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
<skip />
<!-- no translation found for prefs_key_longpress_timeout_settings (6102240298932897873) -->
<skip />
diff --git a/java/res/values-mn-rMN/strings-action-keys.xml b/java/res/values-mn-rMN/strings-action-keys.xml
index 77b8f2c05..a855386d0 100644
--- a/java/res/values-mn-rMN/strings-action-keys.xml
+++ b/java/res/values-mn-rMN/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Өмнөх"</string>
<string name="label_done_key" msgid="7564866296502630852">"Дууссан"</string>
<string name="label_send_key" msgid="482252074224462163">"Илгээх"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Түр зогсоох"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Хүлээх"</string>
</resources>
diff --git a/java/res/values-mn-rMN/strings-emoji-descriptions.xml b/java/res/values-mn-rMN/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..f09a51dd9
--- /dev/null
+++ b/java/res/values-mn-rMN/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Зохиогчийн эрхийн тэмдэг"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Бүртгэгдсэн тэмдэг"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Давхар анхаарлын тэмдэг"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Анхаарал, асуултын тэмдэг"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Худалдааны тэмдэг"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Мэдээллийн эх сурвалж"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Зүүн баруун сум"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Дээш доош сум"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Баруун хойд сум"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Зүүн хойд сум"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Зүүн өмнөд сум"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Баруун өмнөд сум"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Зүүн дэгээтэй сум"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Баруун дэгээтэй сум"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"Үзэх"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Элсэн цаг"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Баруун заасан хар давхар гурвалжин"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Зүүн заасан хар давхар гурвалжин"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Дээш заасан хар давхар гурвалжин"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Доош заасан хар давхар гурвалжин"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Сэрүүлэгтэй цаг"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Урссан элсэн цаг"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Дугуйлсан латин том m үсэг"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Хар жижиг дөрвөлжин"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Цагаан жижиг дөрвөлжин"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Баруун заасан хар гурвалжин"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Зүүн заасан хар гурвалжин"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Цагаан дунд дөрвөлжин"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Хар дунд дөрвөлжин"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Цагаан дунд жижиг дөрвөлжин"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Хар дунд жижиг дөрвөлжин"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Цацрагтай хар нар"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Үүл"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Хар утас"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Чектэй саналын хайрцаг"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Борооны дусалтай шүхэр"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Халуун ундаа"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Цагаан дээш заасан долоовор"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Цагаан инээмсэглэсэн царай"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Хонины орд"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Үхрийн орд"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Ихрийн орд"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Хавчийн орд"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Арслангийн орд"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Охины орд"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Жинлүүрийн орд"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Хилэнцийн орд"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Нумын орд"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Матрын орд"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Бумбын орд"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Загасны орд"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Хар гил хөзөр"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Хар цэцэг хөзөр"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Хар бундан хөзөр"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Хар дөрвөлжин хөзөр"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Халуун рашаан"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Хар дахин боловсруулах тэмдэг"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Тэргэнцэрийн тэмдэг"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Зангуу"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Сануулга тэмдэг"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Өндөр хүчдэлийн тэмдэг"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Дунд зэргийн цагаан тойрог"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Дунд зэргийн хар тойрог"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Хөлбөмбөгийн бөмбөг"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Бейсбол"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Цасгүй цасан хүн"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Үүлний цаадах нар"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Тэнгэрийн мөрөн орд"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Орохыг хориглоно"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Сүм"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Усан оргилуур"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Нүхэндэх туг"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Далбаат завь"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Майхан"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Түлшний насос"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Хар хайч"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Цагаан хүнд чек тэмдэг"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Онгоц"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Дугтуй"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Өргөсөн нударга"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Өргөсөн гар"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Ялалтын гар"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Харандаа"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Хар хошуу"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Хүнд чек тэмдэг"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Хүнд үржүүлэх х"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Цацраг"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Найман үзүүрт од"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Найман үзүүртэй хар од"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Цасан ширхэг"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Цацраг"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Загалмайн тэмдэг"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Сөрөг квадрат дарах тэмдэг"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Хар асуултын тэмдэгэн чимэглэл"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Цагаан асуултын тэмдэгэн чимэглэл"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Цагаан анхаарлын тэмдэгэн чимэглэл"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Хүнд анхаарлын тэмдэгэн симбол"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Хүнд хар зүрх"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Хүнд нэмэх тэмдэг"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Хүнд хасах тэмдэг"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Хүнд хуваах тэмдэг"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Хар баруун сум"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Нуман гогцоо"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Давхар нуман гогцоо"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Баруун зааж дээш эргэсэн сум"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Баруун зааж доош эргэсэн сум"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Зүүн заасан хар сум"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Дээш заасан хар сум"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Доош заасан хар сум"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Хар том дөрвөлжин"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Цагаан том дөрвөлжин"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Цагаан дунд од"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Хүнд том тойрог"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Долгионт зураас"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Хэсэг шилжих тэмдэг"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Дугуй идеограф баяр хүргэлт"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Дугуй идеограф нууц"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Mahjong -н улаан луу"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Хөзөрийн хар хүн"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Цусны А бүлэг"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Цусны В бүлэг"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Цусны O бүлэг"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Машины зогсоол"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Цусны AB бүлэг"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"Дөрвөлжин CL"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Дөрвөлжин гоё"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Дөрвөлжин чөлөөтэй"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"Дөрвөлжин ID"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"Дөрвөлжин шинэ"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"Дөрвөлжин N G"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"Дөрвөлжин OK"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"Дөрвөлжин SOS"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"Анхаарлын тэмдэгтэй дөрвөлжин"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"Дөрвөлжин vs"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Энд дөрвөлжин катакана"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Дөрвөлжин катакана үйлчилгээ"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Дөрвөлжин идеограф төлбөргүй"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Дөрвөлжин идеограф захиалсан суудал"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Дөрвөлжин идеограф хориг"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Дөрвөлжин идеограф орон тоо"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Дөрвөлжин идеограф зөвшөөрөл"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Дөрвөлжин идеограф бүрэн эзэлсэн"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Дөрвөлжин идеограф төлсөн"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Дөрвөлжин идеограф сараар"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Дөрвөлжин идеограф аппликешн"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Дөрвөлжин идеограф хөнгөлөлт"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Дөрвөлжин идеограф бизнесийн"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Дугуй идеограф давуу тал"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Дугуй идеограф зөвшөөрөх"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Циклон"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Будантай"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Хаасан шүхэр"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Одтой шөнө"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Уулын дээр нар мандах"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Нар мандах"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Үдшийн хот"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Барилга дээр нар жаргах"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Солонго"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Шөнийн гүүр"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Усны давалгаа"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Галт уул"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Сүүн зам"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Дэлхий бөмбөрцөг Европ Африк"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Дэлхий бөмбөрцөг Америк"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Дэлхий бөмбөрцөг Ази-Австрали"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Меридантай бөмбөрцөг"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Шинэ сарны симбол"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Мандах хавирган сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"Эхний улирлын сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Мандах бөгтөр сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Бүтэн сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Жаргах бөгтөр сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Сүүлийн улирлын сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Жаргах хавирган сарны тэмдэг"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Хавирган сар"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Нүүртэй шинэ сар"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Нүүртэй эхний улирлын сар"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Нүүртэй сүүлийн улирлын сар"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Нүүртэй бүтэн сар"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Нүүртэй нар"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Гялалзах од"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Сүүлт од"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Туулайн бөөр"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Суулгац"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Мөнх ногоон мод"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Навчит мод"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Далдуу мод"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Кактус"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Алтанзул"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Интоорын дэлбээ"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Сарнай"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Хибискус"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Наранцэцэг"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Дэлбээ"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Эрдэнэ шишийн түрүү"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Цагаан будааны түрүү"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Ургамал"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Дөрвөн навчит хошоонгор"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Агч модны навч"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Унасан навч"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Сэрчигнэх навч"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Мөөг"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Улаан лооль"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Чэс"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Усан үзэм"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Амтат гуа"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Тарвас"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Мандарин"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Лемон"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Банана"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Хан боргоцой"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Улаан алим"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Ногоон алим"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Лийр"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Тоор"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Интоор"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Гүзээлзгэнэ"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Гамбургер"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Пиццаны зүсэм"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Ястай мах"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Тахианы хөл"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Будааны жигнэмэг"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Будааны бөмбөлөг"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Болгосон будаа"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Кари болон будаа"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Ууран аяга"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Шпагетти"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Талх"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Шарсан төмс"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Шарсан чихэрлэг төмс"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Данго"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oден"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Суши"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Шарсан сам хорхой"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Мушгай загасан бялуу"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Зөөлөн зайрмаг"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Хуссан мөс"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Зайрмаг"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Донат"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Печень"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Шоколад"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Чихэр"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Иштэй чихэр"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Шар тос"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Зөгийн бал"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Үелсэн бялуу"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Хоолны сав"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Хоолны тогоо"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Хоол хийх"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Хутга сэрээ"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Бариулгүй цайны аяг"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Сакены лонх болон хундага"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Виноны хундага"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Коктэйлийн хундага"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Халуун орны ундаа"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Пивоны аяга"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Жингэнэсэн пивоны аяга"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Хүүхдийн лонх"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Тууз"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Боодолтой бэлэг"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Төрсөн өдрийн бялуу"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Жак-O-дэнлүү"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Зул сарын гацуур"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Эцэг Христийн баяр"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Галын наадам"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Бенгалийн гал"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Шаар"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Үдэшлэгийн салют"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Чихрэн бөмбөлөг"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Taнабата мод"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Солисон тугнууд"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Нарс модон чимэглэл"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Япон хүүхэлдэй"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Мөрөг загас стример"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Салхины ая"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Сар харах ёслол"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Сургуулийн үүргэвч"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Төгсөгчийн малгай"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Тойруулгын модон морь"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Чөтгөрийн дугуй"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Галзуу хулгана"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Загасны уураг болон загас"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Микрофон"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Кино зургийн аппарат"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Кино"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Чихэвч"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Зураачийн палет"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Бортого малгай"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Циркийн майхан"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Тасалбар"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Кадрын самбар"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Урлагийн тоглолт"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Видео тоглоом"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Шууд хит"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Слот машин"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Билльярд"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Тоглоомын үхэл"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Боулинг"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Хөзрийн цэцэг"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Хөгжмийн нот"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Олон хөгжмийн нот"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Саксофон"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Гитар"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Хөгжмийн даруул"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Бүрээ"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Хийл"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Хөгжмийн оноо"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Гүйдэг цамц, хүрээ"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Теннисны ракет болон бөмбөг"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Цана болон цанын гутал"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Сагсан бөмбөг болон цагираг"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Шоотой туг"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Сноубордчин"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Гүйгч"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Сөрфер"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Цом"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Морин уралдаан"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Америк хөл бөмбөг"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Регби хөл бөмбөг"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Сэлэгч"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Байшин"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Цэцэрлэгтэй байшин"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Оффисын барилга"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Японы шуудан"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Европын шуудан"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Эмнэлэг"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Банк"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Автомат теллер машин"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Зочид буудал"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Секс буудал"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Ая тухтай дэлгүүр"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Сургууль"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Их дэлгүүр"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Үйлдвэр"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Izakaya дэнлүү"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Японы цайз"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Европын цайз"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Харх"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Хулгана"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Шар"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Усны одос"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Үнээ"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Ирвэс"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Молтогчин"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Муур"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Луу"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Матар"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Халим"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Эмгэн хумс"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Могой"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Морь"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Хуц"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Ямаа"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Хонь"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Сармагчин"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Азарган тахиа"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Тахиа"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Нохой"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Гахай"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Зэрлэг гахай"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Заан"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Наймаалж"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Мушгиа дун"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Цох"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Шоргоолж"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Зөгий"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Алтан тэмээ"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Загас"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Халуун орны загас"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Нохой загас"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Яст мэлхий"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Ангаахай"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Дэгдээхий"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Урдаас харсан дэгдээхэй"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Шувуу"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Пенгвин"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Коала"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Пүүдл"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Нэг бөхт тэмээ"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Хоёр бөхт тэмээ"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Делфин"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Хулганы нүүр"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Үнээний нүүр"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Барын нүүр"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Молтогчны нүүр"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Муурны нүүр"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Лууны нүүр"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Ус оргилуулах халим"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Морины нүүр"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Сармагчны нүүр"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"Нохойны нүүр"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Гахайн нүүр"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Мэлхийн нүүр"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Хамстерийн нүүр"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Чонын нүүр"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Баавгайн нүүр"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Пандагийн нүүр"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Гахайн хамар"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Саврын мөр"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Нүд"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Чих"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Хамар"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Ам"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Хэл"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Цагаан дээр дээш заасан долоовор"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Цагаан дээр доош заасан долоовор"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Цагаан дээр зүүн заасан долоовор"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Цагаан дээр баруун заасан долоовор"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Зангидсан гарын тэмдэг"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Даллах гарын тэмдэг"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"Ok гарын тэмдэг"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Эрхий дээш тэмдэг"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Эрхий доош тэмдэг"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Алга ташсан тэмдэг"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Нээлттэй гарын тэмдэг"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Титэм"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Эмэгтэй малгай"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Нүдний шил"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Зангиа"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"Футболк"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Жинс"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Даашинз"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Кимоно"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Бикини"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Эмэгтэй хувцас"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Цүнх"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Гар цүнх"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Даалин"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Эрэгтэй гутал"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Биеийн тамирын гутал"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Өндөр өсгийт"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Эмэгтэй сандаал"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Эмэгтэй түрийтэй гутал"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Хөлийн мөр"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Сүүдрэн хүн"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Сүүдрэн хүмүүс"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Хөвгүүн"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Охин"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Эр хүн"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Эм хүн"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Гэр бүл"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Гар хөтлөлцсөн эр, эм"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Гар хөтлөлцсөн хоёр эр"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Гар хөтлөлцсөн хоёр эм"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Цагдаа"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Бөжин ээмэгтэй эмэгтэй"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Хуримын нөмрөгтэй бүсгүй"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Шаргал үст"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Тоорцогтой эр"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Турбантай эр"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Настай эр"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Настай эм"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Хүүхэд"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Барилгын ажилчин"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Гүнж"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Японы мангас"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Японы чөтгөр"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Сүнс"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Хүүхдийн элч тэнгэр"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Харь гаригийн хүн"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Харь гаригийн мангас"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Бяцхан чөтгөр"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Гавал"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Мэдээллийн ажилтан"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Харуул"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Бүжигчин"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Уруулын будаг"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Хумсны будаг"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Нүүрний массаж"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Үс засалт"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Үсчний реклам"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Тариур"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Эм"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Үнсэлтийн мөр"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Хайрын захиа"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Бөгж"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Эрдэнийн чулуу"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Үнсэлт"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Цэцгийн баглаа"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Зүрхтэй хосууд"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Хурим"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Цохилох зүрх"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Урагдсан зүрх"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Хоёр зүрх"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Оргилуун зүрх"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Томрох зүрх"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Сумтай зүрх"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Цэнхэр зүрх"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Ногоон зүрх"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Шар зүрх"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Нил ягаан өнгийн зүрх"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Туузтай зүрх"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Эргэлдэх зүрх"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Зүрхний чимэглэл"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Цэгтэй даймонд"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Цахилгаан чийдэнгийн шил"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Уурлах тэмдэг"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Бөмбөг"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Унтах тэмдэг"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Мөргөлдөх тэмдэг"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Цацрах хөлсний тэмдэг"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Дусал"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Налуу тэмдэг"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Овоолсон баас"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Булчинтай гар"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Нойрмог тэмдэг"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Үг хэлэх бөмбөлөг"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Бодлын бөмбөг"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Цагаан цэцэг"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Зуун оноо тэмдэг"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Мөнгөний уут"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Валютын арилжаа"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Хүнд долларын тэмдэг"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Кредит карт"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Иен тэмдэгтэй дэвсгэрт"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Долларын тэмдэгт"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Евро тэмдэгтэй дэвсгэрт"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Фунт тэмдэгтэй дэвсгэрт"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Далавчтай мөнгө"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Иен тэмдэгтэй дээш чиглэсэн граф"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Суудал"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Хувийн компьютер"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Чемодан"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Минидиск"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Уян диск"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Оптик диск"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"Dvd"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Файлын хавтас"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Нээлттэй файлын хавтас"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Хуйларсан хуудас"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Дээшээ харсан хуудас"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Календарь"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Урагдсан календарь"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Картын индекс"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Дээш чиглэсэн граф"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Доош чиглэсэн граф"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Хөндөл граф"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Түр санах ой"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Цаас хатгагч"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Цаас хатгагч"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Цаасны клип"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Шулуун шугам"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Гурвалжин шугам"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Хавчуургын таб"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Булшны чулуу"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Тэмдэглэлийн дэвтэр"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Гоёлтой тэмдэглэлийн дэвтэр"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Хаалттай ном"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Нээлттэй ном"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Ногоон ном"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Цэнхэр ном"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Улбар шар өнгийн хавтастай ном"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Ном"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Нэрний тэмдэг"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Гүйлгэх"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Мемо"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Утас хүлээн авагч"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Пэйжер"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Факс машин"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Хиймэл дагуулын антенн"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Нийтэд зарлах чанга яригч"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Хөгжөөн дэмжлэгийн мегафон"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Явсан бичгийн тавиур"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Ирсэн бичгийн тавиур"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Багц"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"И-мэйл тэмдэг"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Ирж буй дугтуй"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Доош сумтай дугтуй"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Доошлуулсан тугтай шуудангийн хайрцаг"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Босгосон тугтай хаагдсан шуудангийн хайрцаг"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Босгосон тугтай нээлттэй шуудангийн хайрцаг"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Доошлуулсан тугтай нээлттэй шуудангийн хайрцаг"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Шуудангийн хайрцаг"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Шуудангийн бүрээ"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Сонин"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Гар утас"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Зүүн талдаа баруун заасан сумтай гар утас"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Чичирхийллийн горим"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Гар утас унтраах"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Гар утас болохгүй"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Хөндөлтэй антенн"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Камер"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Видео камер"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Телевиз"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Радио"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Видео кассет"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Мушгирсан баруун сум"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Зөв баруун, зүүн эргэсэн дугуй сум"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"зөв баруун, зүүн эргэсэн дугуй сум"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Зөв доош, дээш эргэсэн дугуй сум"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Буруу доош, дээш эргэсэн дугуй сум"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Бага гэрэлтүүлэгтэй тэмдэг"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Их гэрэлтүүлэгтэй тэмдэг"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Дарсан зураастай чанга яригч"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Чанга яригч"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Нэг дууны долгиотой чанга яригч"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Гурван дууны долгиотой чанга яригч"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Батерей"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Цахилгаан залгуур"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Зүүн-заасан томруулагч шил"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Баруун-заасан томруулагч шил"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Бэхэн үзэгтэй түгжээ"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Түлхүүртэй цоожлогдсон цоож"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Түлхүүр"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Түгжих"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Нээлттэй цоож"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Хонх"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Дарсан зураастай хонх"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Хавчуурга"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Холбоосын тэмдэг"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Радио товч"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Дээрээ сумтай буцах тэмдэг"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"Дээрээ сумтай төгсгөл"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"Дээрээ зүүн сумтай анхаарлын тэмдэг"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Дээрээ баруун сумтай удахгүй"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Дээрээ дээш сумтай дээр"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"Арван наймаас бага хүн байхгүй тэмдэг"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Аравтын товчлуур"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Латин том үсэгтэй оруулах симбол"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Латин жижиг үсэгтэй оруулах симбол"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Тоо оруулах тэмдэг"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Символ оруулах тэмдэг"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Латин үсэгтэй оруулах тэмдэг"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Гал"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Цахилгаан бамбар"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Түлхүүр"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Алх"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Эрэг, боолт"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Хутга"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Гар буу"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Микроскоф"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Телескоф"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Кристал бөмбөг"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Цэгтэй зургаан хошуут"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Эхлэн сурагчийн Япон тэмдэг"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Сэрээний эмблем"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Хар дөрвөлжин товч"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Цагаан дөрвөлжин товч"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Том улаан дугуй"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Том цэнхэр тойрог"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Том улбар шар даймонд"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Том цэнхэр даймонд"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Жижиг улбар шар даймонд"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Жижиг цэнхэр даймонд"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Дээш заасан улаан гурвалжин"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Доош заасан улаан гурвалжин"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Дээш заасан жижиг улаан гурвалжин"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Доош заасан жижиг улаан гурвалжин"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Цаг нэг цагийг заасан"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Цаг хоёр цагийг заасан"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Цаг гурван цагийг заасан"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Цаг дөрвөн цагийг заасан"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Цаг таван цагийг заасан"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Цаг зургаан цагийг заасан"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Цаг долоон цагийг заасан"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Цаг найман цагийг заасан"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Цаг есөн цагийг заасан"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Цаг арван цагийг заасан"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Цаг арван нэгийг заасан"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Цаг арван хоёрыг заасан"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Цаг нэг гучийг заасан"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Цаг хоёр гучийг заасан"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Цаг гурав гучийг заасан"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Цаг дөрөв гучийг заасан"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Цаг тав гучийг заасан"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Цаг зургаа гучийг заасан"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Цаг долоо гучийг заасан"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Цаг найм гучийг заасан"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Цаг ес гучийг заасан"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Цаг арав гучийг заасан"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Цаг арван нэг гучийг заасан"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Цаг арван хоёр гучийг заасан"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Фүжи уул"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Токио цамхаг"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Эрх чөлөөний хөшөө"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Японы сүүдэр"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Мояай"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Жуумалзсан царай"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Инээсэн нүдтэй жуумалзсан царай"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Баярын нулимстай царай"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Амаа ангайж инээмсэглэсэн царай"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Амаа ангайж инээсэн нүдтэй царай"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Амаа ангайж хүйтэн хөлстэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Амаа ангайж онийсон нүдтэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Хүрээтэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Эвэртэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Ирмэсэн царай"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Инээсэн нүдтэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Амттай хоол тамшаалсан царай"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Тайвширсан царай"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Зүрхэн нүдтэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Нарны шилтэй инээсэн царай"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Мишээсэн царай"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Төв царай"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Хувиралгүй царай"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Гайхашраагүй царай"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Хүйтэн хөлстэй царай"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Бодлогоширсон царай"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Гайхсан царай"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Сандарсан царай"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Үнсэлттэй царай"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Үнсэлт илгээх царай"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Инээсэн нүдтэй үнсэлт илгээх царай"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Аньсан нүдтэй үнсэлт илгээх царай"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Хэлээ цухуйлгасан царай"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Нүдээ ирмэж хэлээ цухуйлгасан царай"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Онийсон нүдтэй хэлээ цухуйлгасан царай"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Сэтгэл дундуур царай"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Санаа нь зовсон царай"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Ууртай царай"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Дорвогор царай"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Уйлсан царай"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Тэвчсэн царай"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Ялгуусан царай"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Сэтгэл дундуур ч тайван царай"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Амаа ангайж барайсан царай"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Шаналсан царай"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Айсан царай"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Ядарсан царай"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Нойрмог царай"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Ядарсан царай"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Ярвайсан царай"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Чанга уйлсан царай"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Амаа ангайсан царай"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Чимээгүй гэсэн царай"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Амаа ангайсан хүйтэн хөлстэй царай"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Айж хашгирсан царай"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Гайхширсан царай"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Уурссан царай"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Унтсан царай"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Дуниартсан царай"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Амгүй царай"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Эмнэлгийн масктай царай"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Инээсэн нүдтэй жуумалзсан муурын царай"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Баярын нулимстай муурын царай"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Амаа ангайж инээмсэглэсэн муурын царай"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Зүрхэн нүдтэй инээсэн муурын царай"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Муруй инээсэн муурын царай"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Аньсан нүдтэй үнсэлт илгээх муурын царай"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Дорвогор муурын царай"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Уйлсан муурын царай"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Ядарсан муурын царай"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Муу гэсэн зангаатай царай"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Сайн гэсэн зангаатай царай"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Мэхийн ёсолсон хүн"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Мууг харахгүй сармагчин"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Мууг сонсохгүй сармагчин"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Мууг ярихгүй сармагчин"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Нэг гараа өргөсөн жаргалтай хүн"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Баярлаж гараа өргөсөн хүн"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Барайсан хүн"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Дорвогор царайтай хүн"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Цээжээ тэвэрсэн хүн"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Пуужин"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Нисдэг тэрэг"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Уур зүтгүүр"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Төмөр замын вагон"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Хурдан галт тэрэг"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Суман хурдан галт тэрэг"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Галт тэрэг"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Метро"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Хөнгөн төмөр зам"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Буудал"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Трамвай"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Трамвай вагон"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Автобус"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Ирж буй автобус"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Тролейбус"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Автобусны зогсоол"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Минибус"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Түргэн тусламж"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Галын машин"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Цагдаагийн машин"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Ирж буй цагдаагийн машин"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Такси"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Ирж буй такси"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Автомашин"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Ирж автомашин"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Амралтын машин"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Хүргэлтийн ачааны машин"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Цуваа тэргэнцэр"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Трактор"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Moнорейл"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Уулын төмөр зам"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Дүүжин төмөр зам"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Уулын кабль зам"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Агаарын трамвай"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Усан онгоц"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Роу завь"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Хурдны завь"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Хэвтээ замын дохио"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Босоо замын дохио"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Барилгын тэмдэг"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Цагдаагийн машины эргэлдэх дохио"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Шуудан гурвалжин туг"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Хаалга"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Орохыг хориглосон тэмдэг"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Тамхи татах тэмдэг"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Тамхи хориглосон тэмдэг"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Хогийг саванд нь хаях тэмдэг"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Хог хаяхгүй тэмдэг"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Ундны усны тэмдэг"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Ундны бус усны тэмдэг"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Дугуй"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Унадаг дугуй болохгүй"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Унадаг дугуйч"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Уулын унадаг дугуйч"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Явган зорчигч"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Явган зорчигч болохгүй"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Хүүхдийн гарц"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Эрэгтэйчүүдийн тэмдэг"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Эмэгтэйчүүдийн тэмдэг"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Ариун цэврийн өрөө"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Хүүхдийн тэмдэг"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Бие засах газар"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"Усны сав"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Шүршүүр"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Ванн"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Ванн"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Паспорт хяналт"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Гааль"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Ачаа авах"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Орхисон ачаа"</string>
+</resources>
diff --git a/java/res/values-mn-rMN/strings-talkback-descriptions.xml b/java/res/values-mn-rMN/strings-talkback-descriptions.xml
index 7eb316775..1c1e6e7f3 100644
--- a/java/res/values-mn-rMN/strings-talkback-descriptions.xml
+++ b/java/res/values-mn-rMN/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Текст оруулаагүй"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> нь <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>-г <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> руу залруулна"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> авто-залруулалт хийдэг"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Товчийн код %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Шифт"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Сэлгэхийг идэвхжүүлсэн (товшиж идэвхгүйжүүлнэ үү)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Томоор бичихийг асаасан (товшиж идэвхгүйжүүлнэ үү)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Өөр тэмдэгтүүд"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Шифт"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Симбол"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Шифт"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Устгах"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Симбол"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Үсэгнүүд"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Өмнөх"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Сэлгэхийг идэвхжүүлсэн"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Томоор бичихийг идэвхжүүлсэн"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Сэлгэхийг идэвхжүүлээгүй"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Симбол төлөв"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Өөр тэмдэгтийн горим"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Үсэгнүүд төлөв"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Утасны төлөв"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Утасны символ төлөв"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Газар"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Симбол"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Эмотикон"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-mn-rMN/strings.xml b/java/res/values-mn-rMN/strings.xml
index 4c64b3354..67886e3bd 100644
--- a/java/res/values-mn-rMN/strings.xml
+++ b/java/res/values-mn-rMN/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Оруулах сонголтууд"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Судалгааны протоколын командууд"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Харилцагчийн нэр хайх"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Алдаа шалгагч нь таны харилцагчдын жагсаалтаас ашиглана"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Товч дарахад чичрэх"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Харилцагчдын нэрс санал болгох"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Санал болгох, залруулахда Харилцагчдын нэрсээс ашиглах"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Хувийн тохиргоотой зөвлөмжүүд"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Давхар зайтай цэг"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Ардаа зайтай цэг оруулахын тулд Зай авах дээр давхар товшино уу"</string>
<string name="auto_cap" msgid="1719746674854628252">"Автоматаар томруулах"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Оруулах хэл"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Хадгалахын тулд дахин хүрнэ үү"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Толь бичиг байна"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Хэрэглэгчийн санал хүсэлтийг идэвхжүүлэх"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Ашиглалтын статистик болон гацалтын репортуудыг автоматаар илгээснээр энэ оруулах арга засагчийг сайжруулахад туслаарай"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Гарын загвар"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Англи (ИБ)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Англи (АНУ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Идэвхжүүлэх"</string>
<string name="not_now" msgid="6172462888202790482">"Одоо биш"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Ижилхэн оруулах загвар байна: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Ашиглалтын судалгааны горим"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Товч удаан дарах хугацааны тохиргоо"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Товч дарах чичиргээний хугацаа"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Товчны дууны хэмжээ"</string>
diff --git a/java/res/values-ms-rMY/strings-action-keys.xml b/java/res/values-ms-rMY/strings-action-keys.xml
index f1a75d2ef..1910c0dc3 100644
--- a/java/res/values-ms-rMY/strings-action-keys.xml
+++ b/java/res/values-ms-rMY/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Sblm"</string>
<string name="label_done_key" msgid="7564866296502630852">"Siap"</string>
<string name="label_send_key" msgid="482252074224462163">"Hntr"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Jeda"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Tggu"</string>
</resources>
diff --git a/java/res/values-ms-rMY/strings-emoji-descriptions.xml b/java/res/values-ms-rMY/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..1595a99a7
--- /dev/null
+++ b/java/res/values-ms-rMY/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Tanda hak cipta"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Tanda berdaftar"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Tanda seruan berkembar"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Tanda tanya seruan"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Tanda cap dagangan"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Sumber maklumat"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Anak panah kiri kanan"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Anak panah atas bawah"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Anak panah barat laut"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Anak panah timur laut"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Anak panah tenggara"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Anak panah barat daya"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Anak panah hala kiri dengan cangkuk"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Anak panah hala kanan dengan cangkuk"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"Jam"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Jam pasir"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Segi tiga kembar arah kanan hitam"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Segi tiga kembar arah kiri hitam"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Segi tiga kembar arah atas hitam"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Segi tiga kembar arah bawah hitam"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Jam penggera"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Jam pasir dengan pasir mengalir"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Huruf m besar latin dalam bulatan"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Empat segi kecil hitam"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Empat segi kecil putih"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Segi tiga arah kanan hitam"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Segi tiga arah kiri hitam"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Empat segi sederhana putih"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Empat segi sederhana hitam"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Empat segi sederhana kecil putih"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Empat segi sederhana kecil hitam"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Matahari dengan sinar hitam"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Awan"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Telefon hitam"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Peti undi dengan tanda semak"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Payung dengan titisan hujan"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Minuman panas"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Indeks putih menunjuk ke atas"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Muka tersenyum putih"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Aries"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Taurus"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Gemini"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Cancer"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Leo"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Virgo"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Libra"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Scorpius"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Sagittarius"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Capricorn"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Aquarius"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Pisces"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Daun sped hitam"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Daun kelawar hitam"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Daun hati hitam"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Daun berlian hitam"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Air panas"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Simbol kitar semula universal hitam"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Simbol kerusi roda"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Sauh"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Tanda amaran"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Tanda voltan tinggi"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Bulatan putih sederhana"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Bulatan hitam sederhana"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Bola sepak"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Besbol"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Orang salji tanpa salji"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Matahari di sebalik awan"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Ophiuchus"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Dilarang masuk"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Gereja"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Air pancut"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Bendera dalam lubang"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Kapal layar"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Khemah"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Pam minyak"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Gunting hitam"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Tanda semak tebal putih"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Kapal terbang"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Sampul surat"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Penumbuk"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Tangan diangkat"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Tanda menang"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Pensel"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Mata pen hitam"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Tanda semak tebal"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"X darab tebal"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Kilauan"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Asterisk berbucu lapan"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Bintang hitam berbucu lapan"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Emping salji"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Kilauan"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Tanda silang"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Tanda silang empat segi negatif"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Perhiasan tanda tanya hitam"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Perhiasan tanda tanya putih"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Perhiasan tanda seruan putih"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Simbol tanda seruan tebal"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Hati hitam tebal"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Tanda tambah tebal"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Tanda tolak tebal"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Tanda bahagi tebal"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Anak panah hala kanan hitam"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Gelung bergulung"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Gelung bergulung kembar"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Anak panah menghala ke kanan kemudian melengkung ke atas"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Anak panah menghala ke kanan kemudian melengkung ke bawah"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Anak panah hitam hala kiri"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Anak panah hitam hala atas"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Anak panah hitam hala bawah"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Empat segi besar hitam"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Empat segi besar putih"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Bintang sederhana putih"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Bulatan besar tebal"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Sengkang beralun"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Tanda perselangan silih"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Ideograf tahniah bulat"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Ideograf rahsia bulat"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Naga merah jubin mahjong"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Joker hitam daun terup"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Jenis darah A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Jenis darah B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Jenis darah O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Tempat letak kereta"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Jenis darah AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"CL empat segi"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"Tenang empat segi"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"Percuma empat segi"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"ID empat segi"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"Baharu empat segi"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"NG empat segi"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"OK empat segi"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"SOS empat segi"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"Naik dengan tanda seruan empat segi"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"Lawan empat segi"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Katakana di sini empat segi"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Perkhidmatan katakana empat segi"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Ideograf percuma empat segi"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Ideograf tempat duduk yang ditempah empat segi"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Ideograf larangan empat segi"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Ideograf jawatan kosong empat segi"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Ideograf penerimaan empat segi"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Ideograf penuh empat segi"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Ideograf dibayar empat segi"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Ideograf bulanan empat segi"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Ideograf permohonan empat segi"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Ideograf diskaun empat segi"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Ideograf perniagaan dibuka empat segi"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Ideograf kelebihan bulat"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Ideograf terima bulat"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Puting beliung"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Berkabut"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Payung tertutup"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Malam dengan bintang"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Matahari terbit di atas gunung"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Sunrise"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Skap bandar raya waktu senja"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Matahari terbenam di atas bangunan"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Pelangi"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Jambatan pada waktu malam"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Gelombang air"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Gunung Berapi"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Bima sakti"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Glob bumi eropah-afrika"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Glob bumi amerika"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Glob bumi asia-australia"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Glob dengan meridian"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Simbol bulan baharu"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Simbol bulan sabit mengambang"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"Simbol bulan suku pertama"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Simbol bulan hampir purnama mengambang"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Simbol bulan purnama"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Simbol bulan hampir purnama surut"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Simbol bulan suku akhir"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Simbol bulan sabit surut"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Bulan sabit"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Bulan baharu dengan muka"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Bulan suku pertama dengan muka"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Bulan suku akhir dengan muka"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Bulan purnama dengan muka"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Matahari dengan muka"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Bintang bersinar"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Tahi bintang"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Buah berangan"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Anak benih"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Pokok malar hijau"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Pokok daun luruh"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Pokok palma"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Kaktus"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Tulip"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Bunga sakura"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Ros"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Bunga raya"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Bunga matahari"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Bunga"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Tongkol jagung"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Pokok padi"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Herba"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Empat daun semanggi"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Daun mapel"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Daun gugur"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Daun ditiup angin"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Cendawan"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Tomato"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Terung"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Anggur"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Tembikai"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Tembikai"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Oren Tangerin"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Lemon"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Kuning Pisang"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Nanas"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Epal merah"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Epal hijau"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Pear"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Pic"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Ceri"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Strawberi"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Hamburger"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Sepotong piza"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Daging pada tulang"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Kaki ayam"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Keropok beras"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Bebola beras"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Nasi"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Kari dan nasi"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Mangkuk mengukus"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Spageti"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Roti"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Kentang goreng"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Ubi keledek panggang"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Dango"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oden"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Sushi"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Udang goreng"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Kek ikan dengan corak pusaran"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Aiskrim lembut"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Ais kisar"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Aiskrim"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Donat"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Biskut"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Bar coklat"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Kandi"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Lolipop"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Kastad"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Bekas madu"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Kek rapuh"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Kotak Bento"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Seperiuk makanan"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Masakan"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Garpu dan pisau"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Cawan tanpa pemegang"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Botol Sake dan cawan"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Gelas wain"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Gelas koktel"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Minuman tropika"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Kole bir"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Kole bir dihantukkan"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Botol bayi"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Reben"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Hadiah berbalut"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Kek hari lahir"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Jack-o-lantern"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Pokok Krismas"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Santa Klaus"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Bunga api"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Bunga api berlian"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Belon"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Peletus konfeti"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Bola Konfeti"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Pokok Tanabata"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Bendera berpalang"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Hiasan pain"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Anak patung Jepun"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Ular-ular kap"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Loceng angin"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Majlis melihat bulan"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Beg galas sekolah"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Topi graduasi"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Kuda karusel"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Roda Ferris"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Roller-coaster"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Joran dan ikan"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Mikrofon"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Kamera filem"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Pawagam"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Fon kepala"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Palet Artis"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Topi"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Khemas sarkas"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Tiket"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Papan ketap"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Seni persembahan"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Permainan video"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Tepat pada sasaran"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Mesin slot"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Biliard"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Dadu"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Boling"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Daun terup bunga"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Nota muzik"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Pelbagai nota muzik"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Saksofon"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Gitar"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Papan nada muzik"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Trompet"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Biola"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Skor muzik"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Baju berlari dengan selempang"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Raket dan bola tenis"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Ski dan but ski"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Bola keranjang dan gelung"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Bendera kotak-kotak"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Peluncur salji"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Pelari"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Peluncur"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Trofi"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Lumba kuda"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Bola sepak Amerika"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Bola sepak ragbi"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Perenang"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Bangunan rumah"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Rumah dengan taman"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Bangunan pejabat"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Pejabat pos Jepun"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Pejabat pos Eropah"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Hospital"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Bank"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Mesin teler automatik"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Hotel"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Hotel cinta"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Kedai serbaneka"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Sekolah"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Gedung beli-belah"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Kilang"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Tanglung izakaya"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Istana Jepun"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Istana Eropah"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Tikus"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Tikus"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Lembu jantan"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Kerbau"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Lembu"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Harimau Bintang"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Arnab"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Kucing"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Naga"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Buaya"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Ikan paus"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Siput"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Ular"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Kuda"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Biri-biri jantan"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Kambing"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Biri-biri"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Monyet"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Ayam jantan"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Ayam"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Anjing"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Babi"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Babi hutan"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Gajah"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Kurita"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Cengkerang berpusar"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Pepijat"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Semut"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Lebah madu"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Kumbang kura-kura"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Ikan"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Ikan tropika"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Ikan buntal"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Penyu"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Anak ayam menetas"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Anak ayam"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Anak ayam menghadap depan"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Burung"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Penguin"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Koala"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Poodle"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Unta dromedaris"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Unta Bactrian"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Dolfin"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Muka tikus"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Muka lembu"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Muka harimau"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Muka arnab"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Muka kucing"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Muka naga"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Ikan paut memancutkan air"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Muka kuda"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Muka monyet"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"Muka anjing"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Muka babi"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Muka katak"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Muka hamster"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Muka serigala"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Muka beruang"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Muka panda"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Hidung babi"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Kesan tapak"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Mata"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Telinga"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Hidung"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Mulut"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Lidah"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Tangan putih menunjuk ke atas"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Tangan putih menunjuk ke bawah"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Tangan putih menunjuk ke kiri"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Tangan putih menunjuk ke kanan"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Isyarat enumbuk"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Isyarat tangan melambai"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"Isyarat ok"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Isyarat bagus"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Isyarat tidak bagus"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Isyarat bertepuk tangan"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Isyarat tangan terbuka"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Mahkota"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Topi wanita"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Cermin mata"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Tali leher"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"Kemeja T"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Jean"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Gaun"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Kimono"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Bikini"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Pakaian wanita"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Beg duit"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Beg tangan"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Dompet"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Kasut lelaki"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Kasut sukan"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Kasut tumit tinggi"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Sandal wanita"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"But wanita"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Tapak kaki"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Bayang patung"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Bayang patung"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Budak lelaki"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Budak perempuan"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Lelaki"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Wanita"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Keluarga"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Lelaki dan wanita berpegangan tangan"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Dua lelaki berpegangan tangan"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Dua wanita berpegangan tangan"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Pegawai polis"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Wanita dengan telinga arnab"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Pengantin dengan vel"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Orang berambut perang"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Lelaki dengan gua pi mao"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Lelaki berserban"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Lelaki lebih tua"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Wanita lebih tua"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Bayi"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Buruh binaan"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Puteri"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Gergasi Jepun"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Jembalang Jepun"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Bebayang"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Malaikat kecil"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Makhluk asing"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Raksasa asing"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Imp"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Tengkorak"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Orang meja maklumat"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Pengawal"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Penari"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Gincu"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Pengilat kuku"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Urutan muka"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Gunting rambut"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Jalur Tukang Gunting Rambut"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Picagari"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Pil"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Tanda ciuman"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Surat cinta"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Cincin"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Batu permata"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Ciuman"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Jambak bunga"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Pasangan dengan hati"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Perkahwinan"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Jantung berdegup"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Patah hati"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Dua hati"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Hati berkilauan"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Hati berkembang"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Hati dengan anak panah"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Hati biru"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Hati hijau"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Hati kuning"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Hati ungu"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Hati dengan riben"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Hati berputar"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Hiasan hati"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Bentuk berlian dengan titik di dalam"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Mentol elektrik"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Simbol kemarahan"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Bom"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Simbol tidur"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Simbol pelanggaran"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Simbol peluh memercik"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Titik kecil"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Simbol sengkang"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Timbunan najis"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Biseps dilenturtegang"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Simbol pening"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Belon pertuturan"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Belon pemikiran"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Bunga putih"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Simbol seratus mata"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Beg wang"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Pertukaran mata wang"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Isyarat dolar tebal"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Kad kredit"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Wang kertas dengan tanda yen"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Wang kertas dengan tanda dolar"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Wang kertas dengan tanda euro"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Wang kertas dengan tanda pound"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Wang dengan sayap"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Carta dengan aliran ke atas dan tanda yen"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Tempat duduk"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Komputer peribadi"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Beg bimbit"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Minicakera"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Cakera liut"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Cakera optik"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"Dvd"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Folder fail"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Buka folder fail"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Halaman bergulung"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Halaman menghadap ke atas"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Kalendar"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Kalendar koyak"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Kad indeks"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Carta dengan aliran ke atas"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Carta dengan aliran ke bawah"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Carta bar"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Papan Keratan"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Pin tekan"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Pin tekan bulat"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Klip kertas"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Pembaris lurus"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Pembaris segi tiga"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Tab penanda halaman"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Lejar"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Buku Nota"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Buku nota dengan kulit bercorak"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Buku tertutup"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Buku terbuka"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Buku hijau"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Buku biru"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Buku jingga"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Buku"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Lencana nama"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Skrol"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Memo"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Gagang telefon"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Alat kelui"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Mesin faks"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Antena satelit"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Pembesar suara pengumuman awam"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Megafon sorakan"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Dulang peti keluar"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Dulang peti masuk"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Pakej"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"Simbol e-mel"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Sampul surat masuk"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Sampul surat dengan anak panah ke bawah di atas"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Peti mel tertutup dengan bendera diturunkan"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Peti mel tertutup dengan bendera dinaikkan"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Peti mel terbuka dengan bendera dinaikkan"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Peti mel terbuka dengan bendera diturunkan"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Peti surat"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Hon pos"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Surat khabar"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Telefon mudah alih"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Telefon mudah alih dengan anak panah hala kanan di sebelah kiri"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Mod getaran"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Telefon mudah alih dimatikan"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Tiada telefon mudah alih"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Antena dengan bar"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Kamera"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Kamera video"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Televisyen"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Radio"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Kaset Video"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Anak panah hala kanan berpintal"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Anak panah bulatan terbuka hala kanan dan hala kiri mengikut arah jam"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Anak panah bulatan terbuka hala kanan dan hala kiri mengikut arah jam dengan tindihan satu dalam bulatan"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Anak panah bulatan terbuka menurun dan menaik mengikut arah jam"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Anak panah bulatan terbuka menurun dan menaik lawan arah jam"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Simbol cahaya rendah"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Simbol cahaya tinggi"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Pembesar suara dengan garisan pembatalan"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Pembesar suara"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Pembesar suara dengan satu gelombang bunyi"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Pembesar suara dengan tiga gelombang bunyi"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Bateri"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Palam elektrik"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Kanta pembesar menunjuk ke kiri"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Kata pembesar menunjuk ke kanan"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Mangga dengan pen dakwat"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Mangga tertutup dengan kunci"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Anak kunci"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Mangga"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Mangga terbuka"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Loceng"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Loceng dengan garisan pembatalan"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Penanda halaman"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Simbol pautan"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Butang radio"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"Kembali dengan anak panah hala kiri di atas"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"Akhir dengan anak panah hala kiri di atas"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"Hidup dengan tanda seruan dengan anak panah kiri kanan di atas"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"Tidak lama lagi dengan anak panah hala kiri di atas"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"Atas dengan anak panah hala atas di atas"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"Simbol tiada sesiapa di bawah umur 18 tahun"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Butang kekunci sepuluh"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Simbol input huruf besar latin"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Simbol input huruf kecil latin"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Simbol input nombor"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Simbol input untuk simbol"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Simbol input huruf latin"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Api"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Lampu suluh"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Sepana"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Tukul"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Nat dan bolt"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Hocho"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Pistol"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Mikroskop"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Teleskop"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Bola kristal"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Bintang berbucu enam dengan titik tengah"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Simbol Jepun untuk perantis"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Lambang trisula"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Butang empat segi hitam"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Butang empat segi putih"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Bulatan merah besar"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Bulatan biru besar"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Berlian oren besar"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Berlian biru besar"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Berlian oren kecil"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Berlian biru kecil"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Segi tiga merah menunjuk ke atas"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Segi tiga merah menunjuk ke bawah"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Segi tiga merah kecil menunjuk ke atas"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Segi tiga merah kecil menunjuk ke bawah"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Muka jam pukul satu"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Muka jam pukul dua"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Muka jam pukul tiga"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Muka jam pukul empat"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Muka jam pukul lima"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Muka jam pukul enam"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Muka jam pukul tujuh"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Muka jam pukul lapan"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Muka jam pukul sembilan"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Muka jam pukul sepuluh"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Muka jam pukul sebelas"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Muka jam pukul dua belas"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Muka jam pukul satu setengah"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Muka jam pukul dua setengah"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Muka jam pukul tiga setengah"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Muka jam pukul empat setengah"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Muka jam pukul lima setengah"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Muka jam pukul enam setengah"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Muka jam pukul tujuh setengah"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Muka jam pukul lapan setengah"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Muka jam pukul sembilan setengah"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Muka jam pukul sepuluh setengah"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Muka jam pukul sebelas setengah"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Muka jam pukul dua belas setengah"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Gunung fuji"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Menara Tokyo"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Patung Liberty"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Bebayang jepun"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Moyai"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Muka tersengih"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Muka tersengih dengan mata tersenyum"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Muka dengan air mata kegembiraan"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Muka tersenyum dengan mulut terbuka"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Muka tersenyum dengan mulut terbuka dan mata tersenyum"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Muka tersenyum dengan mulut terbuka dan peluh dingin"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Muka tersenyum dengan mulut terbuka dan mata terpejam rapat"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Muka tersenyum dengan halo"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Muka tersenyum dengan tanduk"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Muka mengenyit mata"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Muka tersenyum dengan mata tersenyum"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Muka menikmati makanan lazat"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Muka lega"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Muka tersenyum dengan mata berbentuk hati"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Muka tersenyum dengan cermin mata hitam"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Muka mencebik"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Muka neutral"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Muka tanpa perasaan"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Muka tidak hairan"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Muka dengan peluh dingin"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Muka termenung"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Muka keliru"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Muka bingung"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Muka bercium"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Muka melayangkan ciuman"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Muka bercium dengan mata tersenyum"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Muka bercium dengan mata tertutup"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Muka dengan lidah terjelir"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Muka dengan lidah terjelir dan mengenyitkan mata"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Muka dengan lidah terjelir dan mata tertutup rapat"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Muka kecewa"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Muka bimbang"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Muka marah"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Muka muncung"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Muka menangis"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Muka bersungguh-sungguh"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Muka dengan rupa kemenangan"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Muka kecewa tetapi lega"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Muka muram dengan mulut terbuka"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Muka sedih"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Muka takut"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Muka letih"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Muka mengantuk"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Muka penat"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Muka berkerut"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Muka menangis kuat"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Muka dengan mulut terbuka"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Muka diam"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Muka dengan mulut terbuka dan peluh dingin"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Muka menjerit ketakutan"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Muka terperanjat"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Muka merah"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Muka tidur"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Muka pening"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Muka tanpa mulut"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Muka dengan topeng perubatan"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Muka kucing tersengih dengan mata tersenyum"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Muka kucing dengan air mata kegembiraan"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Muka kucing tersenyum dengan mulut terbuka"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Muka kucing tersenyum dengan mata berbentuk hati"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Muka kucing dengan senyuman sinis"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Muka kucing bercium dengan mata tertutup"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Muka kucing muncung"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Muka kucing menangis"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Muka kucing letih"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Muka tanpa gerak isyarat baik"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Muka dengan gerak isyarat ok"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Orang menunduk lama"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Monyet menutup mata"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Monyet menutup telinga"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Monyet menutup mulut"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Orang gembira mengangkat satu tangan"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Orang mengangkat kedua-dua tangan untuk meraikan"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Orang muram"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Orang dengan muka muncung"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Orang dengan tangan bersilang"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Roket"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Helikopter"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Kepala kereta api wap"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Kereta api"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Kereta api kelajuan tinggi"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Kereta api kelajuan tinggi dengan muncung peluru"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Kereta api"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metro"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Aliran ringan"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Stesen"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Trem"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Kereta trem"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Bas"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Bas dari arah depan"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Bas elektrik"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Perhentian bas"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Bas mini"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulans"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Kereta bomba"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Kereta polis"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Kereta polis dari arah depan"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Teksi"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Teksi dari arah depan"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Kereta"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Kereta dari arah depan"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Kenderaan rekreasi"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Trak penghantaran"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Lori sambung sendi"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Traktor"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Monorel"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Kereta api gunung"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Kereta api tergantung"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Kereta kabel gunung"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Trem udara"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Kapal"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Perahu dayung"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Bot laju"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Lampu isyarat mendatar"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Lampu isyarat menegak"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Tanda pembinaan"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Lampu berputar kereta polis"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Bendera segi tiga pada tiang"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Pintu"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Isyarat dilarang masuk"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Simbol merokok"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Simbol dilarang merokok"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Simbol buang sampah di tempatnya"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Simbol jangan buang sampah"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Simbol air boleh diminum"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Simbol air tidak boleh diminum"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Basikal"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Tiada basikal"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Penunggang basikal"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Penunggang basikal gunung"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Pejalan kaki"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Tiada pejalan kaki"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Kanak-kanak melintas"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Simbol lelaki"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Simbol wanita"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Tandas"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Simbol bayi"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Tandas"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"Tandas"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Pancuran"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Bilik mandi"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Tab mandi"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Kawalan pasport"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Kastam"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Tuntutan bagasi"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Bagasi kiri"</string>
+</resources>
diff --git a/java/res/values-ms-rMY/strings-talkback-descriptions.xml b/java/res/values-ms-rMY/strings-talkback-descriptions.xml
index 29c5fd86a..d6a45033e 100644
--- a/java/res/values-ms-rMY/strings-talkback-descriptions.xml
+++ b/java/res/values-ms-rMY/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Tiada teks dimasukkan"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> membetulkan <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> menjadi <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> melakukan auto pembetulan"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Kod kunci %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Kunci anjak dihidupkan (ketik untuk melumpuhkan)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Kunci huruf besar dihidupkan (ketik untuk melumpuhkan)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Lagi simbol"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simbol"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Padam"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simbol"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Huruf"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Sebelumnya"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Kunci anjak didayakan"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Kunci huruf besar didayakan"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Kunci anjak dilumpuhkan"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Mod simbol"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Lagi mod simbol"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Mod huruf"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Mod telefon"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Mod simbol telefon"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Tempat"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simbol"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikon"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ms-rMY/strings.xml b/java/res/values-ms-rMY/strings.xml
index cea20217e..52165c55a 100644
--- a/java/res/values-ms-rMY/strings.xml
+++ b/java/res/values-ms-rMY/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Pilihan input"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Arahan Log Penyelidikan"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Cari nama kenalan"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Penyemak ejaan menggunakan entri dari senarai kenalan anda"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Getar pada tekanan kekunci"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Cadangkan nama Kenalan"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Menggunakan nama daripada Kenalan untuk cadangan dan pembetulan"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Cadangan diperibadikan"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Titik ruang berganda"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Mengetik 2X pada bar ruang memasukkan titik diikuti dengan ruang"</string>
<string name="auto_cap" msgid="1719746674854628252">"Autopenghurufbesaran"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Bahasa input"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Sentuh lagi untuk menyimpan"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Kamus tersedia"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Dayakan maklum balas pengguna"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Bantu memperbaik editor kaedah input ini dengan menghantar statistik penggunaan dan laporan ranap secara automatik"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema papan kekunci"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Bahasa Inggeris (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Bahasa Inggeris (Australia)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Dayakan"</string>
<string name="not_now" msgid="6172462888202790482">"Bukan sekarang"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Mod kajian kebolehgunaan"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Kelewatan tekan lama kekunci"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Tempoh getaran tekan kekunci"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Kelantangan bunyi tekan kekunci"</string>
diff --git a/java/res/values-nb/strings-action-keys.xml b/java/res/values-nb/strings-action-keys.xml
index d4acd36c9..af67b0073 100644
--- a/java/res/values-nb/strings-action-keys.xml
+++ b/java/res/values-nb/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Forrige"</string>
<string name="label_done_key" msgid="7564866296502630852">"Ferdig"</string>
<string name="label_send_key" msgid="482252074224462163">"Send"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Vent"</string>
</resources>
diff --git a/java/res/values-nb/strings-talkback-descriptions.xml b/java/res/values-nb/strings-talkback-descriptions.xml
index 96edf38c8..4870366d1 100644
--- a/java/res/values-nb/strings-talkback-descriptions.xml
+++ b/java/res/values-nb/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Ingen tekst er skrevet inn"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> retter <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> til <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> utfører automatisk retting"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Tastaturkode %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift er på (trykk for å deaktivere)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock er på (trykk for å deaktivere)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Flere symboler"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboler"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Slett"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboler"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Bokstaver"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Forrige"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift er aktivert"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock er aktivert"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift er deaktivert"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbolmodus"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modus for flere symboler"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Bokstavmodus"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Ringemodus"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Ringemodus med symboler"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Steder"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboler"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Smilefjes"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-nb/strings.xml b/java/res/values-nb/strings.xml
index e4f16032c..339361cc4 100644
--- a/java/res/values-nb/strings.xml
+++ b/java/res/values-nb/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Inndataalternativer"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Kommandoer for undersøkelseslogging"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Slå opp kontaktnavn"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Stavekontrollen bruker oppføringer fra kontaktlisten din"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrer ved tastetrykk"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Foreslå kontaktnavn"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Bruk navn fra Kontakter til forslag og korrigeringer"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Spesialtilpassede forslag"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Punktum ved doble mellomrom"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dobbeltrykk på mellomromstasten for punktum etterfulgt av mellomrom"</string>
<string name="auto_cap" msgid="1719746674854628252">"Stor forbokstav"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Inndataspråk"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Trykk på nytt for å lagre"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Ordbok tilgjengelig"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Aktiver brukertilbakemelding"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Ved å sende bruksstatistikk og programstopprapporter til Google automatisk, hjelper du oss med å gjøre redigeringsfunksjonen for denne inndatametoden enda bedre."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tastaturtema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engelsk (Storbritannia)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engelsk (USA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktiver"</string>
<string name="not_now" msgid="6172462888202790482">"Ikke nå"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Inndatastilen finnes allerede: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Bruksstudiemodus"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Forsinkelse lange tastetrykk"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrasjonstid ved tastetrykk"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Lydstyrke ved tastetrykk"</string>
diff --git a/java/res/values-ne-rNP/strings-action-keys.xml b/java/res/values-ne-rNP/strings-action-keys.xml
index 34b0a14a7..5c0a46225 100644
--- a/java/res/values-ne-rNP/strings-action-keys.xml
+++ b/java/res/values-ne-rNP/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"पहिलो"</string>
<string name="label_done_key" msgid="7564866296502630852">"भयो"</string>
<string name="label_send_key" msgid="482252074224462163">"पठाउनुहोस्"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"रोक्नुहोस्"</string>
<string name="label_wait_key" msgid="5891247853595466039">"पर्खनुहोस्"</string>
</resources>
diff --git a/java/res/values-ne-rNP/strings-emoji-descriptions.xml b/java/res/values-ne-rNP/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..a3419b86d
--- /dev/null
+++ b/java/res/values-ne-rNP/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"प्रतिलिपि अधिकार चिन्ह"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"दर्ता चिन्ह"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"दोहोरो उद्गार मार्क"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"विस्मयादिबोधक प्रश्न चिन्ह"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"व्यापार प्रतिक चिन्ह"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"सूचना स्रोत"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"दायाँ तीर बाँयामा"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"तल तीर माथिमा"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"उत्तर पश्चिम तीर"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"उत्तर पूर्वी तीर"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"दक्षिण पूर्व तीर"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"दक्षिण पश्चिम तीर"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"बायाँ हुक साथ तीर"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"दाँया हुक साथ तीर"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"हेर्नु"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"बलौटे घडी"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"कालो दाँया देखाउने डबल त्रिकोण"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"कालो बायाँ-इशारा डबल त्रिकोण"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"कालो माथि देखाउने डबल त्रिकोण"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"कालो तल-इशारा डबल त्रिकोण"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"सचेतक घडी"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"बग्ने बालुवा साथ बालुवा घडी"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"बृताकार भित्र ठुलो ल्याटिन अक्षर m"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"कालो सानो वर्ग"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"श्वेत सानो वर्ग"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"कालो दाँया देखाउने त्रिकोण"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"कालो बायाँ-इशारा त्रिकोण"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"श्वेत मध्यम वर्ग"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"कालो मध्यम वर्ग"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"श्वेत मध्यम सानो वर्ग"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"कालो मध्यम सानो वर्ग"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"किरण साथ कालो सूर्य"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"बादल"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"कालो टेलिफोन"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"जाँच साथ मतदान बक्स"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"वर्षा थोपा साथ छाता"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"तातो पेय"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"श्वेत अप सूचकांक इशारा"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"श्वेत हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"मेष"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"वृष"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"मिथुन"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"कर्कट"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"सिंह"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"कन्या"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"तुला"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"वृष"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"धनु"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"मकर"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"कुंभ"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"मीन"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"कालो कुदाल सुट"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"कालो क्लब सुट"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"कालो हृदय सुट"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"कालो हीरा सुट"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"तातो स्प्रिंग्स"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"कालो विश्वव्यापी रिसाइकिलिंग चिन्ह"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"ह्वीलचेयर चिन्ह"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"अंकुश"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"चेतावनी चिन्ह"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"उच्च भोल्टेज चिन्ह"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"मध्यम सफेद वृत्त"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"मध्यम कालो वृत्त"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"फुटबल"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"बेसबल"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"बिना हिउँ हिममानब"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"बादलको पछाडी सूर्य"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"तारामंडल Ophiuchus"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"प्रवेश निषेध"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"चर्च"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"फोहरा"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"प्वालमा झण्डा"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"जहाजयात्रा"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"पाल"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"इन्धन पम्प"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"कालो कैंची"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"श्वेत भारी चेक मार्क"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"हवाइजहाज"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"खाम"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"उठेको मुट्ठी"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"उठाएको हात"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"विजयी हात"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"शिसाकलम"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"कालो निब"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"भारी चेक मार्क"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"भारी गुणन x"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"झिल्काहरु"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"आठधर्के तारांकन"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"आठ चुच्चे कालो तारा"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"हिमपात"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"चमक"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"क्रस चिन्ह"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"उल्टो चारपाते काटिएको चिन्ह"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"कालो प्रश्न चिन्ह आभूषण"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"श्वेत प्रश्न चिन्ह आभूषण"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"श्वेत उद्गार चिन्ह आभूषण"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"भारी उद्गार चिन्ह प्रतिक"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"दह्रो कालो हृदय"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"भारी प्लस चिन्ह"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"भारी ऋण चिन्ह"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"भारी विभाजन चिन्ह"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"कालो दाँयातीर तीर"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"घुम्रिएको फेरो"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"दोहोरो घुम्रिएको फेरो"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"दाँयातीर इशारा तीर त्यसपछि माथिको घुमाँइ"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"दाँयातीर इशारा तीर त्यसपछि तलको घुमाँइ"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"कालोतीर बायाँतर्फ"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"कालो तीर माथि तर्फ"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"कालो तीर तल तर्फ"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"कालो ठूलो वर्ग"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"सेतो ठूलो वर्ग"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"सेतो मध्यम तारा"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"भारी ठूलो वृत्त"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"तरंग ड्यास"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"खण्ड बैकल्पिक मार्क"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"बृताकार भाबाङ्कन बधाई"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"बृताकार भाबाङ्कन रहस्य"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"माजोङ टाइल रातो ड्रागन"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"खेल्ने तास कालो जोकर"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"रक्त प्रकार A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"रक्त प्रकार B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"रक्त प्रकार O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"पार्क्ङिग स्थल"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"रक्त प्रकार AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"चारपाटे CL"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"चारपाते सुन्दर"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"चारपाते मुक्त"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"चारपाते ID"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"चारपाते नयाँ"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"चारपाते N G"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"चारपाते ठीक"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"चारपाते SOS"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"उद्गार चिन्ह साथ चारपाते"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"चारपाते बिरुद्ध"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"यहाँ चारपाते काताकाना"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"चारपाते काताकाना सेवा"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"चारपाते भाबाङ्कन -निःशुल्क"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"चारपाते भाबाङ्कन सुरक्षित-सीट"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"चारपाते भाबाङ्कन निषेध"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"चारपाते भाबाङ्कन रिक्तता"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"चारपाते भाबाङ्कन स्वीकृति"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"चारपाते भाबाङ्कन पूर्ण अधिभोग"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"चारपाते भाबाङ्कन भुक्तानी"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"चारपाते भाबाङ्कन मासिक"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"चारपाते भाबाङ्कन अनुप्रयोग"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"चारपाते भाबाङ्कन छूट"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"व्यापारमा चारपाते भाबाङ्कन"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"बृताकार भाबाङ्कन लाभ"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"बृताकार भाबाङ्कन स्वीकार"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"चक्रवात"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"धुवाँदार"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"बन्द छाता"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"ताराहरूका साथ रात"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"पहाडमा सूर्योदय"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"सूर्योदय"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"धुलो रहित शहर"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"भवनहरुमा सूर्यास्त"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"ईन्द्रेणी"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"रातमा पुल"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"जल लहर"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"ज्वालामुखी"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"दुधेली बाटो"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"पृथ्बी विश्व युरोप-अफ्रिका"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"पृथ्बी विश्व अमेरीकास"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"पृथ्बी विश्व एशिया-अस्ट्रेलिया"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"मेरीडियन साथ विश्व"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"नयाँ चन्द्रमाको चिन्ह"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"पहेँलो अर्धचन्द्राकार चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"पहिलो चौथाई चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"पहेँलो बाँदर चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"पूर्ण चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"थकित बाँदर चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"अन्तिम चौथाई चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"चेतावनी अर्धचन्द्राकार चन्द्र प्रतीक"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"अर्धचन्द्राकार चन्द्र"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"नयाँ चन्द्रामुहार"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"पहिलो चौथाइ चन्द्रामुहार"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"अन्तिम चौथाइ चन्द्रामुहार"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"पूर्ण चन्द्रामुहार"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"सूर्यामुहार"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"चमकिलो तारा"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"सुटिङ तारा"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"ओखर"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"सिडिङ"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"सदाबहार रूख"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"पतझड रूख"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"ताड रूख"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"सिउँडी"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"तुलिप"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"चेरी फूल"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"गुलाब"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"जाभाकुसुम"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"सूर्यमुखी"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"फूल"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"काने मकै"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"काने धान"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"जडिबुटी"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"चार पाते क्लोभर"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"मेपल पातको"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"झरेको पात"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"पात हावामा उड्दै"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"च्याँउ"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"गोलभेंडा"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"डल्लो भन्टा"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"अंगूर"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"तरबूजा"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"खरबूजा"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"सुन्तले रङ"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"लेमन"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"केरा"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"भुईंकतहर"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"रातो स्याउ"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"हरियो स्याउ"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"नाशपाती"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"बयर"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"चेरी"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"स्ट्रबेरी"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"ह्यामबर्गर"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"पिज्जा टुक्रा"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"हड्डीमा मासु"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"कुखुराको खुट्टा"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"चामलको पातलो बिस्कुट"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"भातको बल"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"पकाएको भात"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"करी र भात"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"उमालेको कचौरा"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"स्पैगेट्टी"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"रोटी"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"फ्रान्सेली फ्राइज"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"रोस्ट गरेको मिठो आलु"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"जापानी मिठाई"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"ओदेन (जापानी खाना)"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"भात र काँचो माछा"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"तारेको सानो माछा"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"घुमाउरो डिजाइनमा माछा केक"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"नरम आइसक्रिम"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"चुर्ण बरफ"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"आइसक्रीम"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"डोनट"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"कुकीज"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"चकलेट बार"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"क्यान्डी"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"लालीपप"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"कस्तार्ड"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"महदानी"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"सर्टकेक"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"टिफिन बट्टा"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"खानाको भाँडो"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"पकाउँदै"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"काँटा र चक्कु"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"ह्यान्डल बिनाको चियाकप"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"शाके (जापानी रक्सी) बोतल र प्याला"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"रक्सी गिलास"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"ककटेल गिलास"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"ट्रपिकल पेयपदार्थ"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"बियर मग"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"बियर मग छुआएको"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"बच्चाको बोतल"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"रिबन"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"बेरिएको उपहार"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"जन्मदिनको केक"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"ज्याक-o-लालटिन"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"क्रिसमस रूख"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"सान्ताक्लस"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"आतसबाजी"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"आतसबाजी झिल्का"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"बेलुन"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"पार्टी भंडुवा"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"रङगिन बल"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"तानाबाता रूख"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"क्रस झण्डा"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"पाइन सजावट"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"जापानी गुडिया"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"कार्प तोरण"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"हावा झंकार"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"चन्द्र अबलोकन समारोह"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"स्कूल झोला"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"दिक्षान्त समारोह टोपी"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"खेलाची घोडा"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"रोटेपिङ्"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"रोलर कोस्टर"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"माछामार्ने पोल र माछा"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"माइक्रोफोन"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"चलचित्र क्यामेरा"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"चलचित्र"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"हेडफोन"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"कलाकार रङदानी"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"शीर्ष टोपी"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"सर्कस पाल"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"टिकट"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"क्लापर बोर्ड"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"कला प्रदर्शन"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"भिडियो खेल"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"प्रत्यक्ष निशाना"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"स्लट मिसिन"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"बिलियर्ड्स"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"पोट"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"बलिङ"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"फूलछापे तास"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"साङ्गीतिक अक्षर"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"बहु साङ्गीतिक अक्षर"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"सेक्सोफोन"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"गितार"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"साङ्गीतिक कुञ्जीपाटी"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"बिगुल"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"भ्वायलिन"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"साङ्गीतिक स्कोर"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"तेर्सो धर्के जर्सी"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"टेनिस रैकेट र बल"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"स्की र स्की बुट"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"बास्केटबल र रिंग"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"चेकढाँचा झण्डा"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"स्नोबोर्दर"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"धावक"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"सर्फ़र"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"शिल"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"घोडा दौड"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"अमेरिकी फुटबल"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"रग्बी फुटबल"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"पौडीबाज"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"घर निर्माण"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"बगैचा सहित घर"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"कार्यालय भवन"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"जापानी हुलाक"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"युरोपेली हुलाक"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"अस्पताल"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"बैंक"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"स्वचालित पारंगत मिसिन"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"होटल"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"मायालु होटल"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"सुविधाजनक स्टोर"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"स्कूल"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"डिपार्टमेन्ट स्टोर"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"कारखाना"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"इजाकाया लालटेन"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"जापानी किल्ला"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"युरोपेली किल्ला"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"मुसा"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"घरेलु मुसा"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"साँढे"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"जल भैंसी"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"गाई"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"चितुवा"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"खरायो"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"बिरालो"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"ड्रागन"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"गोही"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"ह्वेल"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"घोंघा"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"साँप"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"घोडा"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"मेष"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"बाख्रा"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"भेडा"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"बाँदर"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"रोस्टर कुखुरा"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"कुखुरा"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"कुकुर"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"सुँगुर"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"बँदेल"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"हात्ती"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"अक्टोपस"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"शंख"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"कनसुत्लो"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"कमिला"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"माहुरी"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"खपटे कीरा"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"माछा"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"ट्रपिकल माछा"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"फुगु"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"कछुवा"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"चल्ला कोरल्नु"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"सानोचल्ला"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"अधोमुख सानोचल्ला"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"चरा"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"पेंगुइन"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"कोआल"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"पूडल"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"अरेबि उँट"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"दुईजुरे उँट"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"डल्फिन"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"मुसा अनुहार"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"गाई अनुहार"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"बाघ अनुहार"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"खरायो अनुहार"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"ड्रागन अनुहार"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"ह्वेल पानीफाल्दै"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"घोडा अनुहार"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"बाँदर अनुहार"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"कुकुर अनुहार"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"सुँगुर अनुहार"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"भ्यागुतो अनुहार"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"लोखर्के अनुहार"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"ब्वाँसो अनुहार"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"भालु अनुहार"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"पाण्डा अनुहार"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"सुँगुर नाक"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"पंजा छाप"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"आँखाहरु"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"कान"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"नाक"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"मुख"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"जिब्रो"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"ठडाएको औंला पछाडिबाट सूचकांक इशारा"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"घोप्ताएको औंला पछाडिबाट सूचकांक इशारा"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"औंला इशारा पछाडिबाट सूचकांक बायाँ"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"औंला इशारा पछाडिबाट सूचकांक दायाँ"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"मुठी चिन्ह"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"हल्लाएको हात चिन्ह"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"ठीक हात चिन्ह"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"औंठा माथी चिन्ह"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"औंठा तल चिन्ह"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"ताली चिन्ह"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"खुला हात चिन्ह"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"श्रीपेच"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"महिला टोपी"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"चश्मा"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"टाई"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"टी-शर्ट"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"जीन्स"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"पोशाक"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"किमोनो"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"बिकिनी"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"महिला लुगा"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"बटुआ"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"हैंडबैग"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"थैली"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"केटा जुत्ता"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"खेलाडी जुत्ता"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"अग्लो हिलको जुत्ता"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"महिला जुत्ता"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"महिला बूट"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"पैताला छाप"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"छाँया चित्र"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"छाँया चित्रहरू"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"केटा"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"केटी"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"मान्छे"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"महिला"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"परिवार"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"स्त्री र पुरुष हातसमात्दै"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"दुई पुरुष हातसमात्दै"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"दुई महिला हातसमात्दै"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"प्रहरी अधिकारी"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"खरायो काने महिला"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"घुम्टोमा दुलही"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"खैरो कपाल व्यक्ति"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"गुआपी माओ पहिरनमा मानिस"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"फेटाधारी मानिस"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"बृढमान्छे"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"बृढा महिला"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"बच्चा"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"निर्माण कामदार"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"राजकुमारी"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"जापानी राक्षस"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"जापानी लुटेरा"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"भूत"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"सानोपरी"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"अन्य ग्रहबासी"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"अन्य ग्रहबासी राक्षस"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"सानो शैतान"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"खोपडी"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"सोधपुछको व्यक्ति"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"पहरेदार"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"नर्तक"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"लिपस्टिक"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"नेल पलिश"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"अनुहार मालिश"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"सैलुन"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"नाई पोल"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"सुई"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"गोली"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"चुम्बन चिन्ह"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"प्रेमपत्र"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"औंठी"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"रत्न पत्थर"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"चुम्बन"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"फूलगुच्छा"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"युगलजोडी"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"विवाह"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"हृदय धड्कन"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"टुटेको हृदय"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"दुई हृदय"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"चम्केको हृदय"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"बढ्दो हृदय"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"तीर सहित हृदय"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"नीलो हृदय"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"हरियो हृदय"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"पहेंलो हृदय"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"बैजनी हृदय"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"रिबन साथ हृदय"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"परिक्रामी हृदय"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"हृदय सजावट"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"भित्र बिन्दु साथ हीरा आकार"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"इलेक्ट्रिक चिम"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"रिस प्रतीक"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"बम"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"सुताहा प्रतीक"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"टकराव प्रतीक"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"उछिट्टिएको पसिना प्रतीक"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"सानो थोपा"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"ड्यास प्रतीक"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"थुप्रो गु"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"पाखुरा प्रदर्शन"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"तारा प्रतीक"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"भाषण बेलुन"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"बैचारिक बेलुन"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"सेतो फूल"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"सय अंक प्रतीक"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"पैसाको थैली"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"मुद्रा विनिमय"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"मोटो डलर चिन्ह"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"क्रेडिट कार्ड"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"येन चिन्ह साथ नोट"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"डलर चिन्ह सहित बैकनोट"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"यूरो चिन्ह साथ नोट"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"पाउन्ड चिन्ह साथ नोट"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"पखेटाली मुद्रा"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"माथिको प्रवृत्ति र येन चिन्ह साथ चित्रपाती"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"सिट"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"निजी कम्प्यूटर"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"ब्रिफकेस"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"सानो डिस्क"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"फ्लपी डिस्क"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"सी डि चक्का"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"डिभिडी"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"फाइल फोल्डर"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"फाइल फोल्डर खोल्नुहोस्"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"दोब्र्याइएको पृष्ठ"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"माथि पत्याएको पृष्ठ"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"पात्रो"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"च्यातेर पठाउने पात्रो"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"कार्ड सूचकांक"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"माथिको प्रवृत्ति साथ चित्रपाती"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"तल प्रवृत्ति साथ चित्रपाती"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"बार चार्ट"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"क्लिपबोर्ड"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"पुस पिन"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"गोल पुस पिन"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"क्लिप"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"फुट"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"त्रिकोणात्मक फुट"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"किताबी ट्याबहरू"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"लेजर"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"नोटबुक"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"सजावटी खोल सहित नोटबुक"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"बन्द पुस्तक"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"खुला पुस्तक"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"हरियो पुस्तक"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"नीलो पुस्तक"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"सुन्तला पुस्तक"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"पुस्तकहरू"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"बिल्ला नाम"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"स्क्रोल"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"मेमो"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"टेलिफोन रिसीभर"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"पेजर"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"फ्याक्स मेसिन"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"स्याटलाइट एंटीना"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"आकाशबाणी"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"ढ्वांग फुक्नु"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"आउटबक्स ट्रे"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"इनबक्समा ट्रे"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"प्याकेज"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"इमेल प्रतीक"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"आगमन खाम"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"माथि तीर तल देखाइएको साथ खाम"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"माथि झण्डा साथ बन्द मेलबक्स"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"उठाएको झन्डा साथ बन्द मेलबक्स"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"उठाएको झन्डा साथ खुला मेलबक्स"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"तल झण्डा साथ खुला मेलबक्स"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"पत्र पेटिका"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"पोस्टल सीङ"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"अखबार"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"मोबाइल फोन"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"दाँया तीर साथ मोबाइल फोन बायाँ"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"कम्पन ढाँचाः"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"मोबाइल फोन बन्द"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"बिना मोबाइल फोनहरु"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"बारहरू साथ एंटीना"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"क्यामेरा"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"भिडियो क्यामेरा"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"टेलिभिजन"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"रेडियो"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"भिडियोक्यासेट"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"दाँया बटारिएको तीर"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"दाँया र बायाँ खुला वृत्त तीर घडीकोदिशामा"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"वृत्त दोबारेको साथ दाँया र बायाँ खुला वृत्त तीर घडीकोदिशामा"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"घडीको दिशामा तल र माथिको तर्फ खुला वृत्त तीर"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"उल्टा घडीको दिशामा तल र माथिको तर्फ खुला वृत्त तीर"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"कम चमक प्रतीक"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"उच्च चमक प्रतीक"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"ध्वोंनी निषेध स्ट्रोक"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"स्पिकर"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"एक तरङ्ग साथ स्पिकर"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"तीन ध्वनि लहरहरु साथ स्पिकर"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"ब्याट्री"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"बिद्धुतीय प्लग"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"बाँया-इशारा आबर्धक लेन्स"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"दायाँ इशारा आबर्धक लेन्स"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"मसी कलमले बन्द"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"साँचो साथ बन्द ताला"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"साँचो"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"लक गर्नुहोस्"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"खुला ताला"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"घन्टी"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"रद्द स्ट्रोक साथ घन्टी"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"बुकमार्क"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"संपर्क प्रतीक"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"रेडियो बटन"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"बायाँ माथि तीर साथ फर्काएको"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"बायाँ माथि तीर साथ अन्त्य"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"बायाँ साथ उद्गार चिन्हले दाँया माथि तीर"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"दाँया माथि तीर साथ चाँडै"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"माथिको माथि तीर साथ माथि"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"अठार मुनिका प्रतीक निषेधित"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"किक्याप दस"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"ठुलो ल्याटिन अक्षरका आगत प्रतीक"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"सानो ल्याटिन अक्षरका आगत प्रतीक"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"संख्याका लागि आगत प्रतीक"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"प्रतीकको लागि प्रतीक प्रविष्ट गर्नुहोस्"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"ल्याटिन अक्षरका आगत प्रतीक"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"आगो"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"बिजुली बत्ती"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"रेंच"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"हथौडा"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"नट बोल्ट"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"जापानी चक्कु होचो"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"पिस्तौल"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"माइक्रोस्कोप"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"टेलिस्कोप"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"क्रिस्टल बल"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"बीचमा थोप्ला निहित छ चुच्चे तारा"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"शुरुवातको लागि जापानी प्रतीक"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"त्रिशूल प्रतीक"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"कालो वर्ग बटन"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"सेतो वर्ग बटन"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"ठूलो लाल वृत्त"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"ठूलो नीलो वृत्त"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"ठूलो सुन्तला हीरा"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"ठूलो नीलो हीरा"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"लघु सुन्तला हीरा"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"लघु नीलो हीरा"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"माथी-इशारा रातो त्रिकोण"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"तल-इशारा रातो त्रिकोण"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"माथी इशारा सानो रातो त्रिकोण"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"तल-इशारा सानो रातो त्रिकोण"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"घडी अनुहार एक बजे"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"घडी अनुहार दुई बजे"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"घडी अनुहार तीन बजे"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"घडी अनुहार चार बजे"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"घडी अनुहार पाँच बजे"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"घडी अनुहार छ बजे"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"घडी अनुहार सात बजे"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"घडी अनुहार आठ बजे"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"घडी अनुहार नौ बजे"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"घडी अनुहार दश बजे"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"घडी अनुहार एघार बजे"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"घडी अनुहार बाह्र बजे"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"घडी अनुहार एक-तिस"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"घडी अनुहार दुई-तिस"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"घडी अनुहार तीन तीस"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"घडी अनुहार चार-तिस"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"घडी अनुहार पाँच-तिस"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"घडी अनुहार छ-तिस"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"घडी अनुहार सात-तिस"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"घडी अनुहार आठ-तिस"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"घडी अनुहार नौ-तिस"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"घडी अनुहार दश-तिस"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"घडी अनुहार एघार-तिस"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"घडी अनुहार बाह्र-तिस"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"माउन्ट फुजी"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"टोकियो टावर"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"स्वतन्त्रताको प्रतिमा"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"जापानको छान्य मुर्ति"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"मोयै"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"अनुहार ङिच्च हँसाइ"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"हँसिल आँखाको साथ ङिच्च हँसाइ"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"आनन्द आँसुको साथ अनुहार"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"खुला मुखको साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"खुला मुखको र हँसिलो आँखा साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"खुला मुख र चिसो पसिना साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"खुला मुख र बन्द आँखाको साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"हेलो साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"सिंगहरु साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"आँखा झिम्काएको अनुहार"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"हँसिलो आँखाले साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"स्वादिष्ट भोजन savoring अनुहार"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"ढुक्क अनुहार"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"हृदय आकारको आँखाले हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"घाम साथ हँसिलो अनुहार"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"स्वाँग पारेको अनुहार"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"सामान्य अनुहार"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"भाबबिहिन अनुहार"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"निराश अनुहार"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"चिसो पसिना साथ अनुहार"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"चिंताग्रस्त अनुहार"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"गोलमाल अनुहार"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"आघातको अवस्थामा अनुहार"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"चुम्बन अनुहार"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"चुम्बन फालिएको अनुहार"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"हँसिलो आँखा साथ चुम्बन अनुहार"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"बन्द आँखा साथ चुम्बन अनुहार"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"बाहिर जिब्रो साथ अनुहार"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"बाहिर जिब्रो र झिम्काएको आँखा साथ अनुहार"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"बाहिर जिब्रो र बेस्सरी बन्द आँखा साथ अनुहार"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"निराश अनुहार"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"चिन्तित अनुहार"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"आक्रोशित अनुहार"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"दुखी अनुहार"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"कराएको अनुहार"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"संरक्षित अनुहार"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"विजय नजर अनुहार"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"निराश तर राहत अनुहार"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"खुला मुखको साथ निन्याउरो अनुहार"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"विचलित अनुहार"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"डराएको अनुहार"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"थकित अनुहार"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"निदाएको अनुहार"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"थकित अनुहार"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"कित्किताएको अनुहार"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"चर्को सोरले कराएको अनुहार"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"खुला मुख अनुहार"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"चुप अनुहार"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"खुला मुख र चिसो पसिना अनुहार"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"डरमा चिल्लाएको अनुहार"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"छक्क अनुहार"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"निर्लज्ज अनुहार"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"निन्द्रे अनुहार"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"चक्करलागेको अनुहार"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"मुख नभएको अनुहार"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"चिकित्सक माक्स लगाएको अनुहार"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"हँसिलो आँखा साथ ङीच्च बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"आनन्द आँसु झार्दै बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"खुला मुखले हँसिलो बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"हृदय आकारको आँखाले हँसिलो बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"छट्टु मुस्कान साथ बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"बन्द आँखा साथ चुम्बन बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"दुखी बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"कराएको बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"वाक्क भइसकेको बिरालो अनुहार"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"कुनै राम्रो सङ्केत बिना साथ अनुहार"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"ठीक इशारा साथ अनुहार"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"गहिरो निहुरेको व्यक्ति"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"हेर्नुहोस्-कुनै-दुष्ट बाँदर"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"सुन-कुनै-दुष्ट बाँदर"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"बोल्नु-कुनै-दुष्ट बाँदर"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"खुसी व्यक्ति एक हात उठाउँदै"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"उत्सवमा दुवै हात उठाँउदैको व्यक्ति"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"निराश व्यक्ति"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"दुखी अनुहार व्यक्ति"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"नतमस्तक व्यक्ति"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"रकेट"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"हेलिकोप्टर"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"भापद्वारा चल्ने यातायात"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"रेलवे कार"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"उच्च गति रेल"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"गोली नाक साथ उच्च गतिमा रेल"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"रेल"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"मेट्रो"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"प्रकाश रेल"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"स्टेशन"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"ट्राम"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"ट्राम कार"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"बस"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"आउदैको बस"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"ट्रलीबस"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"बस बिसौना"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"सानो बस"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"एम्बुलेन्स"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"दमकल"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"प्रहरी कार"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"आऊदैको प्रहरी कार"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"ट्याक्सी"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"आऊदैको ट्याक्सी"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"अटोमोबाइल"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"आऊदैको गाडी"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"मनोरंजन वाहन"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"वितरण ट्रक"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"जोडिएको ठूलोगाडी"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"ट्रयाक्टर"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"एकतर्फी रेल"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"पहाडी रेलवे"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"सस्पेंशन रेलवे"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"पहाडी केवलवे"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"हवाई ट्रामगाडी"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"पानीजहाज"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"डुंगा"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"द्रुत डुंगा"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"तेर्सो यातायात बत्ती"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"ठाडो यातायात प्रकाश"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"निर्माण चिन्ह"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"प्रहरी कारको परिक्रामी प्रकाश"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"पोस्टमा त्रिकोणात्मक झण्डा"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"ढोका"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"प्रवेश निषेध चिन्ह"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"धूम्रपान चिन्ह"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"धुम्रपान निषेधित चिन्ह"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"फोहर राख्ने ठाउँ चिन्ह"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"फोहर फाल्न निषेधित चिन्ह"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"पेय जल चिन्ह"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"गैह्र पिउने पानी चिन्ह"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"साइकल"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"साइकल निषेध"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"साइकल यात्री"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"पहाडी साइकल् यात्री"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"पैदल यात्री"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"पैदल यात्री निषेध"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"बच्चाहरु बाटो काट्दै"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"पुरुष चिन्ह"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"महिला चिन्ह"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"शौचालय"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"बच्चा चिन्ह"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"शौचालय"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"कम्बोथ"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"फोहरा"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"स्नान"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"बाथटब"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"राहदानी नियन्त्रण"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"भन्सार"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"सामान दाबी"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"छुटेको सामान"</string>
+</resources>
diff --git a/java/res/values-ne-rNP/strings-talkback-descriptions.xml b/java/res/values-ne-rNP/strings-talkback-descriptions.xml
index cffed33db..044a04154 100644
--- a/java/res/values-ne-rNP/strings-talkback-descriptions.xml
+++ b/java/res/values-ne-rNP/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"कुनै पाठ प्रविष्टि गरिएको छैन"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ले <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> लाई <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> मा सच्याउँछ"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ले स्वतः सच्याउने गर्छ"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"कुञ्जी कोड %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"सिफ्ट"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"सिफ्ट सक्रिय छ (असक्षम पार्न ट्याप गर्नुहोस्)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"क्याप्स लक सकृय छ (असक्षम पार्न ट्याप गर्नुहोस्)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"थप प्रतीकहरु"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"सिफ्ट"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"प्रतीकहरू"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"सिफ्ट"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"मेटाउनुहोस्"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"प्रतिकहरू"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"अक्षरहरू"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"अघिल्लो"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"सिफ्ट सक्षम पारिएको छ"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"क्याप्स लक सक्षम पारिएको छ"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"सिफ्ट असक्षम पारिएको छ"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"प्रतिक ढाँचा"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"थप प्रतीक मोड"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"अक्षर ढाँचा"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"फोन ढाँचा"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"फोन प्रतिक मोड"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"स्थानहरू"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"प्रतिकहरू"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"ईमोटिकन्स"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ne-rNP/strings.xml b/java/res/values-ne-rNP/strings.xml
index f467443b3..22e5acb91 100644
--- a/java/res/values-ne-rNP/strings.xml
+++ b/java/res/values-ne-rNP/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"इनपुट विकल्पहरू"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"लग निर्देशनहरू शोध गर्नुहोस्"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"सम्पर्क नामहरू हेर्नुहोस्"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"तपाईँको सम्पर्क सूचीबाट हिज्जे परीक्षकले प्रविष्टिहरूको प्रयोग गर्छ"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"कुञ्जी थिच्दा भाइब्रेट"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"सम्पर्क नामहरू सुझाव गर्नुहोस्"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"सुझाव र सुधारका लागि सम्पर्कबाट नामहरू प्रयोग गर्नुहोस्"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"निजीकृत सुझावहरू"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"डबल-स्पेस पूर्णविराम"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"स्पेसबारमा डबल ट्याप गर्नाले पूर्णविरामपछि स्पेस राख्दछ"</string>
<string name="auto_cap" msgid="1719746674854628252">"स्वतः पूँजिकरण"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"इनपुट भाषाहरू"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"बचत गर्न पुनः छुनुहोस्"</string>
<string name="has_dictionary" msgid="6071847973466625007">"उपलब्ध शब्दकोश"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"प्रयोगकर्ता प्रतिक्रिया सक्षम पार्नुहोस्"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"स्वचालित रूपमा प्रयोग तथ्याङ्कहरू र क्यास रिपोर्टहरू पठाएर यस इनपुट विधि सम्पादकलाई सुधार्न सहयोग गर्नुहोस्।"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"किबोर्ड थिम"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"अंग्रेजी (युके)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"अंग्रेजी (युएस्)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"सक्षम पार्नुहोस्"</string>
<string name="not_now" msgid="6172462888202790482">"अहिले होइन"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"यस्तो इनपुट शैली पहिले नै अवस्थित छ: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"प्रयोग अध्ययन मोड"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"कुञ्जी लामो थिचाइ ढिलाइ"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"कुञ्जी थिचाइ भाइब्रेसन अवधि"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"कुञ्जी थिचाइ आवाज भोल्युम"</string>
diff --git a/java/res/values-nl/strings-action-keys.xml b/java/res/values-nl/strings-action-keys.xml
index c1ce25acf..c9c68bd25 100644
--- a/java/res/values-nl/strings-action-keys.xml
+++ b/java/res/values-nl/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Vorig"</string>
<string name="label_done_key" msgid="7564866296502630852">"Klaar"</string>
<string name="label_send_key" msgid="482252074224462163">"Verz."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauze"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Wacht"</string>
</resources>
diff --git a/java/res/values-nl/strings-talkback-descriptions.xml b/java/res/values-nl/strings-talkback-descriptions.xml
index 8dcd5748d..57bbf91e2 100644
--- a/java/res/values-nl/strings-talkback-descriptions.xml
+++ b/java/res/values-nl/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Geen tekst ingevoerd"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Met <xliff:g id="KEY_NAME">%1$s</xliff:g> wordt <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> gecorrigeerd naar <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Met <xliff:g id="KEY_NAME">%1$s</xliff:g> voert u automatische correctie uit"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Toetscode %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift aan (tik om uit te schakelen)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock aan (tik om uit te schakelen)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Meer symbolen"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbolen"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Verwijderen"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbolen"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letters"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Vorige"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift ingeschakeld"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock ingeschakeld"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift uitgeschakeld"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbolen"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modus voor meer symbolen"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Alfanumeriek toetsenbord"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Toetsenbord telefoon"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefoonsymbolen"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Plaatsen"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbolen"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticons"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-nl/strings.xml b/java/res/values-nl/strings.xml
index 342464fc8..94ccd6b46 100644
--- a/java/res/values-nl/strings.xml
+++ b/java/res/values-nl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Invoeropties"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Opdrachten in onderzoekslogbestand"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Contactnamen opzoeken"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"De spellingcontrole gebruikt items uit uw contactenlijst"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Trillen bij toetsaanslag"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Contactnamen suggereren"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Namen uit Contacten gebruiken voor suggesties en correcties"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Gepersonaliseerde suggesties"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dubbeltik is punt, spatie"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubbeltik op spatiebalk voor een punt gevolgd door een spatie"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-hoofdlettergebruik"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Invoertalen"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Raak nogmaals aan om op te slaan"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Woordenboek beschikbaar"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Gebruikersfeedback inschakelen."</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Help deze invoermethode te verbeteren door automatisch gebruiksstatistieken en crashmeldingen te verzenden."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Toetsenbordthema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engels (GB)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engels (VS)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Inschakelen"</string>
<string name="not_now" msgid="6172462888202790482">"Niet nu"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Dezelfde invoerstijl bestaat al: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modus voor gebruiksvriendelijkheidsonderzoek"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Vertraging toets lang indrukkn"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Trilingsduur bij toetsgebruik"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Geluidsvolume bij toetsgebruik"</string>
diff --git a/java/res/values-pl/strings-action-keys.xml b/java/res/values-pl/strings-action-keys.xml
index 2984b98b8..d641cbc9e 100644
--- a/java/res/values-pl/strings-action-keys.xml
+++ b/java/res/values-pl/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Wróć"</string>
<string name="label_done_key" msgid="7564866296502630852">"Gotowe"</string>
<string name="label_send_key" msgid="482252074224462163">"Wyślij"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauza"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Czekaj"</string>
</resources>
diff --git a/java/res/values-pl/strings-talkback-descriptions.xml b/java/res/values-pl/strings-talkback-descriptions.xml
index 567bb3b23..1708ae02a 100644
--- a/java/res/values-pl/strings-talkback-descriptions.xml
+++ b/java/res/values-pl/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nie wpisano tekstu"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> poprawia <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> na <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> wykonuje autokorektę"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Kod klawisza: %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift włączony (kliknij, by wyłączyć)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock włączony (kliknij, by wyłączyć)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Więcej symboli"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symbole"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Usuń"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symbole"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Litery"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Wstecz"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift włączony"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock włączony"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift wyłączony"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Tryb symboli"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Tryb dodatkowych symboli"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Tryb liter"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Tryb telefonu"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Tryb symboli telefonu"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Miejsca"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symbole"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikony"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-pl/strings.xml b/java/res/values-pl/strings.xml
index c4261c60e..218e6197e 100644
--- a/java/res/values-pl/strings.xml
+++ b/java/res/values-pl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opcje wprowadzania"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Polecenia dziennika badań"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Przeszukaj kontakty"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Sprawdzanie pisowni bierze pod uwagę wpisy z listy kontaktów."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Wibracja przy naciśnięciu"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Proponuj osoby z kontaktów"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"W propozycjach i poprawkach użyj nazwisk z kontaktów"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Spersonalizowane sugestie"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Szybka kropka ze spacją"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dwukrotne kliknięcie spacji wstawia kropkę ze spacją"</string>
<string name="auto_cap" msgid="1719746674854628252">"Wstawiaj wielkie litery"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Języki wprowadzania"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Dotknij ponownie, aby zapisać"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Słownik dostępny"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Włącz przesyłanie opinii użytkownika"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Pomóż ulepszyć edytor wprowadzania tekstu, automatycznie wysyłając statystyki użycia i raporty o awariach."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Motyw klawiatury"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angielski (Wielka Brytania)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angielski (Stany Zjednoczone)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Włącz"</string>
<string name="not_now" msgid="6172462888202790482">"Nie teraz"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Taki styl wprowadzania już istnieje: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Tryb badania przydatności"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Opóźnienie przy długim naciśnięciu"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Wibracja przy naciśniętym klawiszu"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Głośność przy naciśniętym klawiszu"</string>
diff --git a/java/res/values-pt-rPT/strings-action-keys.xml b/java/res/values-pt-rPT/strings-action-keys.xml
index 7a7559fea..1b5921f3e 100644
--- a/java/res/values-pt-rPT/strings-action-keys.xml
+++ b/java/res/values-pt-rPT/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Ant."</string>
<string name="label_done_key" msgid="7564866296502630852">"Conc."</string>
<string name="label_send_key" msgid="482252074224462163">"Env."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pausa"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Esp."</string>
</resources>
diff --git a/java/res/values-pt-rPT/strings-talkback-descriptions.xml b/java/res/values-pt-rPT/strings-talkback-descriptions.xml
index bf51caa78..91d187ec9 100644
--- a/java/res/values-pt-rPT/strings-talkback-descriptions.xml
+++ b/java/res/values-pt-rPT/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nenhum texto digitado"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrige <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> para <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> executa a correção automática"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Código da tecla %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift ativado (tocar para desativar)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock ativado (tocar para desativar)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Mais símbolos"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Símbolos"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Eliminar"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Símbolos"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letras"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift ativado"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock ativado"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift desativado"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Modo de símbolos"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modo Mais símbolos"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Modo de letras"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Modo de telemóvel"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Modo de símbolos de telemóvel"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Locais"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Símbolos"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Ícones expressivos"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml
index 8b75dd0dd..86a619bc6 100644
--- a/java/res/values-pt-rPT/strings.xml
+++ b/java/res/values-pt-rPT/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opções de introdução"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Comandos de Reg. Invest."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Procurar nomes de contac."</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"O corretor ortográfico utiliza entradas da sua lista de contactos"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar ao primir as teclas"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de Contactos"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizar nomes dos Contactos para sugestões e correções"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Sugestões personalizadas"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Ponto de espaço duplo"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Tocar duas vezes na barra espaço insere ponto seguido de espaço"</string>
<string name="auto_cap" msgid="1719746674854628252">"Letras maiúsculas automáticas"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Idiomas de introdução"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para guardar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentários do utilizador"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Envie automaticamente estatísticas de utilização e relatórios de falhas e ajude-nos a melhorar este editor do método de introdução."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Inglês (RU)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Inglês (EUA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Ativar"</string>
<string name="not_now" msgid="6172462888202790482">"Agora não"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Já existe o mesmo estilo de introdução: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo da capacidade de utilização"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Atraso ao manter tecla premida"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Duração vibr. ao premir teclas"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume do som ao premir teclas"</string>
diff --git a/java/res/values-pt/strings-action-keys.xml b/java/res/values-pt/strings-action-keys.xml
index 1d8e760e7..470846b21 100644
--- a/java/res/values-pt/strings-action-keys.xml
+++ b/java/res/values-pt/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Ant."</string>
<string name="label_done_key" msgid="7564866296502630852">"Conc."</string>
<string name="label_send_key" msgid="482252074224462163">"Env."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pausa"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Esp."</string>
</resources>
diff --git a/java/res/values-pt/strings-emoji-descriptions.xml b/java/res/values-pt/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..84e2cc08c
--- /dev/null
+++ b/java/res/values-pt/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Símbolo de copyright"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Símbolo de marca registrada"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Ponto de exclamação duplo"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Ponto de exclamação e ponto de interrogação"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Símbolo de marca comercial"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Fonte de informação"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Seta para esquerda e para direita"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Seta para cima e para baixo"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Seta para o noroeste"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Seta para o nordeste"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Seta para o sudeste"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Seta para o sudoeste"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Seta para a esquerda com gancho"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Seta para a direita com gancho"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"Relógio de pulso"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Ampulheta"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Triângulo duplo preto para a direita"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Triângulo duplo preto para a esquerda"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Triângulo duplo preto para cima"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Triângulo duplo preto para baixo"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Despertador"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Ampulheta com areia correndo"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Letra M maiúscula contida em círculo"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Quadrado pequeno preto"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Quadrado pequeno branco"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Triângulo preto para a direita"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Triângulo preto para a esquerda"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Quadrado médio branco"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Quadrado médio preto"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Quadrado médio branco"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Quadrado médio preto"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Sol preto com raios"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Nuvem"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Telefone preto"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Urna de votação com marca de verificação"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Guarda-chuva com gotas de chuva"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Bebida quente"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Dedo indicador branco apontando para cima de frente"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Rosto sorridente branco"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Áries"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Touro"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Gêmeos"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Câncer"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Leão"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Virgem"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Libra"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Escorpião"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Sagitário"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Capricórnio"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Aquário"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Peixes"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Naipe preto de espadas"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Naipe preto de paus"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Naipe preto de copas"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Naipe preto de ouros"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Águas termais"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Símbolo de reciclagem universal preto"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Símbolo de cadeira de rodas"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Âncora"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Sinal de aviso"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Sinal de alta tensão"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Círculo branco médio"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Círculo preto médio"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Bola de futebol"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Bola de beisebol"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Boneco de neve sem neve"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Sol atrás da nuvem"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Serpentário"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Entrada proíbida"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Igreja"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Fonte"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Bandeira no buraco"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Barco a vela"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Barraca"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Bomba de combustível"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Tesoura preta"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Marca de verificação grossa branca"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Avião"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Envelope"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Punho levantado"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Mão levantada"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Mão de vitória"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Lápis"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Ponta de caneta-tinteiro preta"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Marca de verificação grossa"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Sinal de multiplicação x grosso"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Brilhos"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Asterisco de oito pontas"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Estrela preta de oito pontas"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Floco de neve"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Brilho"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Sinal de cruzamento"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"egativo de sinal de cruzamento contido em quadrado"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Ornamento de ponto de interrogação preto"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Ornamento de ponto de interrogação branco"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Ornamento de ponto de exclamação branco"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Símbolo de ponto de exclamação grosso"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Coração preto grosso"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Sinal de adição grosso"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Sinal de subtração grosso"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Sinal de divisão grosso"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Seta para a direita preta"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Laçada"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Laçada dupla"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Seta para a direita com curva para cima"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Seta para a direita com curva para baixo"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Seta preta para a esquerda"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Seta preta para cima"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Seta preta para baixo"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Quadrado grande preto"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Quadrado grande branco"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Estrela média branca"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Círculo grande grosso"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Traço ondulado"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Marca de alternação de parte"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Ideograma \"parabéns\" contido em círculo"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Ideograma \"segredo\" contido em círculo"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Pedra de mahjong do dragão vermelho"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Curinga preto de baralho"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Tipo sanguíneo A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Tipo sanguíneo B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Tipo sanguíneo O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Estacionamento"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Tipo sanguíneo AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"\"CL\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"\"COOL\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"\"‘FREE\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"\"ID\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"\"NEW\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"\"NG\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"\"OK\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"\"SOS\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"\"UP!\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"\"VS\" em letras de fôrma"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"Caracteres koko em katakana contidos em quadrado"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"Caractere sa em katakana contido em quadrado"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Ideograma \"gratuito\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Ideograma \"lugar reservado\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Ideograma \"proibição\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Ideograma \"vaga\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Ideograma \"aceitação\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Ideograma \"lotação esgotada\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Ideograma \"pago\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Ideograma \"mensal\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Ideograma \"aplicação\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Ideograma \"desconto\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Ideograma \"em atividade\" contido em quadrado"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Ideograma \"vantagem\" contido em círculo"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Ideograma \"aceitar\" contido em círculo"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Ciclone"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Enevoado"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Guarda-chuva fechado"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Noite estrelada"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Nascer do sol nas montanhas"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Nascer do sol"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Cidade ao entardecer"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Pôr do sol nos prédios"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Arco-íris"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Ponte à noite"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Onda do mar"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Vulcão"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Via Láctea"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Globo terrestre Europa/África"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Globo terrestre Américas"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Globo terrestre Ásia/Austrália"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Globo com meridianos"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Símbolo da lua nova"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Símbolo da lua crescente"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"Símbolo da lua em quarto crescente"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Símbolo da lua crescente gibosa"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Símbolo da lua cheia"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Símbolo da lua minguante gibosa"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Símbolo da lua em quarto minguante"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Símbolo da lua minguante"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Lua crescente"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Lua nova com rosto"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Lua em quarto crescente com rosto"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Lua em quarto minguante com rosto"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Lua cheia com rosto"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Sol com rosto"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Estrela brilhante"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Estrela cadente"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Castanha"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Muda"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Árvore perenifólia"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Árvore decídua"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Palmeira"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Cacto"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Tulipa"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Flor de cerejeira"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Rosa"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Hibisco"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Girassol"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Florescência"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Espiga de milho"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Espiga de arroz"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Erva"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Trevo de quatro folhas"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Folha de bordo"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Folha caída"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Folha ao sabor do vento"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Cogumelo"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Tomate"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Berinjela"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Uvas"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Melão"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Melancia"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Tangerina"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Limão"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Banana"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Abacaxi"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Maçã vermelha"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Maçã verde"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Pera"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Pêssego"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Cerejas"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Morango"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Hambúrguer"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Fatia de pizza"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Carne com osso"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Coxa de frango"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Biscoito de arroz japonês"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Bolinho de arroz japonês"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Arroz cozido"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Arroz com curry"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Tigela quente"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Espaguete"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Pão"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Batatas fritas"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Batata doce assada"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Dango"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oden"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Sushi"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Camarão frito"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Kamaboko com design de espiral"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Sorvete de massa"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Raspadinha"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Sorvete"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Rosquinha"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Cookie"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Barra de chocolate"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Doce"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Pirulito"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Flan"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Pote de mel"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Torta"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Marmiteira bento"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Tigela de comida"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Cozinha"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Garfo e faca"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Xícara sem asa"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Garrafa e copo para saquê"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Copo para vinho"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Copo para coquetel"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Bebida tropical"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Caneca de cerveja"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Canecas de cerveja brindando"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Mamadeira"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Fita de presente"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Presente embrulhado"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Bolo de aniversário"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Jack Lanterna"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Árvore de Natal"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Papai Noel"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Fogos de artifício"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Estrelinha"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Balão"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Lança confetes"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Bola de confetes"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Árvore de Tanabata"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Bandeiras cruzadas"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Decoração Kadomatsu"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Bonecas japonesas"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Biruta de carpa Koinobori"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Sinos de vento"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Cerimônia de contemplação da lua Otsukimi"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Mochila escolar"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Capelo"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Carrossel de cavalinho"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Roda-gigante"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Montanha russa"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Vara de pescar e peixe"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Microfone"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Câmera cinematográfica"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Cinema"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Fone de ouvido"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Aquarela"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Cartola"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Tenda de circo"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Ingresso"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Claquete"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Artes cênicas"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Videogame"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Bela pontaria"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Caça-níqueis"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Bilhar"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Dados"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Boliche"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Baralho temático de flores"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Nota musical"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Várias notas musicais"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Saxofone"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Guitarra"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Teclado musical"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Trompete"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Violino"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Partitura"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Camiseta de corrida com faixa"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Raquete e bola de tênis"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Esqui e bota de esqui"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Bola de basquete e cesto"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Bandeira xadrez"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Snowboarder"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Corredor"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Surfista"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Troféu"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Corridas de cavalos"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Futebol americano"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Bola de rugby"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Nadador"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Construção de casas"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Casa com jardim"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Edifício comercial"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Correio japonês"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Correio europeu"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Hospital"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Banco"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Caixa eletrônico"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Hotel"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Motel"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Loja de conveniência"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Escola"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Loja de departamentos"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Fábrica"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Luminária izakaya"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Castelo japonês"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Castelo europeu"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Rato"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Camundongo"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Boi"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Búfalo asiático"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Vaca"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Leopardo"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Coelho"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Gato"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Dragão"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Crocodilo"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Baleia"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Caracol"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Serpente"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Cavalo"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Carneiro"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Cabra"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Ovelha"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Macaco"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Galo"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Galinha"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Cachorro"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Porco"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Javali"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Elefante"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Polvo"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Concha espiral"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Inseto"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Formiga"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Abelha"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Joaninha"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Peixe"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Peixe tropical"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Peixe-balão"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Tartaruga"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Pintinho nascendo"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Pintinho"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Pintinho de frente"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Pássaro"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Pinguim"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Coala"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Poodle"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Dromedário"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Camelo bactriano"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Golfinho"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Smiley de rato"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Smiley de vaca"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Smiley de tigre"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Smiley de coelho"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Smiley de gato"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Smiley de dragão"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Baleia jorrando água"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Smiley de cavalo"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Smiley de macaco"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"Smiley de cachorro"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Smiley de porco"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Smiley de sapo"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Smiley de porquinho-da-índia"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Smiley de lobo"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Smiley de urso"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Smiley de panda"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Focinho de porco"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Pegadas de patas"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Olhos"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Orelha"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Nariz"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Boca"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Língua"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Dedo indicador branco apontando para cima"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Dedo indicador branco apontando para baixo"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Dedo indicador branco apontando para a esquerda"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Dedo indicador branco apontando para a direita"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Sinal de mão em punho"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Sinal de mão acenando"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"Sinal de mão indicando OK"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Sinal com polegar para cima"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Sinal com polegar para baixo"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Sinal de bater palmas"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Sinal de mãos abertas"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Coroa"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Chapéu de mulher"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Óculos de grau"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Gravata"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"Camiseta"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Calça jeans"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Vestido"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Quimono"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Biquíni"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Roupas de mulher"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Bolsinha"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Bolsa"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Bolsa saco"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Sapato masculino"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Tênis"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Sapato de salto alto"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Sandália feminina"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Botas femininas"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Pegadas"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Busto em silhueta"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Bustos em silhueta"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Menino"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Menina"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Homem"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Mulher"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Família"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Homem e mulher de mãos dadas"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Dois homens de mãos dadas"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Duas mulheres de mãos dadas"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Policial"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Mulher com orelhas de coelho"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Noiva com véu"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Pessoa loira"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Homem com gua pi mao"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Homem com turbante"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Idoso"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Idosa"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Bebê"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Operário de construção civil"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Princesa"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Ogro japonês"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Gnomo japonês"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Fantasma"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Anjo bebê"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Alienígena"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Monstro alienígena"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Duende"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Caveira"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Recepcionista de balcão de informações"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Guarda"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Dançarina"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Batom"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Esmalte"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Massagem facial"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Corte de cabelo"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Poste de barbearia"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Seringa"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Comprimido"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Marca de beijo"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Carta de amor"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Anel"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Gema"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Beijo"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Buquê"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Casal com coração"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Casamento"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Coração batendo"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Coração partido"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Dois corações"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Coração brilhando"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Coração crescendo"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Coração com flecha"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Coração azul"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Coração verde"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Coração amarelo"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Coração roxo"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Coração com fita"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Corações em círculo"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Decoração de coração"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Forma de losango com ponto interno"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Lâmpada elétrica"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Símbolo de raiva"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Bomba"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Símbolo de sono"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Símbolo de colisão"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Símbolo da gota de suor"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Gota"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Símbolo de traço"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Cocô"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Bíceps contraídos"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Símbolo de tontura"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Balão de fala"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Balão de pensamento"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Flor branca"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Símbolo de cem pontos"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Saco de dinheiro"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Câmbio de moeda"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Sinal de cifrão grosso"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Cartão de crédito"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Nota bancária com sinal de iene"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Nota bancária com sinal de dólar"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Nota bancária com sinal de euro"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Nota bancária com sinal de libra"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Dinheiro com asas"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Gráfico com tendência ascendente e símbolo de iene"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Assento"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Computador pessoal"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Valise"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Minidisco"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Disquete"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Disco óptico"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Pasta de arquivos"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Pasta de arquivos aberta"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Página com curva"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Página voltada para cima"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Calendário"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Calendário destacável"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Índice de cartões"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Gráfico com tendência ascendente"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Gráfico com tendência descendente"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Gráfico de barras"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Prancheta"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Alfinete"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Alfinete redondo"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Clipe de papel"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Régua reta"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Régua triangular"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"Guias de marca-página"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Livro-razão"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Bloco de anotações"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Bloco de anotações com capa decorativa"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Livro fechado"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Livro aberto"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Livro verde"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Livro azul"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Livro laranja"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Livros"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Crachá"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Pergaminho"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Memorando"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Telefone"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Pager"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Aparelho de fax"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Antena de satélite"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Alto-falante para discursos públicos"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Megafone em uso"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Bandeja da caixa de saída"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Bandeja da caixa de entrada"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Pacote"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"Símbolo de e-mail"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Envelope recebido"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Envelope com seta para baixo"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Caixa de correio fechada com bandeira abaixada"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Caixa de correio fechada com bandeira levantada"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Caixa de correio aberta com bandeira levantada"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Caixa de correio aberta com bandeira abaixada"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Caixa de correio"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Corneta de correio"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Jornal"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Celular"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Celular com seta para a direita"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Modo de vibração"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Celular desligado"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Proibido usar celular"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Antena com barras"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Câmera"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Filmadora"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Televisão"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Rádio"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Videocassete"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Setas entrelaçadas para a direita"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Setas para a esquerda e para a direita em sentido horário"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Setas para a esquerda e para a direita em sentido horário com \"1\""</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Setas para baixo e para cima em sentido horário"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Setas para baixo e para cima em sentido anti-horário"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Símbolo de baixo brilho"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Símbolo de alto brilho"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Alto-falante cortado"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Alto-falante"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Alto-falante com onda sonora"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Alto-falante com três ondas sonoras"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Bateria"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Tomada elétrica"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Lente de aumento virada para a esquerda"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Lente de aumento virada para a direita"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Cadeado com caneta-tinteiro"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Cadeado fechado com chave"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Chave"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Cadeado"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Cadeado aberto"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Sino"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Sino cortado"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Marca-página"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Símbolo de link"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Botão de opção"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"\"Back\" com seta para a esquerda"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"\"End\" com seta para a esquerda"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"\"On!\" com seta para a esquerda e para a direita"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"\"Soon\" com seta para a direita"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"\"Top\" com seta para cima"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"Símbolo de proibido para menores de 18"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Tecla do dez"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Símbolo de entrada de letras latinas maiúsculas"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Símbolo de entrada de letras latinas minúsculas"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Símbolo de entrada de números"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Símbolo de entrada de símbolos"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Símbolo de entrada de letras latinas"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Fogo"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Tocha elétrica"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Chave inglesa"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Martelo"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Porca e parafuso"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Facão"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Pistola"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Microscópio"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Telescópio"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Bola de cristal"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Estrela de seis pontas com ponto central"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Símbolo japonês para iniciante"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Emblema de tridente"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Botão quadrado preto"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Botão quadrado branco"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Círculo grande vermelho"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Círculo grande azul"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Losango grande laranja"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Losango grande azul"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Losango pequeno laranja"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Losango pequeno azul"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Triângulo vermelho apontando para cima"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Triângulo vermelho apontando para baixo"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Triângulo pequeno vermelho apontando para cima"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Triângulo pequeno vermelho apontando para baixo"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Relógio mostrando 01h00"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Relógio mostrando 02h00"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Relógio mostrando 03h00"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Relógio mostrando 04h00"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Relógio mostrando 05h00"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Relógio mostrando 06h00"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Relógio mostrando 07h00"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Relógio mostrando 08h00"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Relógio mostrando 09h00"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Relógio mostrando 10h00"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Relógio mostrando 11h00"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Relógio mostrando 12h00"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Relógio mostrando 01h30"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Relógio mostrando 02h30"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Relógio mostrando 03h30"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Relógio mostrando 04h30"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Relógio mostrando 05h30"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Relógio mostrando 06h30"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Relógio mostrando 07h30"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Relógio mostrando 08h30"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Relógio mostrando 09h30"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Relógio mostrando 10h30"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Relógio mostrando 11h30"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Relógio mostrando 12h30"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Monte Fuji"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Torre de Tóquio"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Estátua da Liberdade"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Silhueta do Japão"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Moai"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Rosto mostrando os dentes"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Rosto mostrando os dentes com olhos sorridentes"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Rosto com lágrimas de alegria"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Rosto sorridente com boca aberta"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Rosto sorridente com boca aberta e olhos sorridentes"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Rosto sorridente com boca aberta e suando frio"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Rosto sorridente com boca aberta e olhos bem fechados"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Rosto sorridente com auréola"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Rosto sorridente com chifres"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Rosto com olho piscando"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Rosto sorridente com olhos sorridentes"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Rosto saboreando comida deliciosa"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Rosto aliviado"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Rosto sorridente com olhos de coração"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Rosto sorridente com óculos de sol"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Rosto com meio sorriso"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Rosto neutro"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Rosto sem expressão"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Rosto de desinteressado"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Rosto suando frio"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Rosto pensativo"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Rosto confuso"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Rosto desconcertado"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Rosto beijando"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Rosto jogando beijo"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Rosto beijando com olhos sorridentes"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Rosto beijando com olhos fechados"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Rosto com língua de fora"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Rosto com língua de fora e piscando"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Rosto com língua de fora e olhos bem fechados"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Rosto de frustrado"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Rosto preocupado"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Rosto nervoso"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Rosto de desaprovação"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Rosto chorando"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Rosto de perseverante"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Rosto com aparência de triunfo"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Rosto com misto de decepção e alívio"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Rosto franzido com boca aberta"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Rosto angustiado"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Rosto temeroso"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Rosto fatigado"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Rosto sonolento"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Rosto cansado"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Rosto mostrando os dentes"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Rosto chorando alto"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Rosto com boca aberta"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Rosto silenciado"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Rosto com boca aberta e suando frio"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Rosto gritando de medo"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Rosto surpreso"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Rosto enrubescido"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Rosto dormindo"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Rosto tonto"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Rosto sem boca"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Rosto com máscara hospitalar"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Smiley de gato feliz com olhos sorridentes"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Smiley de gato com lágrimas de alegria"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Smiley de gato sorridente com boca aberta"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Smiley de gato sorridente com olhos de coração"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Smiley de gato com sorriso maroto"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Smiley de gato beijando com olhos fechados"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Smiley de gato de desaprovação"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Smiley de gato chorando"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Smiley de gato fatigado"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Smiley com gesto de reprovação"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Smiley com gesto de ok"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Pessoa curvando-se bastante"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Macaco cego"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Macaco surdo"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Macaco mudo"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Pessoa feliz levantando uma mão"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Pessoa levantando as mãos em comemoração"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Pessoa franzindo a testa"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Pessoa com rosto de desaprovação"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Pessoa com mãos unidas em oração"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Foguete"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Helicóptero"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Locomotiva a vapor"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Vagão"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Trem de alta velocidade"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Trem-bala de alta velocidade"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Trem"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metrô"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Metrô leve"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Estação"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Bonde"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Elétrico"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Ônibus"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Ônibus de frente"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Trólebus"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Ponto de ônibus"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Micro-ônibus"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulância"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Caminhão de bombeiros"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Viatura policial"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Viatura policial de frente"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Táxi"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Táxi de frente"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Automóvel"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Automóvel de frente"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Veículo recreativo"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Caminhão de entrega"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Caminhão articulado"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Trator"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Monotrilho"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Trem de montanha"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Trem suspenso"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Bondinho"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Teleférico"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Navio"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Barco a remo"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Lancha"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Semáforo horizontal"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Semáforo vertical"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Sinal de construção"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Giroflex de viaturas policiais"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Bandeira triangular em poste"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Porta"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Sinal de entrada proibida"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Símbolo de permitido fumar"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Símbolo de proibido fumar"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Símbolo de \"jogue o lixo no lixo\""</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Símbolo de proibido jogar lixo"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Símbolo de água potável"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Símbolo de água não potável"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Bicicleta"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Proibido bicicletas"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Ciclista"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Ciclista de montanha"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Pedestre"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Proibido pedestres"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Travessia de crianças"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Símbolo masculino"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Símbolo feminino"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Banheiro"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Símbolo de bebê"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Vaso sanitário"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"WC"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Chuveiro"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Banho"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Banheira"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Controle de passaportes"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Alfândega"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Esteira de bagagem"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Bagagem abandonada"</string>
+</resources>
diff --git a/java/res/values-pt/strings-talkback-descriptions.xml b/java/res/values-pt/strings-talkback-descriptions.xml
index 01aac3931..065cdaec6 100644
--- a/java/res/values-pt/strings-talkback-descriptions.xml
+++ b/java/res/values-pt/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nenhum texto digitado"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corrige <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> para <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> realiza correção automática"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Código de tecla %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift ativado (toque para desativar)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock ativado (toque para desativar)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Mais símbolos"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Símbolos"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Excluir"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Símbolos"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Letras"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Anterior"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift ativado"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock ativado"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift desativado"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Modo de símbolos"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modo mais símbolos"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Modo de letras"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Modo de telefone"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Modo de símbolos do telefone"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Lugares"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Símbolos"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticons"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-pt/strings.xml b/java/res/values-pt/strings.xml
index afee26d25..4d65ec86c 100644
--- a/java/res/values-pt/strings.xml
+++ b/java/res/values-pt/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opções de entrada"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Pesq. comandos de reg."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Buscar nomes de contatos"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"O corretor ortográfico usa entradas de sua lista de contatos"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrar ao tocar a tecla"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sugerir nomes de contato"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Usar nomes dos Contatos para sugestões e correções"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Sugestões personalizadas"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Duplo espaço para ponto"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Toque duplo na barra de espaço insere um ponto seguido de espaço"</string>
<string name="auto_cap" msgid="1719746674854628252">"Capitalização automática"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Idiomas de entrada"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para salvar"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentário do usuário"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Ajude a melhorar este editor de método de entrada enviando automaticamente estatísticas de uso e relatórios de falhas."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"inglês (Reino Unido)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"inglês (EUA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Ativar"</string>
<string name="not_now" msgid="6172462888202790482">"Agora não"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"O estilo de entrada já existe: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modo de estudo de utilização"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Atraso ao pressionar teclas"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Duração da vibração ao tocar"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume ao tocar na tela"</string>
diff --git a/java/res/values-rm/strings.xml b/java/res/values-rm/strings.xml
index 2ea98cf53..526ec73bd 100644
--- a/java/res/values-rm/strings.xml
+++ b/java/res/values-rm/strings.xml
@@ -22,7 +22,6 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- no translation found for english_ime_input_options (3909945612939668554) -->
<skip />
- <!-- no translation found for english_ime_research_log (8492602295696577851) -->
<skip />
<!-- no translation found for use_contacts_for_spellchecking_option_title (5374120998125353898) -->
<skip />
@@ -134,8 +133,6 @@
<!-- no translation found for hint_add_to_dictionary (573678656946085380) -->
<skip />
<string name="has_dictionary" msgid="6071847973466625007">"Dicziunari disponibel"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Activar il feedback da l\'utilisader"</string>
- <!-- no translation found for prefs_description_log (7525225584555429211) -->
<skip />
<!-- no translation found for keyboard_layout (8451164783510487501) -->
<skip />
@@ -191,7 +188,6 @@
<skip />
<!-- no translation found for custom_input_style_already_exists (8008728952215449707) -->
<skip />
- <!-- no translation found for prefs_usability_study_mode (1261130555134595254) -->
<skip />
<!-- no translation found for prefs_key_longpress_timeout_settings (6102240298932897873) -->
<skip />
diff --git a/java/res/values-ro/strings-action-keys.xml b/java/res/values-ro/strings-action-keys.xml
index 51aa82f9c..bee4b12ea 100644
--- a/java/res/values-ro/strings-action-keys.xml
+++ b/java/res/values-ro/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Înap."</string>
<string name="label_done_key" msgid="7564866296502630852">"Gata"</string>
<string name="label_send_key" msgid="482252074224462163">"Trim."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauză"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Așt."</string>
</resources>
diff --git a/java/res/values-ro/strings-emoji-descriptions.xml b/java/res/values-ro/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..f44a0b974
--- /dev/null
+++ b/java/res/values-ro/strings-emoji-descriptions.xml
@@ -0,0 +1,851 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+ -->
+
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="spoken_emoji_00A9" msgid="2859822817116803638">"Semnul Copyright"</string>
+ <string name="spoken_emoji_00AE" msgid="7708335454134589027">"Semnul Marcă înregistrată"</string>
+ <string name="spoken_emoji_203C" msgid="153340916701508663">"Semn de exclamare dublu"</string>
+ <string name="spoken_emoji_2049" msgid="4877256448299555371">"Semn de exclamare și întrebare"</string>
+ <string name="spoken_emoji_2122" msgid="9188440722954720429">"Semn marcă înregistrată"</string>
+ <string name="spoken_emoji_2139" msgid="9114342638917304327">"Sursă de informații"</string>
+ <string name="spoken_emoji_2194" msgid="8055202727034946680">"Săgeată stânga-dreapta"</string>
+ <string name="spoken_emoji_2195" msgid="8028122253301087407">"Săgeată sus-jos"</string>
+ <string name="spoken_emoji_2196" msgid="4019164898967854363">"Săgeată nord-vest"</string>
+ <string name="spoken_emoji_2197" msgid="4255723717709017801">"Săgeată nord-est"</string>
+ <string name="spoken_emoji_2198" msgid="1452063451313622090">"Săgeată sud-est"</string>
+ <string name="spoken_emoji_2199" msgid="6942722693368807849">"Săgeată sud-vest"</string>
+ <string name="spoken_emoji_21A9" msgid="5204750172335111188">"Săgeată încovoiată spre stânga"</string>
+ <string name="spoken_emoji_21AA" msgid="3950259884359247006">"Săgeată încovoiată spre dreapta"</string>
+ <string name="spoken_emoji_231A" msgid="6751448803233874993">"Ceas de mână"</string>
+ <string name="spoken_emoji_231B" msgid="5956428809948426182">"Clepsidră"</string>
+ <string name="spoken_emoji_23E9" msgid="4022497733535162237">"Triunghi dublu, negru, orientat spre dreapta"</string>
+ <string name="spoken_emoji_23EA" msgid="2251396938087774944">"Triunghi dublu, negru, orientat spre stânga"</string>
+ <string name="spoken_emoji_23EB" msgid="3746885195641491865">"Triunghi dublu, negru, orientat în sus"</string>
+ <string name="spoken_emoji_23EC" msgid="7852372752901163416">"Triunghi dublu, negru, orientat în jos"</string>
+ <string name="spoken_emoji_23F0" msgid="8474219588750627870">"Ceas deşteptător"</string>
+ <string name="spoken_emoji_23F3" msgid="166900119581024371">"Clepsidră cu nisip"</string>
+ <string name="spoken_emoji_24C2" msgid="3948348737566038470">"Majuscula „M”, din alfabetul latin, încercuită"</string>
+ <string name="spoken_emoji_25AA" msgid="7865181015100227349">"Pătrat mic negru"</string>
+ <string name="spoken_emoji_25AB" msgid="6446532820937381457">"Pătrat mic alb"</string>
+ <string name="spoken_emoji_25B6" msgid="2423897708496040947">"Triunghi negru, orientat spre dreapta"</string>
+ <string name="spoken_emoji_25C0" msgid="3595083440074484934">"Triunghi negru, orientat spre stânga"</string>
+ <string name="spoken_emoji_25FB" msgid="4838691986881215419">"Pătrat mediu alb"</string>
+ <string name="spoken_emoji_25FC" msgid="7008859564991191050">"Pătrat negru mediu"</string>
+ <string name="spoken_emoji_25FD" msgid="7673439755069217479">"Pătrat alb, mijlociu spre mic"</string>
+ <string name="spoken_emoji_25FE" msgid="6782214109919768923">"Pătrat negru, mijlociu spre mic"</string>
+ <string name="spoken_emoji_2600" msgid="2272722634618990413">"Soare negru cu raze"</string>
+ <string name="spoken_emoji_2601" msgid="6205136889311537150">"Nor"</string>
+ <string name="spoken_emoji_260E" msgid="8670395193046424238">"Telefon negru"</string>
+ <string name="spoken_emoji_2611" msgid="4530550203347054611">"Casetă cu bifă"</string>
+ <string name="spoken_emoji_2614" msgid="1612791247861229500">"Umbrelă cu picături de ploaie"</string>
+ <string name="spoken_emoji_2615" msgid="3320562382424018588">"Băuturi calde"</string>
+ <string name="spoken_emoji_261D" msgid="4690554173549768467">"Deget arătător alb, orientat în sus"</string>
+ <string name="spoken_emoji_263A" msgid="3170094381521989300">"Față zâmbitoare albă"</string>
+ <string name="spoken_emoji_2648" msgid="4621241062667020673">"Berbec"</string>
+ <string name="spoken_emoji_2649" msgid="7694461245947059086">"Taur"</string>
+ <string name="spoken_emoji_264A" msgid="1258074605878705030">"Gemeni"</string>
+ <string name="spoken_emoji_264B" msgid="4409219914377810956">"Rac"</string>
+ <string name="spoken_emoji_264C" msgid="6520255367817054163">"Leu"</string>
+ <string name="spoken_emoji_264D" msgid="1504758945499854018">"Fecioară"</string>
+ <string name="spoken_emoji_264E" msgid="2354847104530633519">"Balanţă"</string>
+ <string name="spoken_emoji_264F" msgid="5822933280406416112">"Scorpion"</string>
+ <string name="spoken_emoji_2650" msgid="4832481156714796163">"Săgetător"</string>
+ <string name="spoken_emoji_2651" msgid="840953134601595090">"Capricorn"</string>
+ <string name="spoken_emoji_2652" msgid="3586925968718775281">"Vărsător"</string>
+ <string name="spoken_emoji_2653" msgid="8420547731496254492">"Peşti"</string>
+ <string name="spoken_emoji_2660" msgid="4541170554542412536">"Pică neagră"</string>
+ <string name="spoken_emoji_2663" msgid="3669352721942285724">"Treflă neagră"</string>
+ <string name="spoken_emoji_2665" msgid="6347941599683765843">"Inimă neagra"</string>
+ <string name="spoken_emoji_2666" msgid="8296769213401115999">"Romb negru"</string>
+ <string name="spoken_emoji_2668" msgid="7063148281053820386">"Izvoare termale"</string>
+ <string name="spoken_emoji_267B" msgid="21716857176812762">"Simbol negru, universal, de reciclare"</string>
+ <string name="spoken_emoji_267F" msgid="8833496533226475443">"Simbol pentru scaun cu rotile"</string>
+ <string name="spoken_emoji_2693" msgid="7443148847598433088">"Ancoră"</string>
+ <string name="spoken_emoji_26A0" msgid="6272635532992727510">"Semn de avertizare"</string>
+ <string name="spoken_emoji_26A1" msgid="5604749644693339145">"Semn de înaltă tensiune"</string>
+ <string name="spoken_emoji_26AA" msgid="8005748091690377153">"Cerc alb mediu"</string>
+ <string name="spoken_emoji_26AB" msgid="1655910278422753244">"Cerc negru mediu"</string>
+ <string name="spoken_emoji_26BD" msgid="1545218197938889737">"Minge de fotbal"</string>
+ <string name="spoken_emoji_26BE" msgid="8959760533076498209">"Minge de baseball"</string>
+ <string name="spoken_emoji_26C4" msgid="3045791757044255626">"Om de zăpadă fără zăpadă"</string>
+ <string name="spoken_emoji_26C5" msgid="5580129409712578639">"Soare în spatele unui nor"</string>
+ <string name="spoken_emoji_26CE" msgid="8963656417276062998">"Ophiuchus"</string>
+ <string name="spoken_emoji_26D4" msgid="2231451988209604130">"Intrarea interzisă"</string>
+ <string name="spoken_emoji_26EA" msgid="7513319636103804907">"Biserică"</string>
+ <string name="spoken_emoji_26F2" msgid="7134115206158891037">"Fântână"</string>
+ <string name="spoken_emoji_26F3" msgid="4912302210162075465">"Steag în gaură"</string>
+ <string name="spoken_emoji_26F5" msgid="4766328116769075217">"Barcă cu pânze"</string>
+ <string name="spoken_emoji_26FA" msgid="5888017494809199037">"Cort"</string>
+ <string name="spoken_emoji_26FD" msgid="2417060622927453534">"Pompă de combustibil"</string>
+ <string name="spoken_emoji_2702" msgid="4005741160717451912">"Foarfece negru"</string>
+ <string name="spoken_emoji_2705" msgid="164605766946697759">"Bifă albă îngroșată"</string>
+ <string name="spoken_emoji_2708" msgid="7153840886849268988">"Avion"</string>
+ <string name="spoken_emoji_2709" msgid="2217319160724311369">"Plic"</string>
+ <string name="spoken_emoji_270A" msgid="508347232762319473">"Pumn ridicat"</string>
+ <string name="spoken_emoji_270B" msgid="6640562128327753423">"Mână ridicată"</string>
+ <string name="spoken_emoji_270C" msgid="1344288035704944581">"Mână cu semnul victoriei"</string>
+ <string name="spoken_emoji_270F" msgid="6108251586067318718">"Creion"</string>
+ <string name="spoken_emoji_2712" msgid="6320544535087710482">"Peniță neagră"</string>
+ <string name="spoken_emoji_2714" msgid="1968242800064001654">"Bifă îngroșată"</string>
+ <string name="spoken_emoji_2716" msgid="511941294762977228">"Înmulțire complexă x"</string>
+ <string name="spoken_emoji_2728" msgid="5650330815808691881">"Scântei"</string>
+ <string name="spoken_emoji_2733" msgid="8915809595141157327">"Asterisc cu opt colțuri"</string>
+ <string name="spoken_emoji_2734" msgid="4846583547980754332">"Stea neagră, cu opt colțuri"</string>
+ <string name="spoken_emoji_2744" msgid="4350636647760161042">"Fulg de nea"</string>
+ <string name="spoken_emoji_2747" msgid="3718282973916474455">"Scânteie"</string>
+ <string name="spoken_emoji_274C" msgid="2752145886733295314">"Semn x"</string>
+ <string name="spoken_emoji_274E" msgid="4262918689871098338">"Semn x alb pe fond negru în pătrat"</string>
+ <string name="spoken_emoji_2753" msgid="6935897159942119808">"Semn de întrebare ornamental negru"</string>
+ <string name="spoken_emoji_2754" msgid="7277504915105532954">"Semn de întrebare ornamental alb"</string>
+ <string name="spoken_emoji_2755" msgid="6853076969826960210">"Semn de exclamare ornamental alb"</string>
+ <string name="spoken_emoji_2757" msgid="3707907828776912174">"Semn de exclamare îngroșat"</string>
+ <string name="spoken_emoji_2764" msgid="4214257843609432167">"Inimă neagră îngroșată"</string>
+ <string name="spoken_emoji_2795" msgid="6563954833786162168">"Semn plus îngroșat"</string>
+ <string name="spoken_emoji_2796" msgid="5990926508250772777">"Semn minus îngroșat"</string>
+ <string name="spoken_emoji_2797" msgid="24694184172879174">"Semn de împărțire îngroșat"</string>
+ <string name="spoken_emoji_27A1" msgid="3513434778263100580">"Săgeată neagră, spre dreapta"</string>
+ <string name="spoken_emoji_27B0" msgid="203395646864662198">"Buclă ondulată"</string>
+ <string name="spoken_emoji_27BF" msgid="4940514642375640510">"Buclă ondulată dublă"</string>
+ <string name="spoken_emoji_2934" msgid="9062130477982973457">"Săgeată orientată spre dreapta, apoi curbată în sus"</string>
+ <string name="spoken_emoji_2935" msgid="6198710960720232074">"Săgeată orientată spre dreapta, apoi curbată în jos"</string>
+ <string name="spoken_emoji_2B05" msgid="4813405635410707690">"Săgeată neagră orientată spre stânga"</string>
+ <string name="spoken_emoji_2B06" msgid="1223172079106250748">"Săgeată neagră orientată în sus"</string>
+ <string name="spoken_emoji_2B07" msgid="1599124424746596150">"Săgeată neagră orientată în jos"</string>
+ <string name="spoken_emoji_2B1B" msgid="3461247311988501626">"Pătrat negru mare"</string>
+ <string name="spoken_emoji_2B1C" msgid="5793146430145248915">"Pătrat alb mare"</string>
+ <string name="spoken_emoji_2B50" msgid="3850845519526950524">"Stea albă medie"</string>
+ <string name="spoken_emoji_2B55" msgid="9137882158811541824">"Cerc îngroșat, mare"</string>
+ <string name="spoken_emoji_3030" msgid="4609172241893565639">"Liniuță ondulată"</string>
+ <string name="spoken_emoji_303D" msgid="2545833934975907505">"Semn de modificare"</string>
+ <string name="spoken_emoji_3297" msgid="928912923628973800">"Ideogramă încercuită - felicitări"</string>
+ <string name="spoken_emoji_3299" msgid="3930347573693668426">"Ideogramă încercuită - secret"</string>
+ <string name="spoken_emoji_1F004" msgid="1705216181345894600">"Piesă Mahjong dragon roșu"</string>
+ <string name="spoken_emoji_1F0CF" msgid="7601493592085987866">"Carte de joc joker negru"</string>
+ <string name="spoken_emoji_1F170" msgid="3817698686602826773">"Grupa de sânge A"</string>
+ <string name="spoken_emoji_1F171" msgid="3684218589626650242">"Grupa de sânge B"</string>
+ <string name="spoken_emoji_1F17E" msgid="2978809190364779029">"Grupa de sânge O"</string>
+ <string name="spoken_emoji_1F17F" msgid="463634348668462040">"Parcare"</string>
+ <string name="spoken_emoji_1F18E" msgid="1650705325221496768">"Grupa de sânge AB"</string>
+ <string name="spoken_emoji_1F191" msgid="5386969264431429221">"„CL” în pătrat"</string>
+ <string name="spoken_emoji_1F192" msgid="8324226436829162496">"„COOL” în pătrat"</string>
+ <string name="spoken_emoji_1F193" msgid="4731758603321515364">"„FREE” în pătrat"</string>
+ <string name="spoken_emoji_1F194" msgid="4903128609556175887">"„ID” în pătrat"</string>
+ <string name="spoken_emoji_1F195" msgid="1433142500411060924">"„NEW” în pătrat"</string>
+ <string name="spoken_emoji_1F196" msgid="8825160701159634202">"„N G” în pătrat"</string>
+ <string name="spoken_emoji_1F197" msgid="7841079241554176535">"„OK” în pătrat"</string>
+ <string name="spoken_emoji_1F198" msgid="7020298909426960622">"„SOS” în pătrat"</string>
+ <string name="spoken_emoji_1F199" msgid="5971252667136235630">"„UP” cu semn de exclamare în pătrat"</string>
+ <string name="spoken_emoji_1F19A" msgid="4557270135899843959">"„VS” în pătrat"</string>
+ <string name="spoken_emoji_1F201" msgid="7000490044681139002">"„Katakana” în pătrat"</string>
+ <string name="spoken_emoji_1F202" msgid="8560906958695043947">"„Servicii Katakana” în pătrat"</string>
+ <string name="spoken_emoji_1F21A" msgid="1496435317324514033">"Caracter ideografic „Gratuit” în pătrat"</string>
+ <string name="spoken_emoji_1F22F" msgid="609797148862445402">"Caracter ideografic „Loc rezervat” în pătrat"</string>
+ <string name="spoken_emoji_1F232" msgid="8125716331632035820">"Caracter ideografic „Interzis” în pătrat"</string>
+ <string name="spoken_emoji_1F233" msgid="8749401090457355028">"Caracter ideografic „Loc liber” în pătrat"</string>
+ <string name="spoken_emoji_1F234" msgid="3546951604285970768">"Caracter ideografic „Aprobare” în pătrat"</string>
+ <string name="spoken_emoji_1F235" msgid="5320186982841793711">"Caracter ideografic „Nu sunt locuri libere” în pătrat"</string>
+ <string name="spoken_emoji_1F236" msgid="879755752069393034">"Caracter ideografic „Cu plată” în pătrat"</string>
+ <string name="spoken_emoji_1F237" msgid="6741807001205851437">"Caracter ideografic „Lunar” în pătrat"</string>
+ <string name="spoken_emoji_1F238" msgid="5504414186438196912">"Caracter ideografic „Înscriere” în pătrat"</string>
+ <string name="spoken_emoji_1F239" msgid="1634067311597618959">"Caracter ideografic „Reducere” în pătrat"</string>
+ <string name="spoken_emoji_1F23A" msgid="3107862957630169536">"Caracter ideografic „În activitate” în pătrat"</string>
+ <string name="spoken_emoji_1F250" msgid="6586943922806727907">"Caracter ideografic „Avantaj” în pătrat"</string>
+ <string name="spoken_emoji_1F251" msgid="9099032855993346948">"Caracter ideografic „Acord” în pătrat"</string>
+ <string name="spoken_emoji_1F300" msgid="4720098285295840383">"Ciclon"</string>
+ <string name="spoken_emoji_1F301" msgid="3601962477653752974">"Ceaţă"</string>
+ <string name="spoken_emoji_1F302" msgid="3404357123421753593">"Umbrelă închisă"</string>
+ <string name="spoken_emoji_1F303" msgid="3899301321538188206">"Noapte cu stele"</string>
+ <string name="spoken_emoji_1F304" msgid="2767148930689050040">"Răsărit peste munți"</string>
+ <string name="spoken_emoji_1F305" msgid="9165812924292061196">"Răsărit"</string>
+ <string name="spoken_emoji_1F306" msgid="5889294736109193104">"Peisaj urban la asfințit"</string>
+ <string name="spoken_emoji_1F307" msgid="2714290867291163713">"Apus de soare deasupra clădirilor"</string>
+ <string name="spoken_emoji_1F308" msgid="688704703985173377">"Curcubeu"</string>
+ <string name="spoken_emoji_1F309" msgid="6217981957992313528">"Pod noaptea"</string>
+ <string name="spoken_emoji_1F30A" msgid="4329309263152110893">"Val"</string>
+ <string name="spoken_emoji_1F30B" msgid="5729430693700923112">"Vulcan"</string>
+ <string name="spoken_emoji_1F30C" msgid="2961230863217543082">"Calea Lactee"</string>
+ <string name="spoken_emoji_1F30D" msgid="1113905673331547953">"Globul pământesc: Europa-Africa"</string>
+ <string name="spoken_emoji_1F30E" msgid="5278512600749223671">"Globul pământesc: continentul american"</string>
+ <string name="spoken_emoji_1F30F" msgid="5718144880978707493">"Globul pământesc: Asia-Australia"</string>
+ <string name="spoken_emoji_1F310" msgid="2959618582975247601">"Glob pământesc cu meridiane"</string>
+ <string name="spoken_emoji_1F311" msgid="623906380914895542">"Simbolul Lună nouă"</string>
+ <string name="spoken_emoji_1F312" msgid="4458575672576125401">"Simbolul Lună nouă"</string>
+ <string name="spoken_emoji_1F313" msgid="7599181787989497294">"Simbolul Primul pătrar"</string>
+ <string name="spoken_emoji_1F314" msgid="4898293184964365413">"Simbolul Înainte de lună plină"</string>
+ <string name="spoken_emoji_1F315" msgid="3218117051779496309">"Simbolul Lună plină"</string>
+ <string name="spoken_emoji_1F316" msgid="2061317145777689569">"Simbolul După lună plină"</string>
+ <string name="spoken_emoji_1F317" msgid="2721090687319539049">"Simbolul Ultimul pătrar"</string>
+ <string name="spoken_emoji_1F318" msgid="3814091755648887570">"Simbolul Înainte de lună nouă"</string>
+ <string name="spoken_emoji_1F319" msgid="4074299824890459465">"Semilună"</string>
+ <string name="spoken_emoji_1F31A" msgid="3092285278116977103">"Lună nouă, cu chip"</string>
+ <string name="spoken_emoji_1F31B" msgid="2658562138386927881">"Lună în primul pătrar, cu chip"</string>
+ <string name="spoken_emoji_1F31C" msgid="7914768515547867384">"Lună în ultimul pătrar, cu chip"</string>
+ <string name="spoken_emoji_1F31D" msgid="1925730459848297182">"Lună plină, cu chip"</string>
+ <string name="spoken_emoji_1F31E" msgid="8022112382524084418">"Soare cu chip"</string>
+ <string name="spoken_emoji_1F31F" msgid="1051661214137766369">"Stea strălucitoare"</string>
+ <string name="spoken_emoji_1F320" msgid="5450591979068216115">"Stea căzătoare"</string>
+ <string name="spoken_emoji_1F330" msgid="3115760035618051575">"Castană"</string>
+ <string name="spoken_emoji_1F331" msgid="5658888205290008691">"Puiet"</string>
+ <string name="spoken_emoji_1F332" msgid="2935650450421165938">"Copac veșnic verde"</string>
+ <string name="spoken_emoji_1F333" msgid="5898847427062482675">"Copac cu frunze căzătoare"</string>
+ <string name="spoken_emoji_1F334" msgid="6183375224678417894">"Palmier"</string>
+ <string name="spoken_emoji_1F335" msgid="5352418412103584941">"Cactus"</string>
+ <string name="spoken_emoji_1F337" msgid="3839107352363566289">"Lalea"</string>
+ <string name="spoken_emoji_1F338" msgid="6389970364260468490">"Floare de cireș"</string>
+ <string name="spoken_emoji_1F339" msgid="9128891447985256151">"Trandafir"</string>
+ <string name="spoken_emoji_1F33A" msgid="2025828400095233078">"Hibiscus"</string>
+ <string name="spoken_emoji_1F33B" msgid="8163868254348448552">"Floarea-soarelui"</string>
+ <string name="spoken_emoji_1F33C" msgid="6850371206262335812">"Floare"</string>
+ <string name="spoken_emoji_1F33D" msgid="9033484052864509610">"Spic de porumb"</string>
+ <string name="spoken_emoji_1F33E" msgid="2540173396638444120">"Spic de orez"</string>
+ <string name="spoken_emoji_1F33F" msgid="4384823344364908558">"Plantă"</string>
+ <string name="spoken_emoji_1F340" msgid="3494255459156499305">"Trifoi cu patru foi"</string>
+ <string name="spoken_emoji_1F341" msgid="4581959481754990158">"Frunză de arțar"</string>
+ <string name="spoken_emoji_1F342" msgid="3119068426871821222">"Frunză căzută"</string>
+ <string name="spoken_emoji_1F343" msgid="2663317495805149004">"Frunză în vânt"</string>
+ <string name="spoken_emoji_1F344" msgid="2738517881678722159">"Ciupercă"</string>
+ <string name="spoken_emoji_1F345" msgid="6135288642349085554">"Roșie"</string>
+ <string name="spoken_emoji_1F346" msgid="2075395322785406367">"Vânătă"</string>
+ <string name="spoken_emoji_1F347" msgid="7753453754963890571">"Struguri"</string>
+ <string name="spoken_emoji_1F348" msgid="1247076837284932788">"Pepene galben"</string>
+ <string name="spoken_emoji_1F349" msgid="5563054555180611086">"Pepene verde"</string>
+ <string name="spoken_emoji_1F34A" msgid="4688661208570160524">"Mandarină"</string>
+ <string name="spoken_emoji_1F34B" msgid="4335318423164185706">"Lămâie"</string>
+ <string name="spoken_emoji_1F34C" msgid="3712827239858159474">"Banană"</string>
+ <string name="spoken_emoji_1F34D" msgid="7712521967162622936">"Ananas"</string>
+ <string name="spoken_emoji_1F34E" msgid="1859466882598614228">"Măr roșu"</string>
+ <string name="spoken_emoji_1F34F" msgid="8251711032295005633">"Măr verde"</string>
+ <string name="spoken_emoji_1F350" msgid="625802980159197701">"Pară"</string>
+ <string name="spoken_emoji_1F351" msgid="4269460120610911895">"Piersic"</string>
+ <string name="spoken_emoji_1F352" msgid="965600953360182635">"Cireșe"</string>
+ <string name="spoken_emoji_1F353" msgid="7068623879906925592">"Căpșună"</string>
+ <string name="spoken_emoji_1F354" msgid="45162285238888494">"Hamburger"</string>
+ <string name="spoken_emoji_1F355" msgid="9157587635526433283">"Felie de pizza"</string>
+ <string name="spoken_emoji_1F356" msgid="2667196119149852244">"Carne pe os"</string>
+ <string name="spoken_emoji_1F357" msgid="8022817413851052256">"Picior de pasăre"</string>
+ <string name="spoken_emoji_1F358" msgid="3042693264748036476">"Biscuite de orez"</string>
+ <string name="spoken_emoji_1F359" msgid="3988148661730121958">"Chiftea de orez"</string>
+ <string name="spoken_emoji_1F35A" msgid="1763824172198327268">"Orez gătit"</string>
+ <string name="spoken_emoji_1F35B" msgid="62530406745717835">"Orez cu curry"</string>
+ <string name="spoken_emoji_1F35C" msgid="7537756539198945509">"Castron aburind"</string>
+ <string name="spoken_emoji_1F35D" msgid="8173523083861875196">"Spaghete"</string>
+ <string name="spoken_emoji_1F35E" msgid="2935428307894662571">"Pâine"</string>
+ <string name="spoken_emoji_1F35F" msgid="4840297386785728443">"Cartofi prăjiți"</string>
+ <string name="spoken_emoji_1F360" msgid="4094659855684686801">"Cartof dulce copt"</string>
+ <string name="spoken_emoji_1F361" msgid="6475486395784096109">"Dango"</string>
+ <string name="spoken_emoji_1F362" msgid="5004692577661076275">"Oden"</string>
+ <string name="spoken_emoji_1F363" msgid="1606603765717743806">"Sushi"</string>
+ <string name="spoken_emoji_1F364" msgid="6550457766169570811">"Creveți prăjiți"</string>
+ <string name="spoken_emoji_1F365" msgid="4963815540953316307">"Plăcintă de pește cu model ondulat"</string>
+ <string name="spoken_emoji_1F366" msgid="7862401745277049404">"Cornet de înghețată"</string>
+ <string name="spoken_emoji_1F367" msgid="7447972978281980414">"Fulgi de gheață"</string>
+ <string name="spoken_emoji_1F368" msgid="7790003146142724913">"Înghețată"</string>
+ <string name="spoken_emoji_1F369" msgid="7383712944084857350">"Gogoașă"</string>
+ <string name="spoken_emoji_1F36A" msgid="2726271795913042295">"Biscuit"</string>
+ <string name="spoken_emoji_1F36B" msgid="6342163604299875931">"Ciocolată"</string>
+ <string name="spoken_emoji_1F36C" msgid="2168934753998218790">"Bomboane"</string>
+ <string name="spoken_emoji_1F36D" msgid="3671507903799975792">"Acadea"</string>
+ <string name="spoken_emoji_1F36E" msgid="4630541402785165902">"Budincă"</string>
+ <string name="spoken_emoji_1F36F" msgid="5577915387425169439">"Oală de miere"</string>
+ <string name="spoken_emoji_1F370" msgid="7243244547866114951">"Prăjitură"</string>
+ <string name="spoken_emoji_1F371" msgid="6731527040552916358">"Cutie Bento"</string>
+ <string name="spoken_emoji_1F372" msgid="1635035323832181733">"Oală cu mâncare"</string>
+ <string name="spoken_emoji_1F373" msgid="7799289534289221045">"Gătit"</string>
+ <string name="spoken_emoji_1F374" msgid="5973820884987069131">"Furculiță și cuțit"</string>
+ <string name="spoken_emoji_1F375" msgid="1074832087699617700">"Ceașcă fără toartă"</string>
+ <string name="spoken_emoji_1F376" msgid="6499274685584852067">"Sticlă și ceașcă de sake"</string>
+ <string name="spoken_emoji_1F377" msgid="1762398562314172075">"Pahar de vin"</string>
+ <string name="spoken_emoji_1F378" msgid="5528234560590117516">"Pahar de cocktail"</string>
+ <string name="spoken_emoji_1F379" msgid="790581290787943325">"Băutură tropicală"</string>
+ <string name="spoken_emoji_1F37A" msgid="391966822450619516">"Halbă de bere"</string>
+ <string name="spoken_emoji_1F37B" msgid="9015043286465670662">"Halbe de bere ciocnindu-se"</string>
+ <string name="spoken_emoji_1F37C" msgid="2532113819464508894">"Biberon"</string>
+ <string name="spoken_emoji_1F380" msgid="3487363857092458827">"Panglică"</string>
+ <string name="spoken_emoji_1F381" msgid="614180683680675444">"Cadou ambalat"</string>
+ <string name="spoken_emoji_1F382" msgid="4720497171946687501">"Tort"</string>
+ <string name="spoken_emoji_1F383" msgid="3536505941578757623">"Felinar din dovleac"</string>
+ <string name="spoken_emoji_1F384" msgid="1797870204479059004">"Pom de Crăciun"</string>
+ <string name="spoken_emoji_1F385" msgid="1754174063483626367">"Moș Crăciun"</string>
+ <string name="spoken_emoji_1F386" msgid="2130445450758114746">"Focuri de artificii"</string>
+ <string name="spoken_emoji_1F387" msgid="3403182563117999933">"Artificiu"</string>
+ <string name="spoken_emoji_1F388" msgid="2903047203723251804">"Balon"</string>
+ <string name="spoken_emoji_1F389" msgid="2352830665883549388">"Tun de confetti"</string>
+ <string name="spoken_emoji_1F38A" msgid="6280428984773641322">"Minge de confetti"</string>
+ <string name="spoken_emoji_1F38B" msgid="4902225837479015489">"Copac Tanabata"</string>
+ <string name="spoken_emoji_1F38C" msgid="7623268024030989365">"Steaguri încrucișate"</string>
+ <string name="spoken_emoji_1F38D" msgid="8237542796124408528">"Decorațiune de Crăciun"</string>
+ <string name="spoken_emoji_1F38E" msgid="5373397476238212371">"Păpuși japoneze"</string>
+ <string name="spoken_emoji_1F38F" msgid="8754091376829552844">"Steaguri în formă de pește"</string>
+ <string name="spoken_emoji_1F390" msgid="8903307048095431374">"Clopoței de vânt"</string>
+ <string name="spoken_emoji_1F391" msgid="2134952069191911841">"Ceremonia contemplării lunii"</string>
+ <string name="spoken_emoji_1F392" msgid="6380405493914304737">"Ghiozdan"</string>
+ <string name="spoken_emoji_1F393" msgid="6947890064872470996">"Tocă de absolvire"</string>
+ <string name="spoken_emoji_1F3A0" msgid="3572095190082826057">"Cal de carusel"</string>
+ <string name="spoken_emoji_1F3A1" msgid="4300565511681058798">"Roata mare"</string>
+ <string name="spoken_emoji_1F3A2" msgid="15486093912232140">"Montaigne-russe"</string>
+ <string name="spoken_emoji_1F3A3" msgid="921739319504942924">"Undiță și pește"</string>
+ <string name="spoken_emoji_1F3A4" msgid="7497596355346856950">"Microfon"</string>
+ <string name="spoken_emoji_1F3A5" msgid="4290497821228183002">"Cameră video"</string>
+ <string name="spoken_emoji_1F3A6" msgid="26019057872319055">"Cinema"</string>
+ <string name="spoken_emoji_1F3A7" msgid="837856608794094105">"Căști"</string>
+ <string name="spoken_emoji_1F3A8" msgid="2332260356509244587">"Paletă de pictură"</string>
+ <string name="spoken_emoji_1F3A9" msgid="9045869366525115256">"Joben"</string>
+ <string name="spoken_emoji_1F3AA" msgid="5728760354237132">"Cort de circ"</string>
+ <string name="spoken_emoji_1F3AB" msgid="1657997517193216284">"Bilet"</string>
+ <string name="spoken_emoji_1F3AC" msgid="4317366554314492152">"Clachetă"</string>
+ <string name="spoken_emoji_1F3AD" msgid="607157286336130470">"Arta spectacolului"</string>
+ <string name="spoken_emoji_1F3AE" msgid="2902308174671548150">"Joc video"</string>
+ <string name="spoken_emoji_1F3AF" msgid="5420539221790296407">"Lovitură drept la țintă"</string>
+ <string name="spoken_emoji_1F3B0" msgid="7440244806527891956">"Jocuri mecanice"</string>
+ <string name="spoken_emoji_1F3B1" msgid="545544382391379234">"Biliard"</string>
+ <string name="spoken_emoji_1F3B2" msgid="8302262034774787493">"Zaruri"</string>
+ <string name="spoken_emoji_1F3B3" msgid="5180870610771027520">"Popice"</string>
+ <string name="spoken_emoji_1F3B4" msgid="4723852033266071564">"Cărți de joc cu flori"</string>
+ <string name="spoken_emoji_1F3B5" msgid="1998470239850548554">"Notă muzicală"</string>
+ <string name="spoken_emoji_1F3B6" msgid="3827730457113941705">"Mai multe note muzicale"</string>
+ <string name="spoken_emoji_1F3B7" msgid="5503403099445042180">"Saxofon"</string>
+ <string name="spoken_emoji_1F3B8" msgid="3985658156795011430">"Chitară"</string>
+ <string name="spoken_emoji_1F3B9" msgid="5596295757967881451">"Claviatură"</string>
+ <string name="spoken_emoji_1F3BA" msgid="4284064120340683558">"Trompetă"</string>
+ <string name="spoken_emoji_1F3BB" msgid="2856598510069988745">"Vioară"</string>
+ <string name="spoken_emoji_1F3BC" msgid="1608424748821446230">"Partitură"</string>
+ <string name="spoken_emoji_1F3BD" msgid="5490786111375627777">"Maieu de sport cu dungă"</string>
+ <string name="spoken_emoji_1F3BE" msgid="1851613105691627931">"Rachetă de tenis și minge"</string>
+ <string name="spoken_emoji_1F3BF" msgid="6862405997423247921">"Schi și gheată de schi"</string>
+ <string name="spoken_emoji_1F3C0" msgid="7421420756115104085">"Minge și inel de baschet"</string>
+ <string name="spoken_emoji_1F3C1" msgid="6926537251677319922">"Steag în carouri"</string>
+ <string name="spoken_emoji_1F3C2" msgid="5708596929237987082">"Practicant de snowboard"</string>
+ <string name="spoken_emoji_1F3C3" msgid="5850982999510115824">"Alergător"</string>
+ <string name="spoken_emoji_1F3C4" msgid="8468355585994639838">"Practicant de surf"</string>
+ <string name="spoken_emoji_1F3C6" msgid="9094474706847545409">"Trofeu"</string>
+ <string name="spoken_emoji_1F3C7" msgid="8172206200368370116">"Curse de cai"</string>
+ <string name="spoken_emoji_1F3C8" msgid="5619171461277597709">"Fotbal american"</string>
+ <string name="spoken_emoji_1F3C9" msgid="6371294008765871043">"Rugby"</string>
+ <string name="spoken_emoji_1F3CA" msgid="130977831787806932">"Înnotător"</string>
+ <string name="spoken_emoji_1F3E0" msgid="6277213201655811842">"Clădire"</string>
+ <string name="spoken_emoji_1F3E1" msgid="233476176077538885">"Casă cu grădină"</string>
+ <string name="spoken_emoji_1F3E2" msgid="919736380093964570">"Clădire de birouri"</string>
+ <string name="spoken_emoji_1F3E3" msgid="6177606081825094184">"Oficiu poștal japonez"</string>
+ <string name="spoken_emoji_1F3E4" msgid="717377871070970293">"Oficiu poștal european"</string>
+ <string name="spoken_emoji_1F3E5" msgid="1350532500431776780">"Spital"</string>
+ <string name="spoken_emoji_1F3E6" msgid="342132788513806214">"Bancă"</string>
+ <string name="spoken_emoji_1F3E7" msgid="6322352038284944265">"Bancomat"</string>
+ <string name="spoken_emoji_1F3E8" msgid="5864918444350599907">"Hotel"</string>
+ <string name="spoken_emoji_1F3E9" msgid="7830416185375326938">"Hoteluri pentru îndrăgostiți"</string>
+ <string name="spoken_emoji_1F3EA" msgid="5081084413084360479">"Alimentară"</string>
+ <string name="spoken_emoji_1F3EB" msgid="7010966528205150525">"Şcoală"</string>
+ <string name="spoken_emoji_1F3EC" msgid="4845978861878295154">"Magazin universal"</string>
+ <string name="spoken_emoji_1F3ED" msgid="3980316226665215370">"Fabrică"</string>
+ <string name="spoken_emoji_1F3EE" msgid="1253964276770550248">"Felinar Izakaya"</string>
+ <string name="spoken_emoji_1F3EF" msgid="1128975573507389883">"Castel japonez"</string>
+ <string name="spoken_emoji_1F3F0" msgid="1544632297502291578">"Castel european"</string>
+ <string name="spoken_emoji_1F400" msgid="2063034795679578294">"Șobolan"</string>
+ <string name="spoken_emoji_1F401" msgid="6736421616217369594">"Șoarece"</string>
+ <string name="spoken_emoji_1F402" msgid="7276670995895485604">"Bou"</string>
+ <string name="spoken_emoji_1F403" msgid="8045709541897118928">"Bivol de apă"</string>
+ <string name="spoken_emoji_1F404" msgid="5240777285676662335">"Vacă"</string>
+ <string name="spoken_emoji_1F406" msgid="5163461930159540018">"Leopard"</string>
+ <string name="spoken_emoji_1F407" msgid="6905370221172708160">"Iepure"</string>
+ <string name="spoken_emoji_1F408" msgid="1362164550508207284">"Pisică"</string>
+ <string name="spoken_emoji_1F409" msgid="8476130983168866013">"Dragon"</string>
+ <string name="spoken_emoji_1F40A" msgid="1149626786411545043">"Crocodil"</string>
+ <string name="spoken_emoji_1F40B" msgid="5199104921208397643">"Balenă"</string>
+ <string name="spoken_emoji_1F40C" msgid="2704006052881702675">"Melc"</string>
+ <string name="spoken_emoji_1F40D" msgid="8648186663643157522">"Șarpe"</string>
+ <string name="spoken_emoji_1F40E" msgid="7219137467573327268">"Cal"</string>
+ <string name="spoken_emoji_1F40F" msgid="7834336676729040395">"Berbec"</string>
+ <string name="spoken_emoji_1F410" msgid="8686765722255775031">"Capră"</string>
+ <string name="spoken_emoji_1F411" msgid="3585715397876383525">"Oaie"</string>
+ <string name="spoken_emoji_1F412" msgid="4924794582980077838">"Maimuţă"</string>
+ <string name="spoken_emoji_1F413" msgid="1460475310405677377">"Cocoș"</string>
+ <string name="spoken_emoji_1F414" msgid="5857296282631892219">"Pui"</string>
+ <string name="spoken_emoji_1F415" msgid="5920041074892949527">"Câine"</string>
+ <string name="spoken_emoji_1F416" msgid="4362403392912540286">"Porc"</string>
+ <string name="spoken_emoji_1F417" msgid="6836978415840795128">"Porc mistreț"</string>
+ <string name="spoken_emoji_1F418" msgid="7926161463897783691">"Elefant"</string>
+ <string name="spoken_emoji_1F419" msgid="1055233959755784186">"Caracatiță"</string>
+ <string name="spoken_emoji_1F41A" msgid="5195666556511558060">"Scoică spiralată"</string>
+ <string name="spoken_emoji_1F41B" msgid="7652480167465557832">"Insectă"</string>
+ <string name="spoken_emoji_1F41C" msgid="1123461148697574239">"Furnică"</string>
+ <string name="spoken_emoji_1F41D" msgid="718579308764058851">"Albină"</string>
+ <string name="spoken_emoji_1F41E" msgid="6766305509608115467">"Buburuză"</string>
+ <string name="spoken_emoji_1F41F" msgid="1207261298343160838">"Pești"</string>
+ <string name="spoken_emoji_1F420" msgid="1041145003133609221">"Pești tropicali"</string>
+ <string name="spoken_emoji_1F421" msgid="1748378324417438751">"Pește lună"</string>
+ <string name="spoken_emoji_1F422" msgid="4106724877523329148">"Broască țestoasă"</string>
+ <string name="spoken_emoji_1F423" msgid="4077407945958691907">"Pui ieșind din ou"</string>
+ <string name="spoken_emoji_1F424" msgid="6911326019270172283">"Pui de găină"</string>
+ <string name="spoken_emoji_1F425" msgid="5466514196557885577">"Pui văzut din față"</string>
+ <string name="spoken_emoji_1F426" msgid="2163979138772892755">"Pasăre"</string>
+ <string name="spoken_emoji_1F427" msgid="3585670324511212961">"Pinguin"</string>
+ <string name="spoken_emoji_1F428" msgid="7955440808647898579">"Urs koala"</string>
+ <string name="spoken_emoji_1F429" msgid="5028269352809819035">"Pudel"</string>
+ <string name="spoken_emoji_1F42A" msgid="4681926706404032484">"Dromader"</string>
+ <string name="spoken_emoji_1F42B" msgid="2725166074981558322">"Cămilă cu două cocoașe"</string>
+ <string name="spoken_emoji_1F42C" msgid="6764791873413727085">"Delfin"</string>
+ <string name="spoken_emoji_1F42D" msgid="1033643138546864251">"Cap de șoarece"</string>
+ <string name="spoken_emoji_1F42E" msgid="8099223337120508820">"Cap de vacă"</string>
+ <string name="spoken_emoji_1F42F" msgid="2104743989330781572">"Cap de tigru"</string>
+ <string name="spoken_emoji_1F430" msgid="525492897063150160">"Cap de iepure"</string>
+ <string name="spoken_emoji_1F431" msgid="6051358666235016851">"Cap de pisică"</string>
+ <string name="spoken_emoji_1F432" msgid="7698001871193018305">"Cap de dragon"</string>
+ <string name="spoken_emoji_1F433" msgid="3762356053512899326">"Balenă cenușie"</string>
+ <string name="spoken_emoji_1F434" msgid="3619943222159943226">"Cap de cal"</string>
+ <string name="spoken_emoji_1F435" msgid="59199202683252958">"Cap de maimuță"</string>
+ <string name="spoken_emoji_1F436" msgid="340544719369009828">"Cap de câine"</string>
+ <string name="spoken_emoji_1F437" msgid="1219818379784982585">"Cap de porc"</string>
+ <string name="spoken_emoji_1F438" msgid="9128124743321008210">"Cap de broască"</string>
+ <string name="spoken_emoji_1F439" msgid="1424161319554642266">"Cap de hamster"</string>
+ <string name="spoken_emoji_1F43A" msgid="6727645488430385584">"Cap de lup"</string>
+ <string name="spoken_emoji_1F43B" msgid="5397170068392865167">"Cap de urs"</string>
+ <string name="spoken_emoji_1F43C" msgid="2715995734367032431">"Cap de urs panda"</string>
+ <string name="spoken_emoji_1F43D" msgid="6005480717951776597">"Rât de porc"</string>
+ <string name="spoken_emoji_1F43E" msgid="8917626103219080547">"Urme de labe"</string>
+ <string name="spoken_emoji_1F440" msgid="7144338258163384433">"Ochi"</string>
+ <string name="spoken_emoji_1F442" msgid="1905515392292676124">"Ureche"</string>
+ <string name="spoken_emoji_1F443" msgid="1491504447758933115">"Nas"</string>
+ <string name="spoken_emoji_1F444" msgid="3654613047946080332">"Gură"</string>
+ <string name="spoken_emoji_1F445" msgid="7024905244040509204">"Limbă scoasă"</string>
+ <string name="spoken_emoji_1F446" msgid="2150365643636471745">"Deget arătător alb, orientat în sus"</string>
+ <string name="spoken_emoji_1F447" msgid="8794022344940891388">"Deget arătător alb, orientat în jos"</string>
+ <string name="spoken_emoji_1F448" msgid="3261812959215550650">"Deget arătător alb, orientat la stânga"</string>
+ <string name="spoken_emoji_1F449" msgid="4764447975177805991">"Deget arătător alb, orientat la dreapta"</string>
+ <string name="spoken_emoji_1F44A" msgid="7197417095486424841">"Semn pumn strâns"</string>
+ <string name="spoken_emoji_1F44B" msgid="1975968945250833117">"Semn palmă deschisă"</string>
+ <string name="spoken_emoji_1F44C" msgid="3185919567897876562">"Semn OK"</string>
+ <string name="spoken_emoji_1F44D" msgid="6182553970602667815">"Semn de aprobare"</string>
+ <string name="spoken_emoji_1F44E" msgid="8030851867365111809">"Semn de dezaprobare"</string>
+ <string name="spoken_emoji_1F44F" msgid="5148753662268213389">"Semn Aplauze"</string>
+ <string name="spoken_emoji_1F450" msgid="1012021072085157054">"Semn Palme deschise"</string>
+ <string name="spoken_emoji_1F451" msgid="8257466714629051320">"Coroană"</string>
+ <string name="spoken_emoji_1F452" msgid="4567394011149905466">"Pălărie de damă"</string>
+ <string name="spoken_emoji_1F453" msgid="5978410551173163010">"Ochelari"</string>
+ <string name="spoken_emoji_1F454" msgid="348469036193323252">"Cravată"</string>
+ <string name="spoken_emoji_1F455" msgid="5665118831861433578">"Tricou"</string>
+ <string name="spoken_emoji_1F456" msgid="1890991330923356408">"Blugi"</string>
+ <string name="spoken_emoji_1F457" msgid="3904310482655702620">"Rochie"</string>
+ <string name="spoken_emoji_1F458" msgid="5704243858031107692">"Kimono"</string>
+ <string name="spoken_emoji_1F459" msgid="3553148747050035251">"Bikini"</string>
+ <string name="spoken_emoji_1F45A" msgid="1389654639484716101">"Haine de damă"</string>
+ <string name="spoken_emoji_1F45B" msgid="1113293170254222904">"Poșetă"</string>
+ <string name="spoken_emoji_1F45C" msgid="3410257778598006936">"Geantă"</string>
+ <string name="spoken_emoji_1F45D" msgid="812176504300064819">"Borsetă"</string>
+ <string name="spoken_emoji_1F45E" msgid="2901741399934723562">"Pantofi bărbătești"</string>
+ <string name="spoken_emoji_1F45F" msgid="6828566359287798863">"Încălțăminte sport"</string>
+ <string name="spoken_emoji_1F460" msgid="305863879170420855">"Pantof cu toc înalt"</string>
+ <string name="spoken_emoji_1F461" msgid="5160493217831417630">"Sandale de damă"</string>
+ <string name="spoken_emoji_1F462" msgid="1722897795554863734">"Cizme de damă"</string>
+ <string name="spoken_emoji_1F463" msgid="5850772903593010699">"Urme de pași"</string>
+ <string name="spoken_emoji_1F464" msgid="1228335905487734913">"Bust siluetă"</string>
+ <string name="spoken_emoji_1F465" msgid="4461307702499679879">"Busturi siluetă"</string>
+ <string name="spoken_emoji_1F466" msgid="1938873085514108889">"Băiat"</string>
+ <string name="spoken_emoji_1F467" msgid="8237080594860144998">"Fată"</string>
+ <string name="spoken_emoji_1F468" msgid="6081300722526675382">"Bărbat"</string>
+ <string name="spoken_emoji_1F469" msgid="1090140923076108158">"Femeie"</string>
+ <string name="spoken_emoji_1F46A" msgid="5063570981942606595">"Familie"</string>
+ <string name="spoken_emoji_1F46B" msgid="6795882374287327952">"Bărbat și femeie ținându-se de mână"</string>
+ <string name="spoken_emoji_1F46C" msgid="6844464165783964495">"Doi bărbați ținându-se de mână"</string>
+ <string name="spoken_emoji_1F46D" msgid="2316773068014053180">"Două femei ținându-se de mână"</string>
+ <string name="spoken_emoji_1F46E" msgid="5897625605860822401">"Polițist"</string>
+ <string name="spoken_emoji_1F46F" msgid="7716871657717641490">"Femeie cu urechi de iepure"</string>
+ <string name="spoken_emoji_1F470" msgid="6409995400510338892">"Mireasă cu voal"</string>
+ <string name="spoken_emoji_1F471" msgid="3058247860441670806">"Persoană cu păr blond"</string>
+ <string name="spoken_emoji_1F472" msgid="3928854667819339142">"Bărbat cu gua pi mao"</string>
+ <string name="spoken_emoji_1F473" msgid="5921952095808988381">"Bărbat cu turban"</string>
+ <string name="spoken_emoji_1F474" msgid="1082237499496725183">"Bătrân"</string>
+ <string name="spoken_emoji_1F475" msgid="7280323988642212761">"Bătrână"</string>
+ <string name="spoken_emoji_1F476" msgid="4713322657821088296">"Bebeluș"</string>
+ <string name="spoken_emoji_1F477" msgid="2197036131029221370">"Muncitor în construcții"</string>
+ <string name="spoken_emoji_1F478" msgid="7245521193493488875">"Prinţesă"</string>
+ <string name="spoken_emoji_1F479" msgid="6876475321015553972">"Căpcăun japonez"</string>
+ <string name="spoken_emoji_1F47A" msgid="3900813633102703571">"Goblin japonez"</string>
+ <string name="spoken_emoji_1F47B" msgid="2608250873194079390">"Fantomă"</string>
+ <string name="spoken_emoji_1F47C" msgid="3838699131276537421">"Îngeraș"</string>
+ <string name="spoken_emoji_1F47D" msgid="2874077455888369538">"Extraterestru"</string>
+ <string name="spoken_emoji_1F47E" msgid="3642607168625579507">"Monstru extraterestru"</string>
+ <string name="spoken_emoji_1F47F" msgid="441605977269926252">"Demon"</string>
+ <string name="spoken_emoji_1F480" msgid="3696253485164878739">"Craniu"</string>
+ <string name="spoken_emoji_1F481" msgid="320408708521966893">"Persoană la ghișeul de informații"</string>
+ <string name="spoken_emoji_1F482" msgid="3424354860245608949">"Paznic"</string>
+ <string name="spoken_emoji_1F483" msgid="3221113594843849083">"Dansator"</string>
+ <string name="spoken_emoji_1F484" msgid="7348014979080444885">"Ruj"</string>
+ <string name="spoken_emoji_1F485" msgid="6133507975565116339">"Lac de unghii"</string>
+ <string name="spoken_emoji_1F486" msgid="9085459968247394155">"Masaj facial"</string>
+ <string name="spoken_emoji_1F487" msgid="1479113637259592150">"Tunsoare"</string>
+ <string name="spoken_emoji_1F488" msgid="6922559285234100252">"Simbol pentru bărbier"</string>
+ <string name="spoken_emoji_1F489" msgid="8114863680950147305">"Seringă"</string>
+ <string name="spoken_emoji_1F48A" msgid="8526843630145963032">"Pilulă"</string>
+ <string name="spoken_emoji_1F48B" msgid="2538528967897640292">"Semn de sărut"</string>
+ <string name="spoken_emoji_1F48C" msgid="1681173271652890232">"Scrisoare de dragoste"</string>
+ <string name="spoken_emoji_1F48D" msgid="8259886164999042373">"Inel"</string>
+ <string name="spoken_emoji_1F48E" msgid="8777981696011111101">"Piatră prețioasă"</string>
+ <string name="spoken_emoji_1F48F" msgid="741593675183677907">"Sărut"</string>
+ <string name="spoken_emoji_1F490" msgid="4482549128959806736">"Buchet"</string>
+ <string name="spoken_emoji_1F491" msgid="2305245307882441500">"Cuplu cu inimă"</string>
+ <string name="spoken_emoji_1F492" msgid="3884119934804475732">"Nuntă"</string>
+ <string name="spoken_emoji_1F493" msgid="1208828371565525121">"Inimă bătând"</string>
+ <string name="spoken_emoji_1F494" msgid="6198876398509338718">"Inimă zdrobită"</string>
+ <string name="spoken_emoji_1F495" msgid="9206202744967130919">"Două inimi"</string>
+ <string name="spoken_emoji_1F496" msgid="5436953041732207775">"Inimă strălucitoare"</string>
+ <string name="spoken_emoji_1F497" msgid="7285142863951448473">"Inimă care crește"</string>
+ <string name="spoken_emoji_1F498" msgid="7940131245037575715">"Inimă cu sageată"</string>
+ <string name="spoken_emoji_1F499" msgid="4453235040265550009">"Inimă albastră"</string>
+ <string name="spoken_emoji_1F49A" msgid="6262178648366971405">"Inimă verde"</string>
+ <string name="spoken_emoji_1F49B" msgid="8085384999750714368">"Inimă galbenă"</string>
+ <string name="spoken_emoji_1F49C" msgid="453829540120898698">"Inimă violet"</string>
+ <string name="spoken_emoji_1F49D" msgid="3460534750224161888">"Inimăcu panglică"</string>
+ <string name="spoken_emoji_1F49E" msgid="4490636226072523867">"Inimi care se rotesc"</string>
+ <string name="spoken_emoji_1F49F" msgid="2059319756421226336">"Ornament inimă"</string>
+ <string name="spoken_emoji_1F4A0" msgid="1954850380550212038">"Formă romboidală cu un punct înăuntru"</string>
+ <string name="spoken_emoji_1F4A1" msgid="403137413540909021">"Bec electric"</string>
+ <string name="spoken_emoji_1F4A2" msgid="2604192053295622063">"Simbol pentru furie"</string>
+ <string name="spoken_emoji_1F4A3" msgid="6378351742957821735">"Bombă"</string>
+ <string name="spoken_emoji_1F4A4" msgid="7217736258870346625">"Simbol pentru somn"</string>
+ <string name="spoken_emoji_1F4A5" msgid="5401995723541239858">"Simbol pentru accident"</string>
+ <string name="spoken_emoji_1F4A6" msgid="3837802182716483848">"Simbol stropi de transpirație"</string>
+ <string name="spoken_emoji_1F4A7" msgid="5718438987757885141">"Picătură"</string>
+ <string name="spoken_emoji_1F4A8" msgid="4472108229720006377">"Simbol liniuță"</string>
+ <string name="spoken_emoji_1F4A9" msgid="1240958472788430032">"Excremente"</string>
+ <string name="spoken_emoji_1F4AA" msgid="8427525538635146416">"Biceps flexat"</string>
+ <string name="spoken_emoji_1F4AB" msgid="5484114759939427459">"Simbol pentru amețeală"</string>
+ <string name="spoken_emoji_1F4AC" msgid="5571196638219612682">"Balon de dialog"</string>
+ <string name="spoken_emoji_1F4AD" msgid="353174619257798652">"Balon de gândire"</string>
+ <string name="spoken_emoji_1F4AE" msgid="1223142786927162641">"Floare albă"</string>
+ <string name="spoken_emoji_1F4AF" msgid="3526278354452138397">"Simbol pentru o sută de puncte"</string>
+ <string name="spoken_emoji_1F4B0" msgid="4124102195175124156">"Sac cu bani"</string>
+ <string name="spoken_emoji_1F4B1" msgid="8339494003418572905">"Schimb valutar"</string>
+ <string name="spoken_emoji_1F4B2" msgid="3179159430187243132">"Semn dolar îngroșat"</string>
+ <string name="spoken_emoji_1F4B3" msgid="5375412518221759596">"Card de credit"</string>
+ <string name="spoken_emoji_1F4B4" msgid="1068592463669453204">"Bancnotă cu simbolul yen"</string>
+ <string name="spoken_emoji_1F4B5" msgid="1426708699891832564">"Bancnotă cu simbolul dolar"</string>
+ <string name="spoken_emoji_1F4B6" msgid="8289249930736444837">"Bancnotă cu simbolul euro"</string>
+ <string name="spoken_emoji_1F4B7" msgid="5245100496860739429">"Bancnotă cu simbolul liră"</string>
+ <string name="spoken_emoji_1F4B8" msgid="4401099580477164440">"Bani cu aripi"</string>
+ <string name="spoken_emoji_1F4B9" msgid="647509393536679903">"Diagramă reprezentând o tendință crescătoare și simbolul yen"</string>
+ <string name="spoken_emoji_1F4BA" msgid="1269737854891046321">"Loc"</string>
+ <string name="spoken_emoji_1F4BB" msgid="6252883563347816451">"Computer"</string>
+ <string name="spoken_emoji_1F4BC" msgid="6182597732218446206">"Servietă"</string>
+ <string name="spoken_emoji_1F4BD" msgid="5820961044768829176">"Minidisc"</string>
+ <string name="spoken_emoji_1F4BE" msgid="4754542485835379808">"Dischetă"</string>
+ <string name="spoken_emoji_1F4BF" msgid="2237481756984721795">"Disc optic"</string>
+ <string name="spoken_emoji_1F4C0" msgid="491582501089694461">"DVD"</string>
+ <string name="spoken_emoji_1F4C1" msgid="6645461382494158111">"Dosar cu fișiere"</string>
+ <string name="spoken_emoji_1F4C2" msgid="8095638715523765338">"Dosar deschis"</string>
+ <string name="spoken_emoji_1F4C3" msgid="3727274466173970142">"Pagină îndoită"</string>
+ <string name="spoken_emoji_1F4C4" msgid="4382570710795501612">"Pagină orientată în sus"</string>
+ <string name="spoken_emoji_1F4C5" msgid="8693944622627762487">"Calendar"</string>
+ <string name="spoken_emoji_1F4C6" msgid="8469908708708424640">"Calendar cu file detașabile"</string>
+ <string name="spoken_emoji_1F4C7" msgid="2665313547987324495">"Index cărți de vizită"</string>
+ <string name="spoken_emoji_1F4C8" msgid="8007686702282833600">"Diagramă reprezentând o tendință crescătoare"</string>
+ <string name="spoken_emoji_1F4C9" msgid="2271951411192893684">"Diagramă reprezentând o tendință descrescătoare"</string>
+ <string name="spoken_emoji_1F4CA" msgid="3525692829622381444">"Diagramă cu bare"</string>
+ <string name="spoken_emoji_1F4CB" msgid="977639227554095521">"Clipboard"</string>
+ <string name="spoken_emoji_1F4CC" msgid="156107396088741574">"Piuneză"</string>
+ <string name="spoken_emoji_1F4CD" msgid="4266572175361190231">"Piuneză rotundă"</string>
+ <string name="spoken_emoji_1F4CE" msgid="6294288509864968290">"Agrafă de birou"</string>
+ <string name="spoken_emoji_1F4CF" msgid="149679400831136810">"Riglă dreaptă"</string>
+ <string name="spoken_emoji_1F4D0" msgid="8130339336619202915">"Riglă triunghiulară"</string>
+ <string name="spoken_emoji_1F4D1" msgid="5852176364856284968">"File de marcaj"</string>
+ <string name="spoken_emoji_1F4D2" msgid="2276810154105920052">"Registru"</string>
+ <string name="spoken_emoji_1F4D3" msgid="5873386492793610808">"Blocnotes"</string>
+ <string name="spoken_emoji_1F4D4" msgid="4754469936418776360">"Blocnotes cu copertă decorativă"</string>
+ <string name="spoken_emoji_1F4D5" msgid="4642713351802778905">"Carte închisă"</string>
+ <string name="spoken_emoji_1F4D6" msgid="6987347918381807186">"Carte deschisă"</string>
+ <string name="spoken_emoji_1F4D7" msgid="7813394163241379223">"Carte verde"</string>
+ <string name="spoken_emoji_1F4D8" msgid="7189799718984979521">"Carte albastră"</string>
+ <string name="spoken_emoji_1F4D9" msgid="3874664073186440225">"Carte portocalie"</string>
+ <string name="spoken_emoji_1F4DA" msgid="872212072924287762">"Cărți"</string>
+ <string name="spoken_emoji_1F4DB" msgid="2015183603583392969">"Insignă cu numele"</string>
+ <string name="spoken_emoji_1F4DC" msgid="5075845110932456783">"Sul"</string>
+ <string name="spoken_emoji_1F4DD" msgid="2494006707147586786">"Notă"</string>
+ <string name="spoken_emoji_1F4DE" msgid="7883008605002117671">"Receptor de telefon"</string>
+ <string name="spoken_emoji_1F4DF" msgid="3538610110623780465">"Pager"</string>
+ <string name="spoken_emoji_1F4E0" msgid="2960778342609543077">"Fax"</string>
+ <string name="spoken_emoji_1F4E1" msgid="6269733703719242108">"Antenă satelit"</string>
+ <string name="spoken_emoji_1F4E2" msgid="1987535386302883116">"Megafon"</string>
+ <string name="spoken_emoji_1F4E3" msgid="5588916572878599224">"Megafon"</string>
+ <string name="spoken_emoji_1F4E4" msgid="2063561529097749707">"Tavă de ieșiri"</string>
+ <string name="spoken_emoji_1F4E5" msgid="3232462702926143576">"Tavă de intrări"</string>
+ <string name="spoken_emoji_1F4E6" msgid="3399454337197561635">"Pachet"</string>
+ <string name="spoken_emoji_1F4E7" msgid="5557136988503873238">"Simbolul E-mail"</string>
+ <string name="spoken_emoji_1F4E8" msgid="30698793974124123">"Plic primit"</string>
+ <string name="spoken_emoji_1F4E9" msgid="5947550337678643166">"Plic cu săgeată în jos deasupra"</string>
+ <string name="spoken_emoji_1F4EA" msgid="772614045207213751">"Cutie poștală închisă cu steag coborât"</string>
+ <string name="spoken_emoji_1F4EB" msgid="6491414165464146137">"Cutie poștală închisă cu steag ridicat"</string>
+ <string name="spoken_emoji_1F4EC" msgid="7369517138779988438">"Cutie poștală deschisă cu steag ridicat"</string>
+ <string name="spoken_emoji_1F4ED" msgid="5657520436285454241">"Cutie poștală deschisă cu steag coborât"</string>
+ <string name="spoken_emoji_1F4EE" msgid="8464138906243608614">"Cutie poștală"</string>
+ <string name="spoken_emoji_1F4EF" msgid="8801427577198798226">"Simbolul poștal"</string>
+ <string name="spoken_emoji_1F4F0" msgid="6330208624731662525">"Ziar"</string>
+ <string name="spoken_emoji_1F4F1" msgid="3966503935581675695">"Telefon mobil"</string>
+ <string name="spoken_emoji_1F4F2" msgid="1057540341746100087">"Telefon mobil cu săgeată spre dreapta la stânga"</string>
+ <string name="spoken_emoji_1F4F3" msgid="5003984447315754658">"Modul vibrații"</string>
+ <string name="spoken_emoji_1F4F4" msgid="5549847566968306253">"Telefon mobil închis"</string>
+ <string name="spoken_emoji_1F4F5" msgid="3660199448671699238">"Telefoanele mobile interzise"</string>
+ <string name="spoken_emoji_1F4F6" msgid="2676974903233268860">"Antenă cu bare"</string>
+ <string name="spoken_emoji_1F4F7" msgid="2643891943105989039">"Cameră foto"</string>
+ <string name="spoken_emoji_1F4F9" msgid="4475626303058218048">"Cameră video"</string>
+ <string name="spoken_emoji_1F4FA" msgid="1079796186652960775">"Emisiuni TV"</string>
+ <string name="spoken_emoji_1F4FB" msgid="3848729587403760645">"Radio"</string>
+ <string name="spoken_emoji_1F4FC" msgid="8370432508874310054">"Casetă video"</string>
+ <string name="spoken_emoji_1F500" msgid="2389947994502144547">"Săgeți răsucite spre dreapta"</string>
+ <string name="spoken_emoji_1F501" msgid="2132188352433347009">"Săgeți în formă de cerc deschis, orientate spre dreapta și spre stânga, în sensul acelor de ceasornic"</string>
+ <string name="spoken_emoji_1F502" msgid="2361976580513178391">"Săgeți în formă de cerc deschis, orientate spre dreapta și spre stânga, în sensul acelor de ceasornic, cu suprapunerea cifrei 1 într-un cerc"</string>
+ <string name="spoken_emoji_1F503" msgid="8936283551917858793">"Săgeți în formă de cerc deschis, orientate în sus și în jos, în sens orar"</string>
+ <string name="spoken_emoji_1F504" msgid="708290317843535943">"Săgeți în formă de cerc deschis, orientate în sus și în jos, în sens antiorar"</string>
+ <string name="spoken_emoji_1F505" msgid="6348909939004951860">"Simbol de luminozitate scăzută"</string>
+ <string name="spoken_emoji_1F506" msgid="4449609297521280173">"Simbol de luminozitate ridicată"</string>
+ <string name="spoken_emoji_1F507" msgid="7136386694923708448">"Difuzor cu simbol de anulare"</string>
+ <string name="spoken_emoji_1F508" msgid="5063567689831527865">"Difuzor"</string>
+ <string name="spoken_emoji_1F509" msgid="3948050077992370791">"Difuzor cu un val de sunet"</string>
+ <string name="spoken_emoji_1F50A" msgid="5818194948677277197">"Difuzor cu trei valuri de sunet"</string>
+ <string name="spoken_emoji_1F50B" msgid="8083470451266295876">"Baterie"</string>
+ <string name="spoken_emoji_1F50C" msgid="7793219132036431680">"Alimentare electrică"</string>
+ <string name="spoken_emoji_1F50D" msgid="8140244710637926780">"Lupă orientată spre stânga"</string>
+ <string name="spoken_emoji_1F50E" msgid="4751821352839693365">"Lupă orientată spre dreapta"</string>
+ <string name="spoken_emoji_1F50F" msgid="915079280472199605">"Lacăt cu stilou"</string>
+ <string name="spoken_emoji_1F510" msgid="7658381761691758318">"Lacăt închis cu cheie"</string>
+ <string name="spoken_emoji_1F511" msgid="262319867774655688">"Cheie"</string>
+ <string name="spoken_emoji_1F512" msgid="5628688337255115175">"Lacăt"</string>
+ <string name="spoken_emoji_1F513" msgid="8579201846619420981">"Lacăt deschis"</string>
+ <string name="spoken_emoji_1F514" msgid="7027268683047322521">"Clopoțel"</string>
+ <string name="spoken_emoji_1F515" msgid="8903179856036069242">"Clopoțel cu simbol de anulare"</string>
+ <string name="spoken_emoji_1F516" msgid="108097933937925381">"Marcaj"</string>
+ <string name="spoken_emoji_1F517" msgid="2450846665734313397">"Simbol lanț"</string>
+ <string name="spoken_emoji_1F518" msgid="7028220286841437832">"Buton radio"</string>
+ <string name="spoken_emoji_1F519" msgid="8211189165075445687">"„BACK” cu săgeată spre stânga deasupra"</string>
+ <string name="spoken_emoji_1F51A" msgid="823966751787338892">"„END” cu săgeată spre stânga deasupra"</string>
+ <string name="spoken_emoji_1F51B" msgid="5920570742107943382">"„ON” cu semn de exclamare și cu săgeată stânga-dreapta deasupra"</string>
+ <string name="spoken_emoji_1F51C" msgid="110609810659826676">"„SOON” cu săgeată spre dreapta deasupra"</string>
+ <string name="spoken_emoji_1F51D" msgid="4087697222026095447">"„TOP” cu săgeată în sus deasupra"</string>
+ <string name="spoken_emoji_1F51E" msgid="8512873526157201775">"Simbolul „Interzis sub optsprezece ani”"</string>
+ <string name="spoken_emoji_1F51F" msgid="8673370823728653973">"Tastă zece"</string>
+ <string name="spoken_emoji_1F520" msgid="7335109890337048900">"Simbol de introducere a majusculelor latine"</string>
+ <string name="spoken_emoji_1F521" msgid="2693185864450925778">"Simbol de introducere a literelor mici latine"</string>
+ <string name="spoken_emoji_1F522" msgid="8419130286280673347">"Simbol de introducere a cifrelor"</string>
+ <string name="spoken_emoji_1F523" msgid="3318053476401719421">"Simbol de introducere a simbolurilor"</string>
+ <string name="spoken_emoji_1F524" msgid="1625073997522316331">"Simbol de introducere a literelor latine"</string>
+ <string name="spoken_emoji_1F525" msgid="4083884189172963790">"Foc"</string>
+ <string name="spoken_emoji_1F526" msgid="2035494936742643580">"Lanternă"</string>
+ <string name="spoken_emoji_1F527" msgid="134257142354034271">"Cheie"</string>
+ <string name="spoken_emoji_1F528" msgid="700627429570609375">"Ciocan"</string>
+ <string name="spoken_emoji_1F529" msgid="7480548235904988573">"Piuliță și șurub"</string>
+ <string name="spoken_emoji_1F52A" msgid="7613580031502317893">"Hocho"</string>
+ <string name="spoken_emoji_1F52B" msgid="4554906608328118613">"Pistol"</string>
+ <string name="spoken_emoji_1F52C" msgid="1330294501371770790">"Microscop"</string>
+ <string name="spoken_emoji_1F52D" msgid="7549551775445177140">"Telescop"</string>
+ <string name="spoken_emoji_1F52E" msgid="4457099417872625141">"Glob de cristal"</string>
+ <string name="spoken_emoji_1F52F" msgid="8899031001317442792">"Stea cu șase colțuri cu punct în mijloc"</string>
+ <string name="spoken_emoji_1F530" msgid="3572898444281774023">"Simbolul japonez pentru începători"</string>
+ <string name="spoken_emoji_1F531" msgid="5225633376450025396">"Emblemă trident"</string>
+ <string name="spoken_emoji_1F532" msgid="9169568490485180779">"Buton negru pătrat"</string>
+ <string name="spoken_emoji_1F533" msgid="6554193837201918598">"Buton alb pătrat"</string>
+ <string name="spoken_emoji_1F534" msgid="8339298801331865340">"Cerc mare roșu"</string>
+ <string name="spoken_emoji_1F535" msgid="1227403104835533512">"Cerc mare albastru"</string>
+ <string name="spoken_emoji_1F536" msgid="5477372445510469331">"Romb mare portocaliu"</string>
+ <string name="spoken_emoji_1F537" msgid="3158915214347274626">"Romb mare albastru"</string>
+ <string name="spoken_emoji_1F538" msgid="4300084249474451991">"Romb mic portocaliu"</string>
+ <string name="spoken_emoji_1F539" msgid="6535159756325742275">"Romb mic albastru"</string>
+ <string name="spoken_emoji_1F53A" msgid="3728196273988781389">"Triunghi roșu, îndreptat în sus"</string>
+ <string name="spoken_emoji_1F53B" msgid="7182097039614128707">"Triunghi roșu, îndreptat în jos"</string>
+ <string name="spoken_emoji_1F53C" msgid="4077022046319615029">"Triunghi mic roșu, îndreptat în sus"</string>
+ <string name="spoken_emoji_1F53D" msgid="3939112784894620713">"Triunghi mic roșu, îndreptat în jos"</string>
+ <string name="spoken_emoji_1F550" msgid="7761392621689986218">"Ceas cu ora unu"</string>
+ <string name="spoken_emoji_1F551" msgid="2699448504113431716">"Ceas cu ora două"</string>
+ <string name="spoken_emoji_1F552" msgid="5872107867411853750">"Ceas cu ora trei"</string>
+ <string name="spoken_emoji_1F553" msgid="8490966286158640743">"Ceas cu ora patru"</string>
+ <string name="spoken_emoji_1F554" msgid="7662585417832909280">"Ceas cu ora cinci"</string>
+ <string name="spoken_emoji_1F555" msgid="5564698204520412009">"Ceas cu ora șase"</string>
+ <string name="spoken_emoji_1F556" msgid="7325712194836512205">"Ceas cu ora șapte"</string>
+ <string name="spoken_emoji_1F557" msgid="4398343183682848693">"Ceas cu ora opt"</string>
+ <string name="spoken_emoji_1F558" msgid="3110507820404018172">"Ceas cu ora nouă"</string>
+ <string name="spoken_emoji_1F559" msgid="2972160366448337839">"Ceas cu ora zece"</string>
+ <string name="spoken_emoji_1F55A" msgid="5568112876681714834">"Ceas cu ora unsprezece"</string>
+ <string name="spoken_emoji_1F55B" msgid="6731739890330659276">"Ceas cu ora douăsprezece"</string>
+ <string name="spoken_emoji_1F55C" msgid="7838853679879115890">"Ceas cu ora unu și jumătate"</string>
+ <string name="spoken_emoji_1F55D" msgid="3518832144255922544">"Ceas cu ora două și jumătate"</string>
+ <string name="spoken_emoji_1F55E" msgid="3092760695634993002">"Ceas cu ora trei și jumătate"</string>
+ <string name="spoken_emoji_1F55F" msgid="2326720311892906763">"Ceas cu ora patru și jumătate"</string>
+ <string name="spoken_emoji_1F560" msgid="5771339179963924448">"Ceas cu ora cinci și jumătate"</string>
+ <string name="spoken_emoji_1F561" msgid="3139944777062475382">"Ceas cu ora șase și jumătate"</string>
+ <string name="spoken_emoji_1F562" msgid="8273944611162457084">"Ceas cu ora șapte și jumătate"</string>
+ <string name="spoken_emoji_1F563" msgid="8643976903718136299">"Ceas cu ora opt și jumătate"</string>
+ <string name="spoken_emoji_1F564" msgid="3511070239796141638">"Ceas cu ora nouă și jumătate"</string>
+ <string name="spoken_emoji_1F565" msgid="4567451985272963088">"Ceas cu ora zece și jumătate"</string>
+ <string name="spoken_emoji_1F566" msgid="2790552288169929810">"Ceas cu ora unsprezece și jumătate"</string>
+ <string name="spoken_emoji_1F567" msgid="9026037362100689337">"Ceas cu ora douăsprezece și jumătate"</string>
+ <string name="spoken_emoji_1F5FB" msgid="9037503671676124015">"Muntele Fuji"</string>
+ <string name="spoken_emoji_1F5FC" msgid="1409415995817242150">"Turnul Tokyo"</string>
+ <string name="spoken_emoji_1F5FD" msgid="2562726956654429582">"Statuia Libertății"</string>
+ <string name="spoken_emoji_1F5FE" msgid="1184469756905210580">"Conturul Japoniei"</string>
+ <string name="spoken_emoji_1F5FF" msgid="6003594799354942297">"Moyai"</string>
+ <string name="spoken_emoji_1F600" msgid="7601109464776835283">"Față rânjind"</string>
+ <string name="spoken_emoji_1F601" msgid="746026523967444503">"Față rânjind cu ochi zâmbitori"</string>
+ <string name="spoken_emoji_1F602" msgid="8354558091785198246">"Față cu lacrimi de bucurie"</string>
+ <string name="spoken_emoji_1F603" msgid="3861022912544159823">"Față zâmbitoare cu gura deschisă"</string>
+ <string name="spoken_emoji_1F604" msgid="5119021072966343531">"Față zâmbitoare cu gura deschisă și ochi zâmbitori"</string>
+ <string name="spoken_emoji_1F605" msgid="6140813923973561735">"Față zâmbitoare, cu gura deschisă și sudoare rece"</string>
+ <string name="spoken_emoji_1F606" msgid="3549936813966832799">"Față zâmbitoare cu gura deschisă și ochii închiși"</string>
+ <string name="spoken_emoji_1F607" msgid="2826424078212384817">"Față zâmbitoare cu aură"</string>
+ <string name="spoken_emoji_1F608" msgid="7343559595089811640">"Față zâmbitoare cu coarne"</string>
+ <string name="spoken_emoji_1F609" msgid="5481030187207504405">"Față care face cu ochiul"</string>
+ <string name="spoken_emoji_1F60A" msgid="5023337769148679767">"Față zâmbitoare, cu ochii zâmbitori"</string>
+ <string name="spoken_emoji_1F60B" msgid="3005248217216195694">"Față savurând mâncare delicioasă"</string>
+ <string name="spoken_emoji_1F60C" msgid="349384012958268496">"Față ușurată"</string>
+ <string name="spoken_emoji_1F60D" msgid="7921853137164938391">"Față zâmbitoare, cu ochii în formă de inimă"</string>
+ <string name="spoken_emoji_1F60E" msgid="441718886380605643">"Față zâmbitoare cu ochelari de soare"</string>
+ <string name="spoken_emoji_1F60F" msgid="2674453144890180538">"Față zâmbind șiret"</string>
+ <string name="spoken_emoji_1F610" msgid="3225675825334102369">"Față neutră"</string>
+ <string name="spoken_emoji_1F611" msgid="7199179827619679668">"Față fără expresie"</string>
+ <string name="spoken_emoji_1F612" msgid="985081329745137998">"Față serioasă"</string>
+ <string name="spoken_emoji_1F613" msgid="5548607684830303562">"Față cu sudoare rece"</string>
+ <string name="spoken_emoji_1F614" msgid="3196305665259916390">"Față meditativă"</string>
+ <string name="spoken_emoji_1F615" msgid="3051674239303969101">"Față confuză"</string>
+ <string name="spoken_emoji_1F616" msgid="8124887056243813089">"Față confuză"</string>
+ <string name="spoken_emoji_1F617" msgid="7052733625511122870">"Față care sărută"</string>
+ <string name="spoken_emoji_1F618" msgid="408207170572303753">"Față care trimite bezele"</string>
+ <string name="spoken_emoji_1F619" msgid="8645430335143153645">"Față care sărută cu ochi zâmbitori"</string>
+ <string name="spoken_emoji_1F61A" msgid="2882157190974340247">"Față care sărută cu ochii închiși"</string>
+ <string name="spoken_emoji_1F61B" msgid="3765927202787211499">"Față care scoate limba"</string>
+ <string name="spoken_emoji_1F61C" msgid="198943912107589389">"Față care scoate limba și face cu ochiul"</string>
+ <string name="spoken_emoji_1F61D" msgid="7643546385877816182">"Față care scoate limba, cu ochii închiși"</string>
+ <string name="spoken_emoji_1F61E" msgid="1528732952202098364">"Față dezamăgită"</string>
+ <string name="spoken_emoji_1F61F" msgid="1853664164636082404">"Față îngrijorată"</string>
+ <string name="spoken_emoji_1F620" msgid="6051942001307375830">"Față furioasă"</string>
+ <string name="spoken_emoji_1F621" msgid="2114711878097257704">"Față bosumflată"</string>
+ <string name="spoken_emoji_1F622" msgid="29291014645931822">"Față care plânge"</string>
+ <string name="spoken_emoji_1F623" msgid="7803959833595184773">"Față perseverentă"</string>
+ <string name="spoken_emoji_1F624" msgid="8637637647725752799">"Față cu privire triumfătoare"</string>
+ <string name="spoken_emoji_1F625" msgid="6153625183493635030">"Față dezamăgită dar ușurată"</string>
+ <string name="spoken_emoji_1F626" msgid="6179485689935562950">"Față încruntată cu gura deschisă"</string>
+ <string name="spoken_emoji_1F627" msgid="8566204052903012809">"Față chinuită"</string>
+ <string name="spoken_emoji_1F628" msgid="8875777401624904224">"Față înfricoșată"</string>
+ <string name="spoken_emoji_1F629" msgid="1411538490319190118">"Față obosită"</string>
+ <string name="spoken_emoji_1F62A" msgid="4726686726690289969">"Față somnoroasă"</string>
+ <string name="spoken_emoji_1F62B" msgid="3221980473921623613">"Față obosită"</string>
+ <string name="spoken_emoji_1F62C" msgid="4616356691941225182">"Față cu grimasă"</string>
+ <string name="spoken_emoji_1F62D" msgid="4283677508698812232">"Față plângând în hohote"</string>
+ <string name="spoken_emoji_1F62E" msgid="726083405284353894">"Față cu gura deschisă"</string>
+ <string name="spoken_emoji_1F62F" msgid="7746620088234710962">"Față redusă la tăcere"</string>
+ <string name="spoken_emoji_1F630" msgid="3298804852155581163">"Față cu gura deschisă și sudoare rece"</string>
+ <string name="spoken_emoji_1F631" msgid="1603391150954646779">"Față țipând de frică"</string>
+ <string name="spoken_emoji_1F632" msgid="4846193232203976013">"Față uimită"</string>
+ <string name="spoken_emoji_1F633" msgid="4023593836629700443">"Față congestionată"</string>
+ <string name="spoken_emoji_1F634" msgid="3155265083246248129">"Față care doarme"</string>
+ <string name="spoken_emoji_1F635" msgid="4616691133452764482">"Față amețită"</string>
+ <string name="spoken_emoji_1F636" msgid="947000211822375683">"Față fără gura"</string>
+ <string name="spoken_emoji_1F637" msgid="1269551267347165774">"Față cu mască medicală"</string>
+ <string name="spoken_emoji_1F638" msgid="3410766467496872301">"Față de pisică rânjind, cu ochi zâmbitori"</string>
+ <string name="spoken_emoji_1F639" msgid="1833417519781022031">"Față de pisică cu lacrimi de bucurie"</string>
+ <string name="spoken_emoji_1F63A" msgid="8566294484007152613">"Față zâmbitoare de pisică, cu gura deschisă"</string>
+ <string name="spoken_emoji_1F63B" msgid="74417995938927571">"Față zâmbitoare pisică, cu ochii în formă de inimă"</string>
+ <string name="spoken_emoji_1F63C" msgid="6472812005729468870">"Față de pisică cu zâmbet crispat"</string>
+ <string name="spoken_emoji_1F63D" msgid="1638398369553349509">"Față de pisică sărutând cu ochii închiși"</string>
+ <string name="spoken_emoji_1F63E" msgid="6788969063020278986">"Față de pisică bosumflată"</string>
+ <string name="spoken_emoji_1F63F" msgid="1207234562459550185">"Față de pisică plângând"</string>
+ <string name="spoken_emoji_1F640" msgid="6023054549904329638">"Față de pisică obosită"</string>
+ <string name="spoken_emoji_1F645" msgid="5202090629227587076">"Față cu gest „nu are niciun rost”"</string>
+ <string name="spoken_emoji_1F646" msgid="6734425134415138134">"Față cu gest „OK”"</string>
+ <string name="spoken_emoji_1F647" msgid="1090285518444205483">"Persoană care face plecăciuni"</string>
+ <string name="spoken_emoji_1F648" msgid="8978535230610522356">"Maimuță care-și acoperă ochii"</string>
+ <string name="spoken_emoji_1F649" msgid="8486145279809495102">"Maimuță care-și acoperă urechile"</string>
+ <string name="spoken_emoji_1F64A" msgid="1237524974033228660">"Maimuță care-și acoperă gura"</string>
+ <string name="spoken_emoji_1F64B" msgid="4251150782016370475">"Persoană fericită, ridicând o mână"</string>
+ <string name="spoken_emoji_1F64C" msgid="5446231430684558344">"Persoană fericită ridicând ambele mâini de bucurie"</string>
+ <string name="spoken_emoji_1F64D" msgid="4646485595309482342">"Persoană încruntată"</string>
+ <string name="spoken_emoji_1F64E" msgid="3376579939836656097">"Persoană cu fața bosumflată"</string>
+ <string name="spoken_emoji_1F64F" msgid="1044439574356230711">"Persoană cu mâinile împreunate"</string>
+ <string name="spoken_emoji_1F680" msgid="513263736012689059">"Rachetă"</string>
+ <string name="spoken_emoji_1F681" msgid="9201341783850525339">"Elicopter"</string>
+ <string name="spoken_emoji_1F682" msgid="8046933583867498698">"Locomotivă cu abur"</string>
+ <string name="spoken_emoji_1F683" msgid="8772750354339223092">"Vagon de tren"</string>
+ <string name="spoken_emoji_1F684" msgid="346396777356203608">"Tren de mare viteză"</string>
+ <string name="spoken_emoji_1F685" msgid="1237059817190832730">"Tren de mare viteză cu vârf ascuțit"</string>
+ <string name="spoken_emoji_1F686" msgid="3525197227223620343">"Tren"</string>
+ <string name="spoken_emoji_1F687" msgid="5110143437960392837">"Metrou"</string>
+ <string name="spoken_emoji_1F688" msgid="4702085029871797965">"Metrou ușor"</string>
+ <string name="spoken_emoji_1F689" msgid="2375851019798817094">"Stație"</string>
+ <string name="spoken_emoji_1F68A" msgid="6368370859718717198">"Tramvai"</string>
+ <string name="spoken_emoji_1F68B" msgid="2920160427117436633">"Vagon de tramvai"</string>
+ <string name="spoken_emoji_1F68C" msgid="1061520934758810864">"Autobuz"</string>
+ <string name="spoken_emoji_1F68D" msgid="2890059031360969304">"Autobuz sosind din față"</string>
+ <string name="spoken_emoji_1F68E" msgid="6234042976027309654">"Troleibuz"</string>
+ <string name="spoken_emoji_1F68F" msgid="5871099334672012107">"Stație de autobuz"</string>
+ <string name="spoken_emoji_1F690" msgid="8080964620200195262">"Maxi-taxi"</string>
+ <string name="spoken_emoji_1F691" msgid="999173032408730501">"Ambulanță"</string>
+ <string name="spoken_emoji_1F692" msgid="1712863785341849487">"Mașină de pompieri"</string>
+ <string name="spoken_emoji_1F693" msgid="7987109037389768934">"Mașină de poliție"</string>
+ <string name="spoken_emoji_1F694" msgid="6061658916653884608">"Mașină de poliție sosind din față"</string>
+ <string name="spoken_emoji_1F695" msgid="6913445460364247283">"Taxi"</string>
+ <string name="spoken_emoji_1F696" msgid="6391604457418285404">"Taxi sosind din față"</string>
+ <string name="spoken_emoji_1F697" msgid="7978399334396733790">"Automobil"</string>
+ <string name="spoken_emoji_1F698" msgid="7006050861129732018">"Automobil sosind din față"</string>
+ <string name="spoken_emoji_1F699" msgid="630317052666590607">"Vehicul de agrement"</string>
+ <string name="spoken_emoji_1F69A" msgid="4739797891735823577">"Camion pentru livrări"</string>
+ <string name="spoken_emoji_1F69B" msgid="4715997280786620649">"Camion cu remorcă"</string>
+ <string name="spoken_emoji_1F69C" msgid="5557395610750818161">"Tractor"</string>
+ <string name="spoken_emoji_1F69D" msgid="5467164189942951047">"Monoșină"</string>
+ <string name="spoken_emoji_1F69E" msgid="169238196389832234">"Cale ferată montană"</string>
+ <string name="spoken_emoji_1F69F" msgid="7508128757012845102">"Cale ferată suspendată"</string>
+ <string name="spoken_emoji_1F6A0" msgid="8733056213790160147">"Teleferic montan"</string>
+ <string name="spoken_emoji_1F6A1" msgid="4666516337749347253">"Tramvai aerian"</string>
+ <string name="spoken_emoji_1F6A2" msgid="4511220588943129583">"Vapor"</string>
+ <string name="spoken_emoji_1F6A3" msgid="8412962252222205387">"Barcă cu vâsle"</string>
+ <string name="spoken_emoji_1F6A4" msgid="8867571300266339211">"Barcă cu motor"</string>
+ <string name="spoken_emoji_1F6A5" msgid="7650260812741963884">"Semafor orizontal"</string>
+ <string name="spoken_emoji_1F6A6" msgid="485575967773793454">"Semafor vertical"</string>
+ <string name="spoken_emoji_1F6A7" msgid="6411048933816976794">"Semn de construcție"</string>
+ <string name="spoken_emoji_1F6A8" msgid="6345717218374788364">"Sirena de la mașina de poliție"</string>
+ <string name="spoken_emoji_1F6A9" msgid="6586380356807600412">"Stâlp cu steag triunghiular"</string>
+ <string name="spoken_emoji_1F6AA" msgid="8954448167261738885">"Ușă"</string>
+ <string name="spoken_emoji_1F6AB" msgid="5313946262888343544">"Semn Intrarea oprită"</string>
+ <string name="spoken_emoji_1F6AC" msgid="6946858177965948288">"Simbol Fumatul permis"</string>
+ <string name="spoken_emoji_1F6AD" msgid="6320088669185507241">"Simbol Fumatul interzis"</string>
+ <string name="spoken_emoji_1F6AE" msgid="1062469925352817189">"Simbol Aruncați gunoiul în locuri amenajate"</string>
+ <string name="spoken_emoji_1F6AF" msgid="2286668056123642208">"Simbol Păstrați curățenia"</string>
+ <string name="spoken_emoji_1F6B0" msgid="179424763882990952">"Simbol Apă potabilă"</string>
+ <string name="spoken_emoji_1F6B1" msgid="5585212805429161877">"Simbol Apă care nu este potabilă"</string>
+ <string name="spoken_emoji_1F6B2" msgid="1771885082068421875">"Bicicletă"</string>
+ <string name="spoken_emoji_1F6B3" msgid="8033779581263314408">"Interzis accesul cu bicicleta"</string>
+ <string name="spoken_emoji_1F6B4" msgid="1999538449018476947">"Biciclist"</string>
+ <string name="spoken_emoji_1F6B5" msgid="340846352660993117">"Biciclist pe trasee montane"</string>
+ <string name="spoken_emoji_1F6B6" msgid="4351024386495098336">"Pieton"</string>
+ <string name="spoken_emoji_1F6B7" msgid="4564800655866838802">"Accesul pietonilor interzis"</string>
+ <string name="spoken_emoji_1F6B8" msgid="3020531906940267349">"Copii traversând"</string>
+ <string name="spoken_emoji_1F6B9" msgid="1207095844125041251">"Simbol Bărbați"</string>
+ <string name="spoken_emoji_1F6BA" msgid="2346879310071017531">"Simbol Femei"</string>
+ <string name="spoken_emoji_1F6BB" msgid="2370172469642078526">"Toaletă"</string>
+ <string name="spoken_emoji_1F6BC" msgid="5558827593563530851">"Simbol Bebeluș"</string>
+ <string name="spoken_emoji_1F6BD" msgid="9213590243049835957">"Toaletă"</string>
+ <string name="spoken_emoji_1F6BE" msgid="394016533781742491">"WC"</string>
+ <string name="spoken_emoji_1F6BF" msgid="906336365928291207">"Duș"</string>
+ <string name="spoken_emoji_1F6C0" msgid="4592099854378821599">"Baie"</string>
+ <string name="spoken_emoji_1F6C1" msgid="2845056048320031158">"Cadă"</string>
+ <string name="spoken_emoji_1F6C2" msgid="8117262514698011877">"Control pașapoarte"</string>
+ <string name="spoken_emoji_1F6C3" msgid="1176342001834630675">"Vamă"</string>
+ <string name="spoken_emoji_1F6C4" msgid="1477622834179978886">"Revendicarea bagajului"</string>
+ <string name="spoken_emoji_1F6C5" msgid="2495834050856617451">"Bagaj în custodie"</string>
+</resources>
diff --git a/java/res/values-ro/strings-talkback-descriptions.xml b/java/res/values-ro/strings-talkback-descriptions.xml
index 2b428eb0b..6e5db4d02 100644
--- a/java/res/values-ro/strings-talkback-descriptions.xml
+++ b/java/res/values-ro/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nu a fost introdus text"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> corectează <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> cu <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> efectuează corectare automată"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Tasta cu codul %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Tasta Shift este activată (apăsați pentru a o dezactiva)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Tasta Caps Lock este activată (apăsați pentru a o dezactiva)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Mai multe simboluri"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simboluri"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Ștergeți"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simboluri"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Litere"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Înapoi"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Tasta Shift a fost activată"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Tasta Caps Lock este activată"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Tasta Shift a fost dezactivată"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Modul Simboluri"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Modul Mai multe simboluri"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Modul Alfanumeric"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Modul Telefon"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Modul Telefon cu simboluri"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Locații"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simboluri"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emoticonuri"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ro/strings.xml b/java/res/values-ro/strings.xml
index 51d3c5901..8ab56bc7a 100644
--- a/java/res/values-ro/strings.xml
+++ b/java/res/values-ro/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Opţiuni de introducere text"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Comenzi jurnal cercetare"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Verificare nume în agendă"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Verificatorul ortografic utilizează intrări din lista de contacte"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrare la apăsarea tastei"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sugeraţi nume din Agendă"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Utilizaţi numele din Agendă pentru sugestii şi corecţii"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Sugestii personalizate"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Inserează punct spațiu"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubla atingere a barei de spațiu inserează punct urmat de spațiu"</string>
<string name="auto_cap" msgid="1719746674854628252">"Scriere automată cu majuscule"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Limbi de introducere de text"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Atingeţi din nou pentru a salva"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Dicţionar disponibil"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Activaţi feedback de la utilizatori"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Ajutați la îmbunătățirea acestui instrument de editare a metodelor de introducere a textului trimițând în mod automat statistici de utilizare și rapoarte de blocare."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Temă pentru tastatură"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"engleză (Regatul Unit)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"engleză (S.U.A.)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Activaţi"</string>
<string name="not_now" msgid="6172462888202790482">"Nu acum"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Acelaşi stil de introducere există deja: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modul Studiu privind utilizarea"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Timpul apăsării lungi a tastei"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrare după apăsarea tastei"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Sunet la apăsarea tastelor"</string>
diff --git a/java/res/values-ru/strings-action-keys.xml b/java/res/values-ru/strings-action-keys.xml
index d5080ceb5..3edf2285c 100644
--- a/java/res/values-ru/strings-action-keys.xml
+++ b/java/res/values-ru/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Назад"</string>
<string name="label_done_key" msgid="7564866296502630852">"Готово"</string>
<string name="label_send_key" msgid="482252074224462163">"Отправить"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Пауза"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Пауза"</string>
</resources>
diff --git a/java/res/values-ru/strings-talkback-descriptions.xml b/java/res/values-ru/strings-talkback-descriptions.xml
index 7e64f11b0..f73ceab4e 100644
--- a/java/res/values-ru/strings-talkback-descriptions.xml
+++ b/java/res/values-ru/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Текст не введен."</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"При нажатии клавиши <xliff:g id="KEY_NAME">%1$s</xliff:g> слово <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> будет исправлено на <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>."</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Клавиша <xliff:g id="KEY_NAME">%1$s</xliff:g> выполняет автоисправление."</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Код клавиши %d."</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Клавиша верхнего регистра."</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Верхний регистр включен. Нажмите, чтобы отключить."</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock включен. Нажмите, чтобы отключить."</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Дополнительные символы."</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Клавиша верхнего регистра."</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Символы."</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Клавиша верхнего регистра."</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Удалить."</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Символы."</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Буквы."</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Назад."</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Верхний регистр включен."</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock включен."</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Верхний регистр отключен."</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Режим добавления символов."</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Режим дополнительных символов."</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Режим ввода текста."</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Режим набора номера."</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Режим телефонных символов."</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Места."</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Символы."</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Смайлики."</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-ru/strings.xml b/java/res/values-ru/strings.xml
index bef248385..61c414c4b 100644
--- a/java/res/values-ru/strings.xml
+++ b/java/res/values-ru/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Настройки"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Все команды"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Поиск контактов"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Обращаться к списку контактов при проверке правописания"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Виброотклик клавиш"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Подсказывать имена"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Подсказывать исправления на основе имен из списка контактов"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Пользовательские словари"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Ставить точки автоматически"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Вводить точку с пробелом двойным нажатием кнопки \"Пробел\"."</string>
<string name="auto_cap" msgid="1719746674854628252">"Заглавные автоматически"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Языки ввода"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Нажмите, чтобы сохранить"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Доступен словарь"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Включить отправку сведений"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Помогите усовершенствовать редактор способа ввода, разрешив отправку статистики и отчетов о сбоях"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема клавиатуры"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"английский (Великобритания)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"английский (США)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Включить"</string>
<string name="not_now" msgid="6172462888202790482">"Не сейчас"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Такой стиль ввода уже существует: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим проверки удобства использования"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Долгое нажатие"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Вибросигнал при нажатии клавиш"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Звук при нажатии клавиш"</string>
diff --git a/java/res/values-sk/strings-action-keys.xml b/java/res/values-sk/strings-action-keys.xml
index 3586fb140..ffc5be2d6 100644
--- a/java/res/values-sk/strings-action-keys.xml
+++ b/java/res/values-sk/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Pred."</string>
<string name="label_done_key" msgid="7564866296502630852">"OK"</string>
<string name="label_send_key" msgid="482252074224462163">"Posl."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pauza"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Čakať"</string>
</resources>
diff --git a/java/res/values-sk/strings-talkback-descriptions.xml b/java/res/values-sk/strings-talkback-descriptions.xml
index 605aceb38..9fde012b3 100644
--- a/java/res/values-sk/strings-talkback-descriptions.xml
+++ b/java/res/values-sk/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Nie je zadaný žiadny text"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Klávesom <xliff:g id="KEY_NAME">%1$s</xliff:g> opravíte slovo <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> na <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Klávesom <xliff:g id="KEY_NAME">%1$s</xliff:g> spustíte automatické opravy"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Kód klávesa %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Kláves Shift je zapnutý (zakážete ho klepnutím)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Kláves Caps Lock je zapnutý (zakážete ho klepnutím)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Ďalšie symboly"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboly"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Odstrániť"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboly"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Písmená"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Naspäť"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Kláves Shift je povolený"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Kláves Caps Lock je povolený"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Kláves Shift je zakázaný"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Režim symbolov"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Režim ďalších symbolov"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Režim písmen"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Režim telefónu"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Režim telefónnych symbolov"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Miesta"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboly"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Emotikony"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-sk/strings.xml b/java/res/values-sk/strings.xml
index 9a3564782..1d7a3dc0e 100644
--- a/java/res/values-sk/strings.xml
+++ b/java/res/values-sk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti zadávania textu a údajov"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Príkazy denníka výskumu"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Vyhľadať kontakty"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Kontrola pravopisu používa záznamy z vášho zoznamu kontaktov"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Pri stlačení klávesu vibrovať"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Navrhnúť mená kontaktov"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Používať mená z Kontaktov na návrhy a opravy"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Prispôsobené návrhy"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Bodka s medzerou"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dvojitým klepnutím na medzerník vložíte bodku a medzeru."</string>
<string name="auto_cap" msgid="1719746674854628252">"Veľké písmená automaticky"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Jazyky vstupu"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Opätovným dotykom uložíte"</string>
<string name="has_dictionary" msgid="6071847973466625007">"K dispozícii je slovník"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Povoliť spätnú väzbu od používateľov"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Automatickým zasielaním štatistík o využívaní editora metódy vstupu a správ o jeho zlyhaní môžete prispieť k vylepšeniu tohto nástroja"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Motív klávesnice"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Anglická klávesnica (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Anglická klávesnica (US)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Povoliť"</string>
<string name="not_now" msgid="6172462888202790482">"Teraz nie"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Rovnaký štýl vstupu už existuje: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Režim štúdie použiteľnosti"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Oneskor. pri stlač. a podržaní"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Trvanie vibrov. pri stlač. kl."</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Hlasitosť pri stlačení klávesu"</string>
diff --git a/java/res/values-sl/strings-action-keys.xml b/java/res/values-sl/strings-action-keys.xml
index 0235887af..f8b764723 100644
--- a/java/res/values-sl/strings-action-keys.xml
+++ b/java/res/values-sl/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Prej."</string>
<string name="label_done_key" msgid="7564866296502630852">"Konec"</string>
<string name="label_send_key" msgid="482252074224462163">"Pošl."</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Zaus."</string>
<string name="label_wait_key" msgid="5891247853595466039">"Čakaj"</string>
</resources>
diff --git a/java/res/values-sl/strings-talkback-descriptions.xml b/java/res/values-sl/strings-talkback-descriptions.xml
index 280393a70..27b8d3d6c 100644
--- a/java/res/values-sl/strings-talkback-descriptions.xml
+++ b/java/res/values-sl/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Ni vnesenega besedila"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Tipka <xliff:g id="KEY_NAME">%1$s</xliff:g> popravi <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> v <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Tipka <xliff:g id="KEY_NAME">%1$s</xliff:g> izvede samopopravek"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Koda tipke %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Tipka Shift je vklopljena (dotaknite se, da jo onemogočite)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Tipka Caps lock je vklopljena (dotaknite se, da jo onemogočite)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Več simbolov"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simboli"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Izbriši"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simboli"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Črke"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Nazaj"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Način »Shift« je omogočen"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Funkcija »Caps Lock« je omogočena"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Način »Shift« je onemogočen"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Način simbolov"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Način za več simbolov"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Način črk"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Način telefona"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Način simbolov telefona"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Mesta"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simboli"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Čustveni simboli"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-sl/strings.xml b/java/res/values-sl/strings.xml
index 2594aaec4..85d40f4c9 100644
--- a/java/res/values-sl/strings.xml
+++ b/java/res/values-sl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Možnosti vnosa"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Ukazi za dnevnik raziskav"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Iskanje imen stikov"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Črkovalnik uporablja vnose s seznama stikov"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibriranje ob pritisku tipke"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Predlagaj imena stikov"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Uporaba imen iz stikov za predloge in popravke"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Prilagojeni predlogi"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dva presl. za vnos pike"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Z dvojnim dotikom preslednice vstavite piko in za njo presledek"</string>
<string name="auto_cap" msgid="1719746674854628252">"Samod. velike začetnice"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Jeziki vnosa"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Dotaknite se še enkrat, da shranite"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Slovar je na voljo"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Omogoči povratne informacije uporabnikov"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"S samodejnim pošiljanjem statističnih podatkov o uporabi in poročil o zrušitvah nam pomagate izboljšati urejevalnik načina vnosa."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema tipkovnice"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"angleščina (Združeno kraljestvo)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"angleščina (ZDA)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Omogoči"</string>
<string name="not_now" msgid="6172462888202790482">"Ne zdaj"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Isti slog vnosa že obstaja: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Način za preučevanje uporabnosti"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Zakasn. za dolg pritisk tipke"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Trajanje vibr. ob prit. tipke"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Glasn. zvoka ob pritisku tipke"</string>
diff --git a/java/res/values-sr/strings-action-keys.xml b/java/res/values-sr/strings-action-keys.xml
index 1ce0ed7fb..b3d9411c7 100644
--- a/java/res/values-sr/strings-action-keys.xml
+++ b/java/res/values-sr/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Претх"</string>
<string name="label_done_key" msgid="7564866296502630852">"Готов"</string>
<string name="label_send_key" msgid="482252074224462163">"Шаљи"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Пауза"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Чекај"</string>
</resources>
diff --git a/java/res/values-sr/strings-talkback-descriptions.xml b/java/res/values-sr/strings-talkback-descriptions.xml
index 402d45b91..d47258177 100644
--- a/java/res/values-sr/strings-talkback-descriptions.xml
+++ b/java/res/values-sr/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Текст није унет"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> исправља <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> у <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> обавља аутоматско исправљање"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Кôд тастера %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift је укључен (додирните да бисте га онемогућили)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock је укључен (додирните да бисте га онемогућили)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Још симбола"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Симболи"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Избриши"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Симболи"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Слова"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Следеће"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift је омогућен"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock је омогућен"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift је онемогућен"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Режим симбола"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Режим Још симбола"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Режим слова"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Режим телефона"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Режим симбола телефона"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Места"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Симболи"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Емотикони"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-sr/strings.xml b/java/res/values-sr/strings.xml
index 7bd7f67e5..1862e8539 100644
--- a/java/res/values-sr/strings.xml
+++ b/java/res/values-sr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Опције уноса"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Команде евиденције истраживања"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Потражи имена контаката"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Контролор правописа користи уносе са листе контаката"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Вибрирај на притисак тастера"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Предложи имена контаката"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Користи имена из Контаката за предлоге и исправке"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Персонализовани предлози"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Тачка и размак"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Двоструким додиром размака умеће се тачка праћена размаком"</string>
<string name="auto_cap" msgid="1719746674854628252">"Аутоматски унос великих слова"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Језици уноса"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Поново додирните да бисте сачували"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Речник је доступан"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Омогући повратну информацију корисника"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Помозите нам да побољшамо овај уређивач метода уноса тако што ћете аутоматски слати статистику коришћења и извештаје о отказивању"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема тастатуре"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"енглески (УК)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"енглески (САД)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Омогући"</string>
<string name="not_now" msgid="6172462888202790482">"Не сада"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Исти стил уноса већ постоји: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим за студију могућности коришћења"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Одлагање при дугом притиску"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Трајање вибрације при притиску"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Јачина звука при притиску"</string>
diff --git a/java/res/values-sv/strings-action-keys.xml b/java/res/values-sv/strings-action-keys.xml
index e13860811..053461d07 100644
--- a/java/res/values-sv/strings-action-keys.xml
+++ b/java/res/values-sv/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Föreg"</string>
<string name="label_done_key" msgid="7564866296502630852">"Klart"</string>
<string name="label_send_key" msgid="482252074224462163">"Sänd"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pausa"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Vänta"</string>
</resources>
diff --git a/java/res/values-sv/strings-talkback-descriptions.xml b/java/res/values-sv/strings-talkback-descriptions.xml
index 140202d99..9824b5a7c 100644
--- a/java/res/values-sv/strings-talkback-descriptions.xml
+++ b/java/res/values-sv/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Ingen text har angetts"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Om du trycker på <xliff:g id="KEY_NAME">%1$s</xliff:g> rättas <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> till <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Om du trycker på <xliff:g id="KEY_NAME">%1$s</xliff:g> utförs autokorrigering"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Nyckelkod %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Skift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Skift är aktiverat (tryck för att inaktivera)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock på (tryck för att inaktivera)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Fler symboler"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Skift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Symboler"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Skift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Ta bort"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Symboler"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Bokstäver"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Föregående"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Skift aktiverat"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock är aktiverat"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Skift är inaktiverat"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbolläge"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Läge med fler symboler"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Bokstavsläge"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefonläge"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefonsymbolläge"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Platser"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Symboler"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Uttryckssymboler"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-sv/strings.xml b/java/res/values-sv/strings.xml
index 7092e6876..606140466 100644
--- a/java/res/values-sv/strings.xml
+++ b/java/res/values-sv/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Inmatningsalternativ"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Loggkommandon"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Sök namn på kontakter"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"I stavningskontrollen används poster från kontaktlistan"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Vibrera vid tangenttryck"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Föreslå kontaktnamn"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Använd namn från Kontakter för förslag och korrigeringar"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Anpassade förslag"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dubbelt blanksteg = punkt"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Dubbelt blanksteg ger en punkt följt av mellanslag"</string>
<string name="auto_cap" msgid="1719746674854628252">"Automatiska versaler"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Inmatningsspråk"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Spara genom att trycka igen"</string>
<string name="has_dictionary" msgid="6071847973466625007">"En ordlista är tillgänglig"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Aktivera synpunkter från användare"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Du kan hjälpa till att förbättra inmatningsmetoden genom att automatiskt skicka användningsstatistik och felrapporter"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tangentbordstema"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Engelskt (brittiskt)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Engelskt (amerikanskt)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Aktivera"</string>
<string name="not_now" msgid="6172462888202790482">"Inte nu"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Samma indatastil finns redan: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Läge för studie av användbarhet"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Fördröjning vid långt tryck"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Vibrationslängd för tangenter"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Ljudvolym för tangenter"</string>
diff --git a/java/res/values-sw/strings-action-keys.xml b/java/res/values-sw/strings-action-keys.xml
index 7d8822e80..587cbfa6a 100644
--- a/java/res/values-sw/strings-action-keys.xml
+++ b/java/res/values-sw/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Nyuma"</string>
<string name="label_done_key" msgid="7564866296502630852">"Imekamilika"</string>
<string name="label_send_key" msgid="482252074224462163">"Tuma"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Sitisha"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Subiri"</string>
</resources>
diff --git a/java/res/values-sw/strings-talkback-descriptions.xml b/java/res/values-sw/strings-talkback-descriptions.xml
index e9ca282b9..e00ce6a9b 100644
--- a/java/res/values-sw/strings-talkback-descriptions.xml
+++ b/java/res/values-sw/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Hakuna maandishi yaliyoingizwa"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> hurekebisha <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> kuwa <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> hufanya marekebisho otomatiki"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Msimbo wa kitufe %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift imewashwa (gonga ili kuizima)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock imewashwa (gonga ili kuizima)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Alama zaidi"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Alama"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Futa"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Alama"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Herufi"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Iililotangulia"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift imewashwa"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps lock imewashwa"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift imezimwa"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Hali ya alama"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Hali ya alama zaidi"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Hali ya herufi"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Hali ya simu"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Hali ya alama za simu"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Maeneo"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Alama"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Vikaragosi"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-sw/strings.xml b/java/res/values-sw/strings.xml
index 56312899d..2d130e0bf 100644
--- a/java/res/values-sw/strings.xml
+++ b/java/res/values-sw/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Chaguo za uingizaji"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Amri za Kumbukumbu za Utafiti"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Angalia majina ya unaowasiliana nao"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Kikagua tahajia hutumia majina yaliyoingizwa katika orodha yako ya anwani"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Tetema unabofya kitufe"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Pendekeza majini ya Anwani"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Tumia majina kutoka kwa Anwani kwa mapendekezo na marekebisho"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Mapendekezo yaliyobadilishwa kukufaa"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Kitone baada ya nafasi mbili"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Kugonga mara mbili kwenye upau nafasi kunaingiza kitone kikifuatiwa na nafasi"</string>
<string name="auto_cap" msgid="1719746674854628252">"Uwekaji wa herufi kubwa kiotomatiki"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Lugha zinazoruhusiwa"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Gusa tena ili kuhifadhi"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Kamusi inapatikana"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Wezesha maoni ya watumiaji"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Saidia kuimarisha mbinu hii ya uingizaji wa kihariri, kwa kutuma takwimu za matumizi na ripoti za kuvurugika kiotomatiki"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Maandhari ya kibodi"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Kiingereza cha (Uingereza)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Kiingereza cha (Marekani)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Washa"</string>
<string name="not_now" msgid="6172462888202790482">"Sio sasa"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Mfumo sawa wa maingizo tayari upo: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Modi ya uchunguzi wa utumizi"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ubofyaji kitufe kunakochelewa"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Bonyeza kitufe cha muda wa kutetema"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Bonyeza kitufe cha kiwango cha sauti"</string>
diff --git a/java/res/values-sw600dp-land/config.xml b/java/res/values-sw600dp-land/config.xml
index 00edde161..ba8b52f0b 100644
--- a/java/res/values-sw600dp-land/config.xml
+++ b/java/res/values-sw600dp-land/config.xml
@@ -48,7 +48,9 @@
<fraction name="config_key_letter_ratio_5row">62%</fraction>
<fraction name="config_key_shifted_letter_hint_ratio_5row">36%</fraction>
- <dimen name="config_suggestions_strip_horizontal_padding">252.0dp</dimen>
+ <dimen name="config_suggestions_strip_height">44dp</dimen>
+ <dimen name="config_suggestions_strip_horizontal_margin">180.0dp</dimen>
+ <dimen name="config_suggestions_strip_edge_key_width">54dp</dimen>
<integer name="config_max_more_suggestions_row">5</integer>
<fraction name="config_min_more_suggestions_width">50%</fraction>
diff --git a/java/res/values-sw600dp/config.xml b/java/res/values-sw600dp/config.xml
index 3bd843928..d97538de0 100644
--- a/java/res/values-sw600dp/config.xml
+++ b/java/res/values-sw600dp/config.xml
@@ -63,12 +63,13 @@
<fraction name="config_key_shifted_letter_hint_ratio_5row">27%</fraction>
<dimen name="config_suggestions_strip_height">44dp</dimen>
+ <dimen name="config_suggestions_strip_horizontal_margin">54dp</dimen>
+ <dimen name="config_suggestions_strip_edge_key_width">54dp</dimen>
<dimen name="config_more_suggestions_row_height">44dp</dimen>
<integer name="config_max_more_suggestions_row">6</integer>
<fraction name="config_min_more_suggestions_width">90%</fraction>
- <dimen name="config_suggestions_strip_horizontal_padding">94.5dp</dimen>
<dimen name="config_suggestion_min_width">48.0dp</dimen>
- <dimen name="config_suggestion_text_horizontal_padding">12dp</dimen>
+ <dimen name="config_suggestion_text_horizontal_padding">10dp</dimen>
<dimen name="config_suggestion_text_size">22dp</dimen>
<dimen name="config_more_suggestions_hint_text_size">33dp</dimen>
diff --git a/java/res/values-sw768dp-land/config.xml b/java/res/values-sw768dp-land/config.xml
index 3878a9e84..63f86ba81 100644
--- a/java/res/values-sw768dp-land/config.xml
+++ b/java/res/values-sw768dp-land/config.xml
@@ -49,7 +49,9 @@
<fraction name="config_key_letter_ratio_5row">53%</fraction>
<fraction name="config_key_shifted_letter_hint_ratio_5row">30%</fraction>
- <dimen name="config_suggestions_strip_horizontal_padding">252.0dp</dimen>
+ <dimen name="config_suggestions_strip_height">44dp</dimen>
+ <dimen name="config_suggestions_strip_horizontal_margin">340dp</dimen>
+ <dimen name="config_suggestions_strip_edge_key_width">54dp</dimen>
<fraction name="config_min_more_suggestions_width">50%</fraction>
<!-- Gesture floating preview text parameters -->
diff --git a/java/res/values-sw768dp/config.xml b/java/res/values-sw768dp/config.xml
index 34eec38b8..94b38d850 100644
--- a/java/res/values-sw768dp/config.xml
+++ b/java/res/values-sw768dp/config.xml
@@ -61,12 +61,13 @@
<fraction name="config_key_shifted_letter_hint_ratio_5row">33%</fraction>
<dimen name="config_suggestions_strip_height">44dp</dimen>
+ <dimen name="config_suggestions_strip_horizontal_margin">100dp</dimen>
+ <dimen name="config_suggestions_strip_edge_key_width">54dp</dimen>
<dimen name="config_more_suggestions_row_height">44dp</dimen>
<integer name="config_max_more_suggestions_row">6</integer>
<fraction name="config_min_more_suggestions_width">90%</fraction>
- <dimen name="config_suggestions_strip_horizontal_padding">94.5dp</dimen>
<dimen name="config_suggestion_min_width">46dp</dimen>
- <dimen name="config_suggestion_text_horizontal_padding">8dp</dimen>
+ <dimen name="config_suggestion_text_horizontal_padding">10dp</dimen>
<dimen name="config_suggestion_text_size">22dp</dimen>
<dimen name="config_more_suggestions_hint_text_size">33dp</dimen>
diff --git a/java/res/values-th/strings-action-keys.xml b/java/res/values-th/strings-action-keys.xml
index f23bfbc2a..6cbd491f9 100644
--- a/java/res/values-th/strings-action-keys.xml
+++ b/java/res/values-th/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"ก่อน"</string>
<string name="label_done_key" msgid="7564866296502630852">"เสร็จ"</string>
<string name="label_send_key" msgid="482252074224462163">"ส่ง"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"หยุด"</string>
<string name="label_wait_key" msgid="5891247853595466039">"รอ"</string>
</resources>
diff --git a/java/res/values-th/strings-talkback-descriptions.xml b/java/res/values-th/strings-talkback-descriptions.xml
index eb712aeac..81c86fd5b 100644
--- a/java/res/values-th/strings-talkback-descriptions.xml
+++ b/java/res/values-th/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"ไม่มีข้อความ"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> แก้ไข <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> เป็น <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> ทำการแก้ไขอัตโนมัติ"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"รหัสคีย์ %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift เปิดอยู่ (แตะเพื่อปิดใช้งาน)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock เปิดอยู่ (แตะเพื่อปิดใช้งาน)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"สัญลักษณ์เพิ่มเติม"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"สัญลักษณ์"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"ลบ"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"สัญลักษณ์"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"ตัวอักษร"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"ก่อนหน้า"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"เปิดใช้งาน Shift แล้ว"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"เปิดใช้งาน Caps Lock แล้ว"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"ปิดใช้งาน Shift แล้ว"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"โหมดสัญลักษณ์"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"โหมดสัญลักษณ์เพิ่มเติม"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"โหมดตัวอักษร"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"โหมดโทรศัพท์"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"โหมดสัญลักษณ์โทรศัพท์"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"สถานที่"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"สัญลักษณ์"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"ไอคอนสื่ออารมณ์"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-th/strings.xml b/java/res/values-th/strings.xml
index ece0c4ba9..83f196f87 100644
--- a/java/res/values-th/strings.xml
+++ b/java/res/values-th/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"ตัวเลือกการป้อนข้อมูล"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"คำสั่งบันทึกการวิจัย"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"ค้นหารายชื่อติดต่อ"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"เครื่องมือตรวจการสะกดใช้รายการจากรายชื่อติดต่อของคุณ"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"สั่นเมื่อกดปุ่ม"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"แนะนำชื่อผู้ติดต่อ"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"ใช้ชื่อจากรายชื่อติดต่อสำหรับคำแนะนำและการแก้ไข"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"คำแนะนำในแบบของคุณ"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"แตะ Space สองครั้งแทรกจุด"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"แตะ Spacebar สองครั้งจะแทรกจุดตามด้วยช่องว่างหนึ่งช่อง"</string>
<string name="auto_cap" msgid="1719746674854628252">"ปรับเป็นตัวพิมพ์ใหญ่อัตโนมัติ"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"ภาษาสำหรับการป้อนข้อมูล"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"แตะอีกครั้งเพื่อบัน​​ทึก"</string>
<string name="has_dictionary" msgid="6071847973466625007">"มีพจนานุกรมให้ใช้งาน"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"เปิดใช้งานการแสดงความคิดเห็นจากผู้ใช้"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"ช่วยปรับปรุงตัวแก้ไขวิธีการป้อนข้อมูลนี้โดยการส่งสถิติการใช้งานและรายงานการขัดข้องโดยอัตโนมัติ"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"ชุดรูปแบบแป้นพิมพ์"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"อังกฤษ (สหราชอาณาจักร)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"อังกฤษ (อเมริกัน)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"เปิดใช้งาน"</string>
<string name="not_now" msgid="6172462888202790482">"ข้ามไปก่อน"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"รูปแบบการป้อนข้อมูลเดียวกันนี้มีอยู่แล้ว: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"โหมดศึกษาประโยชน์ในการใช้งาน"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"การหน่วงเวลาของการกดแป้นค้าง"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"ระยะเวลาการสั่นเมื่อกดแป้นพิมพ์"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"ระดับเสียงเมื่อกดแป้นพิมพ์"</string>
diff --git a/java/res/values-tl/strings-action-keys.xml b/java/res/values-tl/strings-action-keys.xml
index a7f4cc78f..ac511d03f 100644
--- a/java/res/values-tl/strings-action-keys.xml
+++ b/java/res/values-tl/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Nauna"</string>
<string name="label_done_key" msgid="7564866296502630852">"Tapos"</string>
<string name="label_send_key" msgid="482252074224462163">"Send"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Pause"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Intay"</string>
</resources>
diff --git a/java/res/values-tl/strings-talkback-descriptions.xml b/java/res/values-tl/strings-talkback-descriptions.xml
index fbf276be8..06ba9211d 100644
--- a/java/res/values-tl/strings-talkback-descriptions.xml
+++ b/java/res/values-tl/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Walang tekstong inilagay"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"Itinatama ng <xliff:g id="KEY_NAME">%1$s</xliff:g> ang <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> sa <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"Nagsasagawa ang <xliff:g id="KEY_NAME">%1$s</xliff:g> ng auto-correction"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Key code %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Naka-on ang shift (i-tap upang i-disable)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Naka-on ang caps lock (i-tap upang i-disable)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Marami pang simbolo"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Mga Simbolo"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Tanggalin"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Mga Simbolo"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Mga Titik"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Nauna"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Naka-enable ang shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Naka-enable ang caps lock"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Naka-disable ang shift"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Symbols mode"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Mode na marami pang simbolo"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Letters mode"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Phone mode"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Phone symbols mode"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Mga Lugar"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Mga Simbolo"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Mga Emoticon"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-tl/strings.xml b/java/res/values-tl/strings.xml
index ce1207a5f..b9216a607 100644
--- a/java/res/values-tl/strings.xml
+++ b/java/res/values-tl/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Mga pagpipilian sa input"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Cmmnd sa Log ng Pnnliksik"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Maghanap pangalan contact"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Gumagamit ang Spell Checker ng entries mula sa iyong contact list."</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Mag-vibrate sa keypress"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Mungkahi pangalan Contact"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Gamitin pangalan mula Mga Contact sa mga mungkahi\'t pagwawasto"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Personalized suggestions"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Double-space period"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Naglalagay ng tuldok na may puwang ang pag-double tap sa spacebar"</string>
<string name="auto_cap" msgid="1719746674854628252">"Auto-capitalization"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Mga wika ng input"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Pinduting muli upang i-save"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Available ang diksyunaryo"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Paganahin ang feedback ng user"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Tumulong na pahusayin ang editor ng pamamaraan ng pag-input na ito sa pamamagitan ng awtomatikong pagpapadala ng mga istatistika ng paggamit at ulat ng pag-crash"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Tema ng keyboard"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Ingles (UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Ingles (Estados Unidos)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Paganahin"</string>
<string name="not_now" msgid="6172462888202790482">"Hindi ngayon"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Umiiral na ang parehong estilo ng input: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Study mode ng pagiging kapaki-pakinabang"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Key long press delay"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Tagal ng vibration ng keypress"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Volume ng tunog ng keypress"</string>
diff --git a/java/res/values-tr/strings-action-keys.xml b/java/res/values-tr/strings-action-keys.xml
index b34c576b6..5592e6c69 100644
--- a/java/res/values-tr/strings-action-keys.xml
+++ b/java/res/values-tr/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Geri"</string>
<string name="label_done_key" msgid="7564866296502630852">"Bitti"</string>
<string name="label_send_key" msgid="482252074224462163">"Gönder"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Dur"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Bekle"</string>
</resources>
diff --git a/java/res/values-tr/strings-talkback-descriptions.xml b/java/res/values-tr/strings-talkback-descriptions.xml
index d06c9009c..a3f635cb9 100644
--- a/java/res/values-tr/strings-talkback-descriptions.xml
+++ b/java/res/values-tr/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Metin girilmedi"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g>, <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> kelimesini <xliff:g id="CORRECTED_WORD">%3$s</xliff:g> olarak düzeltir"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> otomatik düzeltme yapar"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Tuş kodu: %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Üst karakter"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Üst karakter açık (devre dışı bırakmak için hafifçe vurun)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Büyük harf kilidi açık (devre dışı bırakmak için hafifçe vurun)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Diğer simgeler"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Üst karakter"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Simgeler"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Üst karakter"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Sil"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Simgeler"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Harfler"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Önceki"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Üst karakter etkin"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Büyük harf etkin"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Üst karakter devre dışı"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Sembol modu"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Diğer simgeler modu"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Harf modu"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Telefon modu"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Telefon sembolleri modu"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Yerler"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Simgeler"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"İfadeler"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-tr/strings.xml b/java/res/values-tr/strings.xml
index 3584ec5db..b1573c3d8 100644
--- a/java/res/values-tr/strings.xml
+++ b/java/res/values-tr/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Giriş seçenekleri"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Araştırma Günlüğü Komutları"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Kişi adlarını denetle"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Yazım denetleyici, kişi listenizdeki girişleri kullanır"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Tuşa basıldığında titret"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Kişi Adları öner"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Öneri ve düzeltmeler için Kişiler\'deki adları kullan"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Kişisel öneriler"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Çift boşlukla nokta ekleme"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Boşluk çubuğuna iki kez vurmak nokta ve ardından bir boşluk ekler"</string>
<string name="auto_cap" msgid="1719746674854628252">"Otomatik olarak büyük harf yap"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Giriş dilleri"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Kaydetmek için tekrar dokunun"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Sözlük kullanılabilir"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Kullanıcı geri bildirimini etkinleştir"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Kullanım istatistiklerini ve kilitlenme raporlarını otomatik olarak göndererek bu giriş yöntemi düzenleyicisinin iyileştirilmesine yardımcı olun."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Klavye teması"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"İngilizce (BK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"İngilizce (ABD)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Etkinleştir"</string>
<string name="not_now" msgid="6172462888202790482">"Şimdi değil"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Aynı giriş stili zaten var: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Kullanılabilirlik çalışması modu"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Tuşa uzun basma gecikmesi"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Tuşa basma titreşim süresi"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Tuşa basma ses seviyesi"</string>
diff --git a/java/res/values-uk/strings-action-keys.xml b/java/res/values-uk/strings-action-keys.xml
index 3e5762b3f..8b71498c1 100644
--- a/java/res/values-uk/strings-action-keys.xml
+++ b/java/res/values-uk/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Назад"</string>
<string name="label_done_key" msgid="7564866296502630852">"ОК"</string>
<string name="label_send_key" msgid="482252074224462163">"Слати"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Пауза"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Ждати"</string>
</resources>
diff --git a/java/res/values-uk/strings-talkback-descriptions.xml b/java/res/values-uk/strings-talkback-descriptions.xml
index 9b6d1142d..e4df115ae 100644
--- a/java/res/values-uk/strings-talkback-descriptions.xml
+++ b/java/res/values-uk/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Текст не введено"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> виправляє слово \"<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>\" на \"<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>\""</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> автоматично виправляє"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Код клавіші – %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift увімкнено (торкніться, щоб вимкнути)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps Lock увімкнено (торкніться, щоб вимкнути)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Більше символів"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Клавіша Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Символи"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Клавіша Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Видалити"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Символи"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Літери"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Назад"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift увімкнено"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Caps Lock увімкнено"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift вимкнено"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Режим символів"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Режим \"Більше символів\""</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Режим літер"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Режим номерів телефону"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Режим телефонних символів"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Місця"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Символи"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Смайли"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-uk/strings.xml b/java/res/values-uk/strings.xml
index 15a30805e..f2993fc03 100644
--- a/java/res/values-uk/strings.xml
+++ b/java/res/values-uk/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Парам. введення"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Команди журналу дослідж."</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Шукати імена контактів"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Програма перевірки правопису використ. записи зі списку контактів"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Вібр. при натисканні клавіш"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Пропон. імена контактів"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Використ. імена зі списку контактів для пропозицій і виправлень"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Персональні пропозиції"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Крапка подвійним пробілом"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Подвійне натискання пробілу вставляє крапку з пробілом після неї"</string>
<string name="auto_cap" msgid="1719746674854628252">"Авто викор. вел. літер"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Мови введення"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Торкніться знову, щоб зберегти"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Словник доступний"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Увімк. відгуки корист."</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Допоможіть покращити цей редактор методу введення, автоматично надсилаючи в Google статистику використання та звіти про аварійне завершення роботи."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Тема клавіатури"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Англійська (Великобританія)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Англійська (США)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Увімкнути"</string>
<string name="not_now" msgid="6172462888202790482">"Не зараз"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Такий стиль введення вже існує: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Режим вивчення зручності у використанні"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Затримка довгого натискання"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Вібрація при натисканні клавіш"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Гучність натискання клавіш"</string>
diff --git a/java/res/values-v20/platform-theme.xml b/java/res/values-v20/platform-theme.xml
index 06062047b..52e7f3521 100644
--- a/java/res/values-v20/platform-theme.xml
+++ b/java/res/values-v20/platform-theme.xml
@@ -21,6 +21,6 @@
<!-- TODO: This file is temporarily placed under values-v20. -->
<!-- TODO: It might be moved under values-v21. -->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="platformActivityTheme" parent="@android:style/Theme.Quantum.Light" />
- <style name="platformDialogTheme" parent="@android:style/Theme.Quantum.Light.Dialog" />
+ <style name="platformActivityTheme" parent="@android:style/Theme.Material.Light" />
+ <style name="platformDialogTheme" parent="@android:style/Theme.Material.Light.Dialog" />
</resources>
diff --git a/java/res/values-vi/strings-action-keys.xml b/java/res/values-vi/strings-action-keys.xml
index ceb780ed1..16b7c959e 100644
--- a/java/res/values-vi/strings-action-keys.xml
+++ b/java/res/values-vi/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Trước"</string>
<string name="label_done_key" msgid="7564866296502630852">"Xong"</string>
<string name="label_send_key" msgid="482252074224462163">"Gửi"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Tdừng"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Đợi"</string>
</resources>
diff --git a/java/res/values-vi/strings-talkback-descriptions.xml b/java/res/values-vi/strings-talkback-descriptions.xml
index 9202883c8..ad63fa52f 100644
--- a/java/res/values-vi/strings-talkback-descriptions.xml
+++ b/java/res/values-vi/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Không có ký tự nào được nhập"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"<xliff:g id="KEY_NAME">%1$s</xliff:g> sửa <xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> thành <xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"<xliff:g id="KEY_NAME">%1$s</xliff:g> tự động sửa"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Mã phím %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift đang bật (nhấn để tắt)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Caps lock đang bật (nhấn để tắt)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Biểu tượng khác"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Biểu tượng"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Xóa"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Biểu tượng"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Chữ cái"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Trước"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Đã bật Shift"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Đã bật Caps lock"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Đã tắt Shift"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Chế độ biểu tượng"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Chế độ biểu tượng khác"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Chế độ chữ cái"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Chế độ điện thoại"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Chế độ biểu tượng điện thoại"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Địa điểm"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Biểu tượng"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Biểu tượng cảm xúc"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-vi/strings.xml b/java/res/values-vi/strings.xml
index 529dcec17..5a47ad06a 100644
--- a/java/res/values-vi/strings.xml
+++ b/java/res/values-vi/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Tùy chọn nhập"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Lệnh ghi nhật ký cho nghiên cứu"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Tra cứu tên liên hệ"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Trình kiểm tra chính tả sử dụng các mục nhập từ danh sách liên hệ của bạn"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Rung khi nhấn phím"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Đề xuất tên liên hệ"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Sử dụng tên từ Danh bạ cho các đề xuất và chỉnh sửa"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Đề xuất được cá nhân hóa"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Dấu cách đôi"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Nhấn đúp vào phím cách sẽ chèn thêm một dấu sau dấu cách"</string>
<string name="auto_cap" msgid="1719746674854628252">"Tự động viết hoa"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Ngôn ngữ nhập"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Chạm lại để lưu"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Có sẵn từ điển"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Bật phản hồi của người dùng"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Giúp cải tiến trình chỉnh sửa phương thức nhập này bằng cách tự động gửi thống kê sử dụng và báo cáo sự cố"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Chủ đề bàn phím"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"Tiếng Anh (Anh)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"Tiếng Anh (Mỹ)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Bật"</string>
<string name="not_now" msgid="6172462888202790482">"Để sau"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Đã tồn tại kiểu nhập tương tự: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Chế độ nghiên cứu tính khả dụng"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Tgian chờ cho nhấn và giữ phím"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Thời gian rung khi nhấn phím"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Âm lượng khi nhấn phím"</string>
diff --git a/java/res/values-zh-rCN/strings-action-keys.xml b/java/res/values-zh-rCN/strings-action-keys.xml
index aacbb5fc7..a3629da2f 100644
--- a/java/res/values-zh-rCN/strings-action-keys.xml
+++ b/java/res/values-zh-rCN/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"上个"</string>
<string name="label_done_key" msgid="7564866296502630852">"完成"</string>
<string name="label_send_key" msgid="482252074224462163">"发送"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"暂停"</string>
<string name="label_wait_key" msgid="5891247853595466039">"等待"</string>
</resources>
diff --git a/java/res/values-zh-rCN/strings-talkback-descriptions.xml b/java/res/values-zh-rCN/strings-talkback-descriptions.xml
index 93f89e091..dda7638e4 100644
--- a/java/res/values-zh-rCN/strings-talkback-descriptions.xml
+++ b/java/res/values-zh-rCN/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"未输入文字"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"按<xliff:g id="KEY_NAME">%1$s</xliff:g>键可将<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>更正为<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"按<xliff:g id="KEY_NAME">%1$s</xliff:g>键可进行自动更正"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"键码为%d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"已开启Shift模式(点按即可关闭)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"已锁定大写模式(点按即可关闭)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"更多符号"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift键"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"符号"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift键"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"删除"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"符号"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"字母"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"上一个"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"已开启Shift模式"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"已锁定大写模式"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"已关闭Shift模式"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"符号模式"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"更多符号模式"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"字母模式"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"电话模式"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"电话符号模式"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"地点"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"符号"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"表情图标"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-zh-rCN/strings.xml b/java/res/values-zh-rCN/strings.xml
index 41fe0bfb6..7725118e8 100644
--- a/java/res/values-zh-rCN/strings.xml
+++ b/java/res/values-zh-rCN/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"输入选项"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"研究记录命令"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查找联系人姓名"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼写检查工具会使用您的联系人列表中的条目"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按键振动"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"联系人姓名建议"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"根据通讯录中的姓名提供建议和更正"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"个性化建议"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"双击空格插入句号"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"双击空格键可插入句号并后跟空格"</string>
<string name="auto_cap" msgid="1719746674854628252">"自动大写"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"输入语言"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"再次触摸即可保存"</string>
<string name="has_dictionary" msgid="6071847973466625007">"有可用词典"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"启用用户反馈"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"自动发送使用情况统计信息和崩溃报告,帮助改进此输入法。"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"键盘主题"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英语(英国)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英语(美国)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"启用"</string>
<string name="not_now" msgid="6172462888202790482">"以后再说"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"已经存在相同的输入风格:<xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"可用性研究模式"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"按键长按延迟"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"按键振动时长"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"按键音量"</string>
diff --git a/java/res/values-zh-rHK/strings-action-keys.xml b/java/res/values-zh-rHK/strings-action-keys.xml
index e95251696..4dc5c8450 100644
--- a/java/res/values-zh-rHK/strings-action-keys.xml
+++ b/java/res/values-zh-rHK/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"上一步"</string>
<string name="label_done_key" msgid="7564866296502630852">"完成"</string>
<string name="label_send_key" msgid="482252074224462163">"傳送"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"暫停"</string>
<string name="label_wait_key" msgid="5891247853595466039">"等候"</string>
</resources>
diff --git a/java/res/values-zh-rHK/strings-talkback-descriptions.xml b/java/res/values-zh-rHK/strings-talkback-descriptions.xml
index 8b60504d9..a962492ed 100644
--- a/java/res/values-zh-rHK/strings-talkback-descriptions.xml
+++ b/java/res/values-zh-rHK/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"未輸入文字"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"按「<xliff:g id="KEY_NAME">%1$s</xliff:g>」可將「<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>」修正為「<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>」"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"按「<xliff:g id="KEY_NAME">%1$s</xliff:g>」可自動修正"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"按鍵代碼 %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift 鍵"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift 鍵已開啟 (輕按即可停用)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"大寫鎖定已開啟 (輕按即可停用)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"更多符號"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift 鍵"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"符號"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift 鍵"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"刪除"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"符號"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"字母"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"上一個"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift 鍵已啟用"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"大寫鎖定已啟用"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift 鍵已停用"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"符號模式"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"更多符號模式"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"字母模式"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"撥號模式"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"符號撥號模式"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"地點"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"符號"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"表情符號"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-zh-rHK/strings.xml b/java/res/values-zh-rHK/strings.xml
index 34fa9c037..564db46fe 100644
--- a/java/res/values-zh-rHK/strings.xml
+++ b/java/res/values-zh-rHK/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"輸入選項"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"研究記錄指令"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查找聯絡人姓名"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼字檢查程式使用您的聯絡人名單中的各項記錄"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"建議聯絡人名稱"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"使用「聯絡人」的名稱提供建議與修正"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"個人化建議"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"按兩下空格鍵插入句號"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"只要輕按兩下空格鍵,即可插入句號並在後面加上一個空格"</string>
<string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"輸入語言"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"再次輕觸即可儲存"</string>
<string name="has_dictionary" msgid="6071847973466625007">"可使用字典"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"啟用用戶意見反映"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"自動傳送使用統計資料和當機報告,協助改良這個輸入法編輯器"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英文 (英國)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英文 (美國)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"啟用"</string>
<string name="not_now" msgid="6172462888202790482">"暫時不要"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"已存在相同的輸入樣式:<xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"可用性研究模式"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"長按鍵延遲"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"按鍵震動時間"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"按鍵音量"</string>
diff --git a/java/res/values-zh-rTW/strings-action-keys.xml b/java/res/values-zh-rTW/strings-action-keys.xml
index 00daa5c63..9b8be9426 100644
--- a/java/res/values-zh-rTW/strings-action-keys.xml
+++ b/java/res/values-zh-rTW/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"返回"</string>
<string name="label_done_key" msgid="7564866296502630852">"完成"</string>
<string name="label_send_key" msgid="482252074224462163">"傳送"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"暫停"</string>
<string name="label_wait_key" msgid="5891247853595466039">"等待"</string>
</resources>
diff --git a/java/res/values-zh-rTW/strings-talkback-descriptions.xml b/java/res/values-zh-rTW/strings-talkback-descriptions.xml
index 6351a985a..c097b28b7 100644
--- a/java/res/values-zh-rTW/strings-talkback-descriptions.xml
+++ b/java/res/values-zh-rTW/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"未輸入文字"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"按下「<xliff:g id="KEY_NAME">%1$s</xliff:g>」可將「<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g>」修正為「<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>」"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"按下「<xliff:g id="KEY_NAME">%1$s</xliff:g>」可執行自動修正"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"按鍵代碼 %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"Shift 鍵"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"Shift 鍵已開啟 (輕按即可停用)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"大寫鎖定已開啟 (輕按即可停用)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"更多符號"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"Shift 鍵"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"符號"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"Shift 鍵"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"刪除"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"符號"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"字母"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"上一個"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"Shift 鍵已啟用"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"大寫鎖定已啟用"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"Shift 鍵已停用"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"符號模式"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"更多符號模式"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"字母模式"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"撥號模式"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"撥號符號模式"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"地點"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"符號"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"表情"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-zh-rTW/strings.xml b/java/res/values-zh-rTW/strings.xml
index 9c9f5e052..176d5b4a7 100644
--- a/java/res/values-zh-rTW/strings.xml
+++ b/java/res/values-zh-rTW/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"輸入選項"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"研究紀錄指令"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"查詢聯絡人姓名"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"拼字檢查程式使用您的聯絡人清單項目"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"按鍵時震動"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"聯絡人姓名建議"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"根據「聯絡人」名稱提供建議與修正"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"個人化建議"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"輕按兩下空格鍵即插入句號"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"輕按兩下空格鍵可插入句號另加一個空格"</string>
<string name="auto_cap" msgid="1719746674854628252">"自動大寫"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"輸入語言"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"再次輕觸即可儲存"</string>
<string name="has_dictionary" msgid="6071847973466625007">"可用的字典"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"啟用使用者意見回饋"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"自動傳送使用統計資料和當機報告,協助改善此輸入法編輯器"</string>
<string name="keyboard_layout" msgid="8451164783510487501">"鍵盤主題"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"英文 (英國)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"英文 (美國)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"啟用"</string>
<string name="not_now" msgid="6172462888202790482">"暫時不要"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"已存在相同的輸入樣式:<xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"使用習慣學習模式"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"按鍵長按延遲"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"按鍵震動持續時間"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"按鍵音量"</string>
diff --git a/java/res/values-zu/strings-action-keys.xml b/java/res/values-zu/strings-action-keys.xml
index 6cd5e8c99..5d60a6cca 100644
--- a/java/res/values-zu/strings-action-keys.xml
+++ b/java/res/values-zu/strings-action-keys.xml
@@ -25,6 +25,8 @@
<string name="label_previous_key" msgid="1421141755779895275">"Okwedlule"</string>
<string name="label_done_key" msgid="7564866296502630852">"Kwenziwe"</string>
<string name="label_send_key" msgid="482252074224462163">"Thumela"</string>
+ <!-- no translation found for label_search_key (7965186050435796642) -->
+ <skip />
<string name="label_pause_key" msgid="2225922926459730642">"Misa isikhashana"</string>
<string name="label_wait_key" msgid="5891247853595466039">"Linda"</string>
</resources>
diff --git a/java/res/values-zu/strings-talkback-descriptions.xml b/java/res/values-zu/strings-talkback-descriptions.xml
index e01f7347d..9f344d8bf 100644
--- a/java/res/values-zu/strings-talkback-descriptions.xml
+++ b/java/res/values-zu/strings-talkback-descriptions.xml
@@ -25,10 +25,13 @@
<string name="spoken_no_text_entered" msgid="1711276837961785646">"Awukho umbhalo ofakiwe"</string>
<string name="spoken_auto_correct" msgid="8989324692167993804">"I-<xliff:g id="KEY_NAME">%1$s</xliff:g> ilungisa i-<xliff:g id="ORIGINAL_WORD">%2$s</xliff:g> kube yi-<xliff:g id="CORRECTED_WORD">%3$s</xliff:g>"</string>
<string name="spoken_auto_correct_obscured" msgid="7769449372355268412">"I-<xliff:g id="KEY_NAME">%1$s</xliff:g> yenza ukulungisa okuzenzakalelayo"</string>
- <string name="spoken_description_unknown" msgid="2382510329910793539">"Ikhodi yokhiye %d"</string>
+ <!-- no translation found for spoken_description_unknown (5139930082759824442) -->
+ <skip />
<string name="spoken_description_shift" msgid="7209798151676638728">"U-Shift"</string>
- <string name="spoken_description_shift_shifted" msgid="1609924271343916689">"U-Shift uvuliwe (thepha ukuwuvimbela)"</string>
- <string name="spoken_description_caps_lock" msgid="5020582161133170892">"Ofeleba bavuliwe (thepha ukubavimbela)"</string>
+ <string name="spoken_description_symbols_shift" msgid="3483198879916435717">"Amasimbuli amaningi"</string>
+ <string name="spoken_description_shift_shifted" msgid="3122704922642232605">"U-Shift"</string>
+ <string name="spoken_description_symbols_shift_shifted" msgid="5179175466878186081">"Amasimbuli"</string>
+ <string name="spoken_description_caps_lock" msgid="1224851412185975036">"U-Shift"</string>
<string name="spoken_description_delete" msgid="3878902286264983302">"Susa"</string>
<string name="spoken_description_to_symbol" msgid="8244903740201126590">"Amasimbuli"</string>
<string name="spoken_description_to_alpha" msgid="4081215210530031950">"Izinhlamvu"</string>
@@ -46,8 +49,8 @@
<string name="spoken_description_action_previous" msgid="2919072174697865110">"Okwangaphambilini"</string>
<string name="spoken_description_shiftmode_on" msgid="5107180516341258979">"U-Shift uvunyelwe"</string>
<string name="spoken_description_shiftmode_locked" msgid="7307477738053606881">"Ofeleba bavunyelwe"</string>
- <string name="spoken_description_shiftmode_off" msgid="5039126122829961331">"U-Shift uvimbelwe"</string>
<string name="spoken_description_mode_symbol" msgid="111186851131446691">"Imodi yezimpawu"</string>
+ <string name="spoken_description_mode_symbol_shift" msgid="4305607977537665389">"Imodi yamasimbuli amaningi"</string>
<string name="spoken_description_mode_alpha" msgid="4676004119618778911">"Imodi yezinhlamvu"</string>
<string name="spoken_description_mode_phone" msgid="2061220553756692903">"Imodi yefoni"</string>
<string name="spoken_description_mode_phone_shift" msgid="7879963803547701090">"Imodi yezimpawu zefoni"</string>
@@ -69,4 +72,22 @@
<string name="spoken_descrption_emoji_category_places" msgid="1163315840948545317">"Izindawo"</string>
<string name="spoken_descrption_emoji_category_symbols" msgid="474680659024880601">"Amasimbuli"</string>
<string name="spoken_descrption_emoji_category_emoticons" msgid="456737544787823539">"Izithombe-mzwelo"</string>
+ <!-- no translation found for spoken_description_upper_case (4904835255229433916) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0049 (4743162182646977944) -->
+ <skip />
+ <!-- no translation found for spoken_letter_0130 (4766619646231612274) -->
+ <skip />
+ <!-- no translation found for spoken_symbol_unknown (717298227061173706) -->
+ <skip />
+ <!-- no translation found for spoken_emoji_unknown (5981009928135394306) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_keys_keyboard (6832897688371903747) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_keys_keyboard (3524914657934712026) -->
+ <skip />
+ <!-- no translation found for spoken_open_more_suggestions (4231720702882969760) -->
+ <skip />
+ <!-- no translation found for spoken_close_more_suggestions (9118455416075032839) -->
+ <skip />
</resources>
diff --git a/java/res/values-zu/strings.xml b/java/res/values-zu/strings.xml
index c79d81dcc..d330c0785 100644
--- a/java/res/values-zu/strings.xml
+++ b/java/res/values-zu/strings.xml
@@ -21,7 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_input_options" msgid="3909945612939668554">"Okukhethwa kukho kokungenayo"</string>
- <string name="english_ime_research_log" msgid="8492602295696577851">"Imiyalo yefayela lokungena lokucwaninga"</string>
<string name="use_contacts_for_spellchecking_option_title" msgid="5374120998125353898">"Bheka amagama woxhumana nabo"</string>
<string name="use_contacts_for_spellchecking_option_summary" msgid="8754413382543307713">"Isihloli sokupela sisebenzisa okungenayo kusuka kuhlu lalabo oxhumana nabo"</string>
<string name="vibrate_on_keypress" msgid="5258079494276955460">"Dlidlizelisa ngokucindezela inkinobho"</string>
@@ -47,6 +46,8 @@
<string name="use_contacts_dict" msgid="4435317977804180815">"Sikisela amagama Othintana nabo"</string>
<string name="use_contacts_dict_summary" msgid="6599983334507879959">"Amagama abasebenzisi kusuka Kothintana nabo bokusikisela nokulungisa"</string>
<string name="use_personalized_dicts" msgid="5167396352105467626">"Iziphakamiso ezenziwe okomuntu siqu"</string>
+ <!-- no translation found for enable_metrics_logging (5506372337118822837) -->
+ <skip />
<string name="use_double_space_period" msgid="8781529969425082860">"Isikhathi se-Double-space"</string>
<string name="use_double_space_period_summary" msgid="6532892187247952799">"Ukuthepha kabili kubha yesikhala kufaka isikhathi esilandelwa yisikhala"</string>
<string name="auto_cap" msgid="1719746674854628252">"Ukwenza ofeleba okuzenzakalelayo"</string>
@@ -84,8 +85,6 @@
<string name="select_language" msgid="3693815588777926848">"Izilimi zokufakwayo"</string>
<string name="hint_add_to_dictionary" msgid="573678656946085380">"Thinta futhi ukuze ulondoloze"</string>
<string name="has_dictionary" msgid="6071847973466625007">"Isichazamazwi siyatholakala"</string>
- <string name="prefs_enable_log" msgid="6620424505072963557">"Vumela impendulo yomsebenzisi"</string>
- <string name="prefs_description_log" msgid="7525225584555429211">"Siza ukuthuthukisa lo mhleli wendlela yokufaka ngokusithumela ngokuzenzakalela izibalo zokusetshenziswa nokukhubeka."</string>
<string name="keyboard_layout" msgid="8451164783510487501">"Indikimba yekhibhodi"</string>
<string name="subtype_en_GB" msgid="88170601942311355">"i-English(UK)"</string>
<string name="subtype_en_US" msgid="6160452336634534239">"i-English (US)"</string>
@@ -118,7 +117,6 @@
<string name="enable" msgid="5031294444630523247">"Nika amandla"</string>
<string name="not_now" msgid="6172462888202790482">"Hhayi manje"</string>
<string name="custom_input_style_already_exists" msgid="8008728952215449707">"Isitayela sokufaka esifanayo sesivele sikhona: <xliff:g id="INPUT_STYLE_NAME">%s</xliff:g>"</string>
- <string name="prefs_usability_study_mode" msgid="1261130555134595254">"Imodi yesitadi yokusebenziseka"</string>
<string name="prefs_key_longpress_timeout_settings" msgid="6102240298932897873">"Ukulibazisa ukucindezela isikhashana ukhiye"</string>
<string name="prefs_keypress_vibration_duration_settings" msgid="7918341459947439226">"Ubude besikhathi sokudlidliza ukucindezela ukhiye"</string>
<string name="prefs_keypress_sound_volume_settings" msgid="6027007337036891623">"Ivolumu yomsindo wokucindezela ukhiye"</string>
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 475e92f2e..a1f478bd5 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -41,13 +41,17 @@
</declare-styleable>
<declare-styleable name="KeyboardView">
- <!-- Image for the key. This image needs to be a {@link StateListDrawable}, with the
- following possible states: normal, pressed, checkable, checkable+pressed,
+ <!-- Background image for the key. This image needs to be a {@link StateListDrawable},
+ with the following possible states: normal, pressed, checkable, checkable+pressed,
checkable+checked, checkable+checked+pressed. -->
<attr name="keyBackground" format="reference" />
- <!-- Image for the functional key used in Emoji layout. -->
- <attr name="keyBackgroundEmojiFunctional" format="reference" />
-
+ <!-- Background image for the functional key. This image needs to be a
+ {@link StateListDrawable}, with the following possible states: normal, pressed. -->
+ <attr name="functionalKeyBackground" format="reference" />
+ <!-- Background image for the spacebar. This image needs to be a
+ {@link StateListDrawable}, with the following possible states: normal, pressed. -->
+ <attr name="spacebarBackground" format="reference" />
+ <attr name="spacebarIconWidthRatio" format="float" />
<!-- Horizontal padding of left/right aligned key label to the edge of the key. -->
<attr name="keyLabelHorizontalPadding" format="dimension" />
<!-- Right padding of hint letter to the edge of the key.-->
@@ -69,14 +73,11 @@
</declare-styleable>
<declare-styleable name="MainKeyboardView">
- <attr name="autoCorrectionSpacebarLedEnabled" format="boolean" />
- <attr name="autoCorrectionSpacebarLedIcon" format="reference" />
<!-- Size of the text for spacebar language label, in the proportion of key height. -->
<attr name="languageOnSpacebarTextRatio" format="fraction" />
<attr name="languageOnSpacebarTextColor" format="color" />
+ <attr name="languageOnSpacebarTextShadowRadius" format="float" />
<attr name="languageOnSpacebarTextShadowColor" format="color" />
- <!-- Background image for the spacebar. -->
- <attr name="spacebarBackground" format="reference" />
<!-- Fadeout animator for spacebar language label. -->
<attr name="languageOnSpacebarFinalAlpha" format="integer" />
<attr name="languageOnSpacebarFadeoutAnimator" format="reference" />
@@ -171,7 +172,18 @@
</declare-styleable>
<declare-styleable name="EmojiPalettesView">
- <attr name="emojiTabLabelColor" format="reference" />
+ <attr name="categoryIndicatorEnabled" format="boolean" />
+ <attr name="categoryIndicatorDrawable" format="reference" />
+ <attr name="categoryIndicatorBackground" format="reference" />
+ <attr name="categoryPageIndicatorColor" format="color" />
+ <attr name="categoryPageIndicatorBackground" format="color" />
+ <attr name="iconEmojiRecentsTab" format="reference" />
+ <attr name="iconEmojiCategory1Tab" format="reference" />
+ <attr name="iconEmojiCategory2Tab" format="reference" />
+ <attr name="iconEmojiCategory3Tab" format="reference" />
+ <attr name="iconEmojiCategory4Tab" format="reference" />
+ <attr name="iconEmojiCategory5Tab" format="reference" />
+ <attr name="iconEmojiCategory6Tab" format="reference" />
</declare-styleable>
<declare-styleable name="SuggestionStripView">
@@ -217,7 +229,12 @@
<attr name="iconSettingsKey" format="reference" />
<attr name="iconSpaceKey" format="reference" />
<attr name="iconEnterKey" format="reference" />
+ <attr name="iconGoKey" format="reference" />
<attr name="iconSearchKey" format="reference" />
+ <attr name="iconSendKey" format="reference" />
+ <attr name="iconNextKey" format="reference" />
+ <attr name="iconDoneKey" format="reference" />
+ <attr name="iconPreviousKey" format="reference" />
<attr name="iconTabKey" format="reference" />
<attr name="iconShortcutKey" format="reference" />
<attr name="iconSpaceKeyForNumberLayout" format="reference" />
@@ -279,6 +296,7 @@
<!-- This should be aligned with Key.LABEL_FLAGS__* -->
<flag name="alignLeft" value="0x01" />
<flag name="alignRight" value="0x02" />
+ <flag name="alignButtom" value="0x04" />
<flag name="alignLeftOfCenter" value="0x08" />
<flag name="fontNormal" value="0x10" />
<flag name="fontMonoSpace" value="0x20" />
@@ -304,6 +322,9 @@
<flag name="shiftedLetterActivated" value="0x20000" />
<!-- If true, use EditorInfo.actionLabel for the key label. -->
<flag name="fromCustomActionLabel" value="0x40000" />
+ <!-- If true, use functionalTextColor instead of ketTextColor to drawing the label on
+ the key -->
+ <flag name="followFunctionalTextColor" value="0x80000" />
<!-- If true, disable keyHintLabel. -->
<flag name="disableKeyHintLabel" value="0x40000000" />
<!-- If true, disable additionalMoreKeys. -->
@@ -360,6 +381,8 @@
<attr name="keyTextShadowColor" format="color" />
<!-- Color to use for the label in a key when in inactivated state. -->
<attr name="keyTextInactivatedColor" format="color" />
+ <!-- Color to use for the label in a key that has followFunctionalTextColor keyLabelFlags. -->
+ <attr name="functionalTextColor" format="color" />
<!-- Key hint letter (= one character hint label) color -->
<attr name="keyHintLetterColor" format="color" />
<!-- Key hint label color -->
@@ -414,7 +437,6 @@
<attr name="navigatePrevious" format="boolean" />
<attr name="passwordInput" format="boolean" />
<attr name="clobberSettingsKey" format="boolean" />
- <attr name="supportsSwitchingToShortcutIme" format="boolean" />
<attr name="hasShortcutKey" format="boolean" />
<attr name="languageSwitchKeyEnabled" format="boolean" />
<attr name="isMultiLine" format="boolean" />
@@ -431,6 +453,7 @@
<!-- This should be aligned with KeyboardId.IME_ACTION_* -->
<enum name="actionCustomLabel" value="0x100" />
</attr>
+ <attr name="isIconDefined" format="string" />
<attr name="localeCode" format="string" />
<attr name="languageCode" format="string" />
<attr name="countryCode" format="string" />
diff --git a/java/res/values/colors.xml b/java/res/values/colors.xml
index 824928c6b..0eee08de2 100644
--- a/java/res/values/colors.xml
+++ b/java/res/values/colors.xml
@@ -26,7 +26,6 @@
<color name="suggested_word_color_ics">#B233B5E5</color>
<color name="highlight_translucent_color_ics">#9933B5E5</color>
<color name="key_text_color_holo">@android:color/white</color>
- <color name="key_text_shadow_color_holo">@android:color/transparent</color>
<color name="key_text_inactivated_color_holo">#66E0E4E5</color>
<color name="key_hint_letter_color_holo">#80000000</color>
<color name="key_hint_label_color_holo">#A0FFFFFF</color>
@@ -35,21 +34,31 @@
<color name="spacebar_text_color_holo">#FFC0C0C0</color>
<color name="spacebar_text_shadow_color_holo">#80000000</color>
<color name="gesture_floating_preview_color_holo">#C0000000</color>
+ <color name="emoji_tab_page_indicator_background_holo">#111111</color>
<!-- Color resources for KLP theme. Base color = F0F0F0 -->
<color name="highlight_color_klp">#FFF0F0F0</color>
<color name="typed_word_color_klp">#D8F0F0F0</color>
<color name="suggested_word_color_klp">#B2F0F0F0</color>
<color name="highlight_translucent_color_klp">#99E0E0E0</color>
+ <!-- Color resources for LXX theme. Base color = F0F0F0 -->
+ <color name="key_text_color_lxx_dark">#FFFFFF</color>
+ <color name="key_text_inactive_color_lxx_dark">#808184</color>
+ <color name="key_hint_letter_color_lxx_dark">#808184</color>
+ <color name="highlight_color_lxx_dark">#7FCAC3</color>
+ <color name="typed_word_color_lxx_dark">#D87FCAC3</color>
+ <color name="suggested_word_color_lxx_dark">#B27FCAC3</color>
+ <color name="highlight_translucent_color_lxx_dark">#997FCAC3</color>
+ <color name="keyboard_background_lxx_dark">#384248</color>
+ <color name="key_background_lxx_dark">#384248</color>
+ <color name="key_background_pressed_lxx_dark">#546872</color>
+ <color name="suggestions_strip_background_lxx_dark">#263238</color>
+ <color name="suggested_word_background_selected_lxx_dark">#384248</color>
+ <color name="gesture_floating_preview_color_lxx_dark">#C0000000</color>
+ <color name="emoji_tab_page_indicator_background_lxx_dark">#263238</color>
<!-- Color resources for setup wizard and tutorial -->
<color name="setup_background">#FFEBEBEB</color>
<color name="setup_text_dark">#FF707070</color>
<color name="setup_text_action">@android:color/holo_blue_light</color>
<color name="setup_step_background">@android:color/background_light</color>
<color name="setup_welcome_video_margin_color">#FFCCCCCC</color>
- <color name="emoji_category_page_id_view_background">#FF000000</color>
- <color name="emoji_category_page_id_view_foreground">#80FFFFFF</color>
-
- <!-- TODO: Color which should be included in the theme -->
- <color name="emoji_key_background_color">#00000000</color>
- <color name="emoji_key_pressed_background_color">#30FFFFFF</color>
</resources>
diff --git a/java/res/values/config-common.xml b/java/res/values/config-common.xml
index 3fe4b947c..58f3e9827 100644
--- a/java/res/values/config-common.xml
+++ b/java/res/values/config-common.xml
@@ -24,9 +24,6 @@
at input history to suggest a hopefully helpful suggestions for the next word? -->
<bool name="config_default_next_word_prediction">true</bool>
- <!-- This configuration must be aligned with {@link KeyboardTheme#DEFAULT_THEME_ID}. -->
- <string name="config_default_keyboard_theme_id" translatable="false">2</string>
-
<integer name="config_delay_update_shift_state">100</integer>
<integer name="config_double_space_period_timeout">1100</integer>
@@ -51,6 +48,7 @@
<integer name="config_max_longpress_timeout">700</integer>
<integer name="config_min_longpress_timeout">100</integer>
<integer name="config_longpress_timeout_step">10</integer>
+ <integer name="config_accessibility_long_press_key_timeout">1500</integer>
<integer name="config_max_more_keys_column">5</integer>
<integer name="config_more_keys_keyboard_fadein_anim_time">0</integer>
<integer name="config_more_keys_keyboard_fadeout_anim_time">100</integer>
@@ -136,7 +134,7 @@
<integer name="config_gesture_trail_shadow_ratio">-1</integer>
<!-- Common configuration of Emoji keyboard -->
- <dimen name="config_emoji_category_page_id_height">3dp</dimen>
+ <dimen name="config_emoji_category_page_id_height">2dp</dimen>
<!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. -->
<dimen name="config_accessibility_edge_slop">8dp</dimen>
diff --git a/java/res/values/config.xml b/java/res/values/config.xml
index 45ea48392..9f556a6e4 100644
--- a/java/res/values/config.xml
+++ b/java/res/values/config.xml
@@ -64,10 +64,11 @@
<fraction name="config_key_shifted_letter_hint_ratio_5row">41%</fraction>
<dimen name="config_suggestions_strip_height">40dp</dimen>
+ <dimen name="config_suggestions_strip_horizontal_margin">36dp</dimen>
+ <dimen name="config_suggestions_strip_edge_key_width">36dp</dimen>
<dimen name="config_more_suggestions_row_height">40dp</dimen>
<integer name="config_max_more_suggestions_row">6</integer>
<fraction name="config_min_more_suggestions_width">90%</fraction>
- <dimen name="config_suggestions_strip_horizontal_padding">0dp</dimen>
<dimen name="config_suggestion_min_width">44dp</dimen>
<dimen name="config_suggestion_text_horizontal_padding">6dp</dimen>
<dimen name="config_suggestion_text_size">18dp</dimen>
diff --git a/java/res/values/donottranslate-config-spacing-and-punctuations.xml b/java/res/values/donottranslate-config-spacing-and-punctuations.xml
index 1be5cf888..2faf578d2 100644
--- a/java/res/values/donottranslate-config-spacing-and-punctuations.xml
+++ b/java/res/values/donottranslate-config-spacing-and-punctuations.xml
@@ -26,6 +26,8 @@
<string name="symbols_preceded_by_space">([{&amp;</string>
<!-- Symbols that are normally followed by a space (used to add an auto-space after these) -->
<string name="symbols_followed_by_space">.,;:!?)]}&amp;</string>
+ <!-- Symbols that behave like a single punctuation when typed next to each other -->
+ <string name="symbols_clustering_together"></string>
<!-- Symbols that separate words -->
<!-- Don't remove the enclosing double quotes, they protect whitespace (not just U+0020) -->
<string name="symbols_word_separators">"&#x0009;&#x0020;&#x000A;&#x00A0;"()[]{}*&amp;&lt;&gt;+=|.,;:!?/_\"</string>
diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml
index 9a610a0d0..83d082f82 100644
--- a/java/res/values/donottranslate.xml
+++ b/java/res/values/donottranslate.xml
@@ -47,17 +47,6 @@
<string name="prefs_debug_mode">Debug Mode</string>
<string name="prefs_force_non_distinct_multitouch">Force non-distinct multitouch</string>
- <!-- For keyboard color scheme option dialog. -->
- <string-array name="keyboard_theme_names">
- <item>@string/keyboard_color_scheme_white</item>
- <item>@string/keyboard_color_scheme_blue</item>
- </string-array>
- <!-- An element must be a keyboard theme id of {@link KeyboardTheme#THEME_ID_*}. -->
- <string-array name="keyboard_theme_ids">
- <item>2</item>
- <item>0</item>
- </string-array>
-
<!-- Subtype locale display name exceptions.
For each exception, there should be related string resources for display name that may have
explicit keyboard layout. The string resource name must be "subtype_<locale>" or
@@ -148,6 +137,4 @@
<item>tr:AsciiCapable,SupportTouchPositionCorrection,EmojiCapable</item>
<item>qwerty</item>
</string-array>
-
- <string name="settings_warning_researcher_mode">Attention! You are using the special keyboard for research purposes.</string>
</resources>
diff --git a/java/res/values/keyboard-icons-holo.xml b/java/res/values/keyboard-icons-holo.xml
index 4c888d570..669d2c07d 100644
--- a/java/res/values/keyboard-icons-holo.xml
+++ b/java/res/values/keyboard-icons-holo.xml
@@ -21,9 +21,6 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="KeyboardIcons.Holo">
<!-- Keyboard icons -->
- <!-- TODO: The following holo icon for phone (drawable-hdpi and drawable-xhdpi) are missing.
- sym_keyboard_123_mic_holo
- -->
<item name="iconShiftKey">@drawable/sym_keyboard_shift_holo_dark</item>
<item name="iconDeleteKey">@drawable/sym_keyboard_delete_holo_dark</item>
<item name="iconSettingsKey">@drawable/sym_keyboard_settings_holo_dark</item>
diff --git a/java/res/values/keyboard-icons-lxx-dark.xml b/java/res/values/keyboard-icons-lxx-dark.xml
new file mode 100644
index 000000000..6e9c4d1c1
--- /dev/null
+++ b/java/res/values/keyboard-icons-lxx-dark.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="KeyboardIcons.LXX_Dark">
+ <!-- Keyboard icons -->
+ <!-- TODO: Update those icons for LXX theme. -->
+ <item name="iconShiftKey">@drawable/sym_keyboard_shift_lxx_dark</item>
+ <item name="iconDeleteKey">@drawable/sym_keyboard_delete_lxx_dark</item>
+ <item name="iconSettingsKey">@drawable/sym_keyboard_settings_lxx_dark</item>
+ <item name="iconSpaceKey">@drawable/sym_keyboard_spacebar_lxx_dark</item>
+ <item name="iconEnterKey">@drawable/sym_keyboard_return_lxx_dark</item>
+ <item name="iconGoKey">@drawable/sym_keyboard_go_lxx_dark</item>
+ <item name="iconSearchKey">@drawable/sym_keyboard_search_lxx_dark</item>
+ <item name="iconSendKey">@drawable/sym_keyboard_send_lxx_dark</item>
+ <item name="iconNextKey">@drawable/sym_keyboard_next_lxx_dark</item>
+ <item name="iconDoneKey">@drawable/sym_keyboard_done_lxx_dark</item>
+ <item name="iconPreviousKey">@drawable/sym_keyboard_previous_lxx_dark</item>
+ <item name="iconTabKey">@drawable/sym_keyboard_tab_holo_dark</item>
+ <item name="iconShortcutKey">@drawable/sym_keyboard_voice_lxx_dark</item>
+ <item name="iconSpaceKeyForNumberLayout">@drawable/sym_keyboard_space_holo_dark</item>
+ <item name="iconShiftKeyShifted">@drawable/sym_keyboard_shift_locked_lxx_dark</item>
+ <item name="iconShortcutKeyDisabled">@drawable/sym_keyboard_voice_off_lxx_dark</item>
+ <item name="iconTabKeyPreview">@drawable/sym_keyboard_feedback_tab</item>
+ <item name="iconLanguageSwitchKey">@drawable/sym_keyboard_language_switch_lxx_dark</item>
+ <item name="iconZwnjKey">@drawable/sym_keyboard_zwnj_holo_dark</item>
+ <item name="iconZwjKey">@drawable/sym_keyboard_zwj_holo_dark</item>
+ <item name="iconEmojiKey">@drawable/sym_keyboard_smiley_lxx_dark</item>
+ </style>
+</resources>
diff --git a/java/res/values/keyboard-themes.xml b/java/res/values/keyboard-themes.xml
new file mode 100644
index 000000000..a06082c6e
--- /dev/null
+++ b/java/res/values/keyboard-themes.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- For keyboard color scheme option dialog. -->
+ <string-array name="keyboard_theme_names" translatable="false">
+ <!-- TODO: Make this item as translatable string resource. -->
+ <item>Material</item>
+ <item>@string/keyboard_color_scheme_white</item>
+ <item>@string/keyboard_color_scheme_blue</item>
+ </string-array>
+ <!-- An element must be a keyboard theme id of {@link KeyboardTheme#THEME_ID_*}. -->
+ <string-array name="keyboard_theme_ids" translatable="false">
+ <item>3</item>
+ <item>2</item>
+ <item>0</item>
+ </string-array>
+</resources>
diff --git a/java/res/values/research_strings.xml b/java/res/values/research_strings.xml
deleted file mode 100644
index e73871109..000000000
--- a/java/res/values/research_strings.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2012, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Contents of note explaining what data is collected and how. -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_splash_content" translatable="false"></string>
- <!-- Account type allowed for inclusion in user-invoked feedback logs [CHAR LIMIT=38] -->
- <string name="research_account_type" translatable="false"></string>
- <!-- Account domain allowed for inclusion in user-invoked feedback logs [CHAR LIMIT=38] -->
- <string name="research_allowed_account_domain" translatable="false"></string>
-
- <!-- Menu option that lets user send feedback for research purposes about the IME [CHAR LIMIT=38] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_menu_option" translatable="false">Send feedback</string>
- <!-- Title of dialog box that lets user send feedback for research purposes about the IME [CHAR LIMIT=38] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_dialog_title" translatable="false">Send feedback</string>
- <!-- Hint to user about the text entry field where they should enter research feedback [CHAR LIMIT=40] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_hint" translatable="false">Enter your feedback here.</string>
- <!-- Message informing the user that the feedback string must not be empty [CHAR LIMIT=100] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_empty_feedback_error_message" translatable="false">The feedback field must not be empty.</string>
-</resources>
diff --git a/java/res/values/strings-action-keys.xml b/java/res/values/strings-action-keys.xml
index 7003784c6..96b2e7dda 100644
--- a/java/res/values/strings-action-keys.xml
+++ b/java/res/values/strings-action-keys.xml
@@ -29,6 +29,8 @@
<string name="label_done_key">Done</string>
<!-- Label for soft enter key when it performs SEND action. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7] -->
<string name="label_send_key">Send</string>
+ <!-- Label for soft enter key when it performs SEARCH action. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7] -->
+ <string name="label_search_key">Search</string>
<!-- Label for "Pause" key of phone number keyboard. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7] -->
<string name="label_pause_key">Pause</string>
<!-- Label for "Wait" key of phone number keyboard. Must be short to fit on key. 5 chars or less is preferable. [CHAR LIMIT=7]-->
diff --git a/java/res/values/strings-emoji-descriptions.xml b/java/res/values/strings-emoji-descriptions.xml
new file mode 100644
index 000000000..8cbde264c
--- /dev/null
+++ b/java/res/values/strings-emoji-descriptions.xml
@@ -0,0 +1,1671 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<!--
+ These Emoji symbols are unsupported by TTS.
+ TODO: Remove this file when TTS/TalkBack support these Emoji symbols.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Spoken description for Unicode code point U+00A9: "©" COPYRIGHT SIGN -->
+ <string name="spoken_emoji_00A9">Copyright sign</string>
+ <!-- Spoken description for Unicode code point U+00AE: "®" REGISTERED SIGN -->
+ <string name="spoken_emoji_00AE">Registered sign</string>
+ <!-- Spoken description for Unicode code point U+203C: "‼" DOUBLE EXCLAMATION MARK -->
+ <string name="spoken_emoji_203C">Double exclamation mark</string>
+ <!-- Spoken description for Unicode code point U+2049: "⁉" EXCLAMATION QUESTION MARK -->
+ <string name="spoken_emoji_2049">Exclamation question mark</string>
+ <!-- Spoken description for Unicode code point U+2122: "™" TRADE MARK SIGN -->
+ <string name="spoken_emoji_2122">Trade mark sign</string>
+ <!-- Spoken description for Unicode code point U+2139: "ℹ" INFORMATION SOURCE -->
+ <string name="spoken_emoji_2139">Information source</string>
+ <!-- Spoken description for Unicode code point U+2194: "↔" LEFT RIGHT ARROW -->
+ <string name="spoken_emoji_2194">Left right arrow</string>
+ <!-- Spoken description for Unicode code point U+2195: "↕" UP DOWN ARROW -->
+ <string name="spoken_emoji_2195">Up down arrow</string>
+ <!-- Spoken description for Unicode code point U+2196: "↖" NORTH WEST ARROW -->
+ <string name="spoken_emoji_2196">North west arrow</string>
+ <!-- Spoken description for Unicode code point U+2197: "↗" NORTH EAST ARROW -->
+ <string name="spoken_emoji_2197">North east arrow</string>
+ <!-- Spoken description for Unicode code point U+2198: "↘" SOUTH EAST ARROW -->
+ <string name="spoken_emoji_2198">South east arrow</string>
+ <!-- Spoken description for Unicode code point U+2199: "↙" SOUTH WEST ARROW -->
+ <string name="spoken_emoji_2199">South west arrow</string>
+ <!-- Spoken description for Unicode code point U+21A9: "↩" LEFTWARDS ARROW WITH HOOK -->
+ <string name="spoken_emoji_21A9">Leftwards arrow with hook</string>
+ <!-- Spoken description for Unicode code point U+21AA: "↪" RIGHTWARDS ARROW WITH HOOK -->
+ <string name="spoken_emoji_21AA">Rightwards arrow with hook</string>
+ <!-- Spoken description for Unicode code point U+231A: "⌚" WATCH -->
+ <string name="spoken_emoji_231A">Watch</string>
+ <!-- Spoken description for Unicode code point U+231B: "⌛" HOURGLASS -->
+ <string name="spoken_emoji_231B">Hourglass</string>
+ <!-- Spoken description for Unicode code point U+23E9: "⏩" BLACK RIGHT-POINTING DOUBLE TRIANGLE -->
+ <string name="spoken_emoji_23E9">Black right-pointing double triangle</string>
+ <!-- Spoken description for Unicode code point U+23EA: "⏪" BLACK LEFT-POINTING DOUBLE TRIANGLE -->
+ <string name="spoken_emoji_23EA">Black left-pointing double triangle</string>
+ <!-- Spoken description for Unicode code point U+23EB: "⏫" BLACK UP-POINTING DOUBLE TRIANGLE -->
+ <string name="spoken_emoji_23EB">Black up-pointing double triangle</string>
+ <!-- Spoken description for Unicode code point U+23EC: "⏬" BLACK DOWN-POINTING DOUBLE TRIANGLE -->
+ <string name="spoken_emoji_23EC">Black down-pointing double triangle</string>
+ <!-- Spoken description for Unicode code point U+23F0: "⏰" ALARM CLOCK -->
+ <string name="spoken_emoji_23F0">Alarm clock</string>
+ <!-- Spoken description for Unicode code point U+23F3: "⏳" HOURGLASS WITH FLOWING SAND -->
+ <string name="spoken_emoji_23F3">Hourglass with flowing sand</string>
+ <!-- Spoken description for Unicode code point U+24C2: "Ⓜ" CIRCLED LATIN CAPITAL LETTER M -->
+ <string name="spoken_emoji_24C2">Circled latin capital letter m</string>
+ <!-- Spoken description for Unicode code point U+25AA: "▪" BLACK SMALL SQUARE -->
+ <string name="spoken_emoji_25AA">Black small square</string>
+ <!-- Spoken description for Unicode code point U+25AB: "▫" WHITE SMALL SQUARE -->
+ <string name="spoken_emoji_25AB">White small square</string>
+ <!-- Spoken description for Unicode code point U+25B6: "▶" BLACK RIGHT-POINTING TRIANGLE -->
+ <string name="spoken_emoji_25B6">Black right-pointing triangle</string>
+ <!-- Spoken description for Unicode code point U+25C0: "◀" BLACK LEFT-POINTING TRIANGLE -->
+ <string name="spoken_emoji_25C0">Black left-pointing triangle</string>
+ <!-- Spoken description for Unicode code point U+25FB: "◻" WHITE MEDIUM SQUARE -->
+ <string name="spoken_emoji_25FB">White medium square</string>
+ <!-- Spoken description for Unicode code point U+25FC: "◼" BLACK MEDIUM SQUARE -->
+ <string name="spoken_emoji_25FC">Black medium square</string>
+ <!-- Spoken description for Unicode code point U+25FD: "◽" WHITE MEDIUM SMALL SQUARE -->
+ <string name="spoken_emoji_25FD">White medium small square</string>
+ <!-- Spoken description for Unicode code point U+25FE: "◾" BLACK MEDIUM SMALL SQUARE -->
+ <string name="spoken_emoji_25FE">Black medium small square</string>
+ <!-- Spoken description for Unicode code point U+2600: "☀" BLACK SUN WITH RAYS -->
+ <string name="spoken_emoji_2600">Black sun with rays</string>
+ <!-- Spoken description for Unicode code point U+2601: "☁" CLOUD -->
+ <string name="spoken_emoji_2601">Cloud</string>
+ <!-- Spoken description for Unicode code point U+260E: "☎" BLACK TELEPHONE -->
+ <string name="spoken_emoji_260E">Black telephone</string>
+ <!-- Spoken description for Unicode code point U+2611: "☑" BALLOT BOX WITH CHECK -->
+ <string name="spoken_emoji_2611">Ballot box with check</string>
+ <!-- Spoken description for Unicode code point U+2614: "☔" UMBRELLA WITH RAIN DROPS -->
+ <string name="spoken_emoji_2614">Umbrella with rain drops</string>
+ <!-- Spoken description for Unicode code point U+2615: "☕" HOT BEVERAGE -->
+ <string name="spoken_emoji_2615">Hot beverage</string>
+ <!-- Spoken description for Unicode code point U+261D: "☝" WHITE UP POINTING INDEX -->
+ <string name="spoken_emoji_261D">White up pointing index</string>
+ <!-- Spoken description for Unicode code point U+263A: "☺" WHITE SMILING FACE -->
+ <string name="spoken_emoji_263A">White smiling face</string>
+ <!-- Spoken description for Unicode code point U+2648: "♈" ARIES -->
+ <string name="spoken_emoji_2648">Aries</string>
+ <!-- Spoken description for Unicode code point U+2649: "♉" TAURUS -->
+ <string name="spoken_emoji_2649">Taurus</string>
+ <!-- Spoken description for Unicode code point U+264A: "♊" GEMINI -->
+ <string name="spoken_emoji_264A">Gemini</string>
+ <!-- Spoken description for Unicode code point U+264B: "♋" CANCER -->
+ <string name="spoken_emoji_264B">Cancer</string>
+ <!-- Spoken description for Unicode code point U+264C: "♌" LEO -->
+ <string name="spoken_emoji_264C">Leo</string>
+ <!-- Spoken description for Unicode code point U+264D: "♍" VIRGO -->
+ <string name="spoken_emoji_264D">Virgo</string>
+ <!-- Spoken description for Unicode code point U+264E: "♎" LIBRA -->
+ <string name="spoken_emoji_264E">Libra</string>
+ <!-- Spoken description for Unicode code point U+264F: "♏" SCORPIUS -->
+ <string name="spoken_emoji_264F">Scorpius</string>
+ <!-- Spoken description for Unicode code point U+2650: "♐" SAGITTARIUS -->
+ <string name="spoken_emoji_2650">Sagittarius</string>
+ <!-- Spoken description for Unicode code point U+2651: "♑" CAPRICORN -->
+ <string name="spoken_emoji_2651">Capricorn</string>
+ <!-- Spoken description for Unicode code point U+2652: "♒" AQUARIUS -->
+ <string name="spoken_emoji_2652">Aquarius</string>
+ <!-- Spoken description for Unicode code point U+2653: "♓" PISCES -->
+ <string name="spoken_emoji_2653">Pisces</string>
+ <!-- Spoken description for Unicode code point U+2660: "♠" BLACK SPADE SUIT -->
+ <string name="spoken_emoji_2660">Black spade suit</string>
+ <!-- Spoken description for Unicode code point U+2663: "♣" BLACK CLUB SUIT -->
+ <string name="spoken_emoji_2663">Black club suit</string>
+ <!-- Spoken description for Unicode code point U+2665: "♥" BLACK HEART SUIT -->
+ <string name="spoken_emoji_2665">Black heart suit</string>
+ <!-- Spoken description for Unicode code point U+2666: "♦" BLACK DIAMOND SUIT -->
+ <string name="spoken_emoji_2666">Black diamond suit</string>
+ <!-- Spoken description for Unicode code point U+2668: "♨" HOT SPRINGS -->
+ <string name="spoken_emoji_2668">Hot springs</string>
+ <!-- Spoken description for Unicode code point U+267B: "♻" BLACK UNIVERSAL RECYCLING SYMBOL -->
+ <string name="spoken_emoji_267B">Black universal recycling symbol</string>
+ <!-- Spoken description for Unicode code point U+267F: "♿" WHEELCHAIR SYMBOL -->
+ <string name="spoken_emoji_267F">Wheelchair symbol</string>
+ <!-- Spoken description for Unicode code point U+2693: "⚓" ANCHOR -->
+ <string name="spoken_emoji_2693">Anchor</string>
+ <!-- Spoken description for Unicode code point U+26A0: "⚠" WARNING SIGN -->
+ <string name="spoken_emoji_26A0">Warning sign</string>
+ <!-- Spoken description for Unicode code point U+26A1: "⚡" HIGH VOLTAGE SIGN -->
+ <string name="spoken_emoji_26A1">High voltage sign</string>
+ <!-- Spoken description for Unicode code point U+26AA: "⚪" MEDIUM WHITE CIRCLE -->
+ <string name="spoken_emoji_26AA">Medium white circle</string>
+ <!-- Spoken description for Unicode code point U+26AB: "⚫" MEDIUM BLACK CIRCLE -->
+ <string name="spoken_emoji_26AB">Medium black circle</string>
+ <!-- Spoken description for Unicode code point U+26BD: "⚽" SOCCER BALL -->
+ <string name="spoken_emoji_26BD">Soccer ball</string>
+ <!-- Spoken description for Unicode code point U+26BE: "⚾" BASEBALL -->
+ <string name="spoken_emoji_26BE">Baseball</string>
+ <!-- Spoken description for Unicode code point U+26C4: "⛄" SNOWMAN WITHOUT SNOW -->
+ <string name="spoken_emoji_26C4">Snowman without snow</string>
+ <!-- Spoken description for Unicode code point U+26C5: "⛅" SUN BEHIND CLOUD -->
+ <string name="spoken_emoji_26C5">Sun behind cloud</string>
+ <!-- Spoken description for Unicode code point U+26CE: "⛎" OPHIUCHUS -->
+ <string name="spoken_emoji_26CE">Ophiuchus</string>
+ <!-- Spoken description for Unicode code point U+26D4: "⛔" NO ENTRY -->
+ <string name="spoken_emoji_26D4">No entry</string>
+ <!-- Spoken description for Unicode code point U+26EA: "⛪" CHURCH -->
+ <string name="spoken_emoji_26EA">Church</string>
+ <!-- Spoken description for Unicode code point U+26F2: "⛲" FOUNTAIN -->
+ <string name="spoken_emoji_26F2">Fountain</string>
+ <!-- Spoken description for Unicode code point U+26F3: "⛳" FLAG IN HOLE -->
+ <string name="spoken_emoji_26F3">Flag in hole</string>
+ <!-- Spoken description for Unicode code point U+26F5: "⛵" SAILBOAT -->
+ <string name="spoken_emoji_26F5">Sailboat</string>
+ <!-- Spoken description for Unicode code point U+26FA: "⛺" TENT -->
+ <string name="spoken_emoji_26FA">Tent</string>
+ <!-- Spoken description for Unicode code point U+26FD: "⛽" FUEL PUMP -->
+ <string name="spoken_emoji_26FD">Fuel pump</string>
+ <!-- Spoken description for Unicode code point U+2702: "✂" BLACK SCISSORS -->
+ <string name="spoken_emoji_2702">Black scissors</string>
+ <!-- Spoken description for Unicode code point U+2705: "✅" WHITE HEAVY CHECK MARK -->
+ <string name="spoken_emoji_2705">White heavy check mark</string>
+ <!-- Spoken description for Unicode code point U+2708: "✈" AIRPLANE -->
+ <string name="spoken_emoji_2708">Airplane</string>
+ <!-- Spoken description for Unicode code point U+2709: "✉" ENVELOPE -->
+ <string name="spoken_emoji_2709">Envelope</string>
+ <!-- Spoken description for Unicode code point U+270A: "✊" RAISED FIST -->
+ <string name="spoken_emoji_270A">Raised fist</string>
+ <!-- Spoken description for Unicode code point U+270B: "✋" RAISED HAND -->
+ <string name="spoken_emoji_270B">Raised hand</string>
+ <!-- Spoken description for Unicode code point U+270C: "✌" VICTORY HAND -->
+ <string name="spoken_emoji_270C">Victory hand</string>
+ <!-- Spoken description for Unicode code point U+270F: "✏" PENCIL -->
+ <string name="spoken_emoji_270F">Pencil</string>
+ <!-- Spoken description for Unicode code point U+2712: "✒" BLACK NIB -->
+ <string name="spoken_emoji_2712">Black nib</string>
+ <!-- Spoken description for Unicode code point U+2714: "✔" HEAVY CHECK MARK -->
+ <string name="spoken_emoji_2714">Heavy check mark</string>
+ <!-- Spoken description for Unicode code point U+2716: "✖" HEAVY MULTIPLICATION X -->
+ <string name="spoken_emoji_2716">Heavy multiplication x</string>
+ <!-- Spoken description for Unicode code point U+2728: "✨" SPARKLES -->
+ <string name="spoken_emoji_2728">Sparkles</string>
+ <!-- Spoken description for Unicode code point U+2733: "✳" EIGHT SPOKED ASTERISK -->
+ <string name="spoken_emoji_2733">Eight spoked asterisk</string>
+ <!-- Spoken description for Unicode code point U+2734: "✴" EIGHT POINTED BLACK STAR -->
+ <string name="spoken_emoji_2734">Eight pointed black star</string>
+ <!-- Spoken description for Unicode code point U+2744: "❄" SNOWFLAKE -->
+ <string name="spoken_emoji_2744">Snowflake</string>
+ <!-- Spoken description for Unicode code point U+2747: "❇" SPARKLE -->
+ <string name="spoken_emoji_2747">Sparkle</string>
+ <!-- Spoken description for Unicode code point U+274C: "❌" CROSS MARK -->
+ <string name="spoken_emoji_274C">Cross mark</string>
+ <!-- Spoken description for Unicode code point U+274E: "❎" NEGATIVE SQUARED CROSS MARK -->
+ <string name="spoken_emoji_274E">Negative squared cross mark</string>
+ <!-- Spoken description for Unicode code point U+2753: "❓" BLACK QUESTION MARK ORNAMENT -->
+ <string name="spoken_emoji_2753">Black question mark ornament</string>
+ <!-- Spoken description for Unicode code point U+2754: "❔" WHITE QUESTION MARK ORNAMENT -->
+ <string name="spoken_emoji_2754">White question mark ornament</string>
+ <!-- Spoken description for Unicode code point U+2755: "❕" WHITE EXCLAMATION MARK ORNAMENT -->
+ <string name="spoken_emoji_2755">White exclamation mark ornament</string>
+ <!-- Spoken description for Unicode code point U+2757: "❗" HEAVY EXCLAMATION MARK SYMBOL -->
+ <string name="spoken_emoji_2757">Heavy exclamation mark symbol</string>
+ <!-- Spoken description for Unicode code point U+2764: "❤" HEAVY BLACK HEART -->
+ <string name="spoken_emoji_2764">Heavy black heart</string>
+ <!-- Spoken description for Unicode code point U+2795: "➕" HEAVY PLUS SIGN -->
+ <string name="spoken_emoji_2795">Heavy plus sign</string>
+ <!-- Spoken description for Unicode code point U+2796: "➖" HEAVY MINUS SIGN -->
+ <string name="spoken_emoji_2796">Heavy minus sign</string>
+ <!-- Spoken description for Unicode code point U+2797: "➗" HEAVY DIVISION SIGN -->
+ <string name="spoken_emoji_2797">Heavy division sign</string>
+ <!-- Spoken description for Unicode code point U+27A1: "➡" BLACK RIGHTWARDS ARROW -->
+ <string name="spoken_emoji_27A1">Black rightwards arrow</string>
+ <!-- Spoken description for Unicode code point U+27B0: "➰" CURLY LOOP -->
+ <string name="spoken_emoji_27B0">Curly loop</string>
+ <!-- Spoken description for Unicode code point U+27BF: "➿" DOUBLE CURLY LOOP -->
+ <string name="spoken_emoji_27BF">Double curly loop</string>
+ <!-- Spoken description for Unicode code point U+2934: "⤴" ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS -->
+ <string name="spoken_emoji_2934">Arrow pointing rightwards then curving upwards</string>
+ <!-- Spoken description for Unicode code point U+2935: "⤵" ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS -->
+ <string name="spoken_emoji_2935">Arrow pointing rightwards then curving downwards</string>
+ <!-- Spoken description for Unicode code point U+2B05: "⬅" LEFTWARDS BLACK ARROW -->
+ <string name="spoken_emoji_2B05">Leftwards black arrow</string>
+ <!-- Spoken description for Unicode code point U+2B06: "⬆" UPWARDS BLACK ARROW -->
+ <string name="spoken_emoji_2B06">Upwards black arrow</string>
+ <!-- Spoken description for Unicode code point U+2B07: "⬇" DOWNWARDS BLACK ARROW -->
+ <string name="spoken_emoji_2B07">Downwards black arrow</string>
+ <!-- Spoken description for Unicode code point U+2B1B: "⬛" BLACK LARGE SQUARE -->
+ <string name="spoken_emoji_2B1B">Black large square</string>
+ <!-- Spoken description for Unicode code point U+2B1C: "⬜" WHITE LARGE SQUARE -->
+ <string name="spoken_emoji_2B1C">White large square</string>
+ <!-- Spoken description for Unicode code point U+2B50: "⭐" WHITE MEDIUM STAR -->
+ <string name="spoken_emoji_2B50">White medium star</string>
+ <!-- Spoken description for Unicode code point U+2B55: "⭕" HEAVY LARGE CIRCLE -->
+ <string name="spoken_emoji_2B55">Heavy large circle</string>
+ <!-- Spoken description for Unicode code point U+3030: "〰" WAVY DASH -->
+ <string name="spoken_emoji_3030">Wavy dash</string>
+ <!-- Spoken description for Unicode code point U+303D: "〽" PART ALTERNATION MARK -->
+ <string name="spoken_emoji_303D">Part alternation mark</string>
+ <!-- Spoken description for Unicode code point U+3297: "㊗" CIRCLED IDEOGRAPH CONGRATULATION -->
+ <string name="spoken_emoji_3297">Circled ideograph congratulation</string>
+ <!-- Spoken description for Unicode code point U+3299: "㊙" CIRCLED IDEOGRAPH SECRET -->
+ <string name="spoken_emoji_3299">Circled ideograph secret</string>
+ <!-- Spoken description for Unicode code point U+1F004: "🀄" MAHJONG TILE RED DRAGON -->
+ <string name="spoken_emoji_1F004">Mahjong tile red dragon</string>
+ <!-- Spoken description for Unicode code point U+1F0CF: "🃏" PLAYING CARD BLACK JOKER -->
+ <string name="spoken_emoji_1F0CF">Playing card black joker</string>
+ <!-- Spoken description for Unicode code point U+1F170: "🅰" NEGATIVE SQUARED LATIN CAPITAL LETTER A -->
+ <string name="spoken_emoji_1F170">Blood type A</string>
+ <!-- Spoken description for Unicode code point U+1F171: "🅱" NEGATIVE SQUARED LATIN CAPITAL LETTER B -->
+ <string name="spoken_emoji_1F171">Blood type B</string>
+ <!-- Spoken description for Unicode code point U+1F17E: "🅾" NEGATIVE SQUARED LATIN CAPITAL LETTER O -->
+ <string name="spoken_emoji_1F17E">Blood type O</string>
+ <!-- Spoken description for Unicode code point U+1F17F: "🅿" NEGATIVE SQUARED LATIN CAPITAL LETTER P -->
+ <string name="spoken_emoji_1F17F">Parking lot</string>
+ <!-- Spoken description for Unicode code point U+1F18E: "🆎" NEGATIVE SQUARED AB -->
+ <string name="spoken_emoji_1F18E">Blood type AB</string>
+ <!-- Spoken description for Unicode code point U+1F191: "🆑" SQUARED CL -->
+ <string name="spoken_emoji_1F191">Squared CL</string>
+ <!-- Spoken description for Unicode code point U+1F192: "🆒" SQUARED COOL -->
+ <string name="spoken_emoji_1F192">Squared cool</string>
+ <!-- Spoken description for Unicode code point U+1F193: "🆓" SQUARED FREE -->
+ <string name="spoken_emoji_1F193">Squared free</string>
+ <!-- Spoken description for Unicode code point U+1F194: "🆔" SQUARED ID -->
+ <string name="spoken_emoji_1F194">Squared ID</string>
+ <!-- Spoken description for Unicode code point U+1F195: "🆕" SQUARED NEW -->
+ <string name="spoken_emoji_1F195">Squared new</string>
+ <!-- Spoken description for Unicode code point U+1F196: "🆖" SQUARED NG -->
+ <string name="spoken_emoji_1F196">Squared N G</string>
+ <!-- Spoken description for Unicode code point U+1F197: "🆗" SQUARED OK -->
+ <string name="spoken_emoji_1F197">Squared OK</string>
+ <!-- Spoken description for Unicode code point U+1F198: "🆘" SQUARED SOS -->
+ <string name="spoken_emoji_1F198">Squared SOS</string>
+ <!-- Spoken description for Unicode code point U+1F199: "🆙" SQUARED UP WITH EXCLAMATION MARK -->
+ <string name="spoken_emoji_1F199">Squared up with exclamation mark</string>
+ <!-- Spoken description for Unicode code point U+1F19A: "🆚" SQUARED VS -->
+ <string name="spoken_emoji_1F19A">Squared vs</string>
+ <!-- Spoken description for Unicode code point U+1F201: "🈁" SQUARED KATAKANA KOKO -->
+ <string name="spoken_emoji_1F201">Squared katakana here</string>
+ <!-- Spoken description for Unicode code point U+1F202: "🈂" SQUARED KATAKANA SA -->
+ <string name="spoken_emoji_1F202">Squared katakana service</string>
+ <!-- Spoken description for Unicode code point U+1F21A: "🈚" SQUARED CJK UNIFIED IDEOGRAPH-7121 -->
+ <string name="spoken_emoji_1F21A">Squared ideograph charge-free</string>
+ <!-- Spoken description for Unicode code point U+1F22F: "🈯" SQUARED CJK UNIFIED IDEOGRAPH-6307 -->
+ <string name="spoken_emoji_1F22F">Squared ideograph reserved-seat</string>
+ <!-- Spoken description for Unicode code point U+1F232: "🈲" SQUARED CJK UNIFIED IDEOGRAPH-7981 -->
+ <string name="spoken_emoji_1F232">Squared ideograph prohibitation</string>
+ <!-- Spoken description for Unicode code point U+1F233: "🈳" SQUARED CJK UNIFIED IDEOGRAPH-7A7A -->
+ <string name="spoken_emoji_1F233">Squared ideograph vacancy</string>
+ <!-- Spoken description for Unicode code point U+1F234: "🈴" SQUARED CJK UNIFIED IDEOGRAPH-5408 -->
+ <string name="spoken_emoji_1F234">Squared ideograph acceptance</string>
+ <!-- Spoken description for Unicode code point U+1F235: "🈵" SQUARED CJK UNIFIED IDEOGRAPH-6E80 -->
+ <string name="spoken_emoji_1F235">Squared ideograph full occupancy</string>
+ <!-- Spoken description for Unicode code point U+1F236: "🈶" SQUARED CJK UNIFIED IDEOGRAPH-6709 -->
+ <string name="spoken_emoji_1F236">Squared ideograph paid</string>
+ <!-- Spoken description for Unicode code point U+1F237: "🈷" SQUARED CJK UNIFIED IDEOGRAPH-6708 -->
+ <string name="spoken_emoji_1F237">Squared ideograph monthly</string>
+ <!-- Spoken description for Unicode code point U+1F238: "🈸" SQUARED CJK UNIFIED IDEOGRAPH-7533 -->
+ <string name="spoken_emoji_1F238">Squared ideograph application</string>
+ <!-- Spoken description for Unicode code point U+1F239: "🈹" SQUARED CJK UNIFIED IDEOGRAPH-5272 -->
+ <string name="spoken_emoji_1F239">Squared ideograph discount</string>
+ <!-- Spoken description for Unicode code point U+1F23A: "🈺" SQUARED CJK UNIFIED IDEOGRAPH-55B6 -->
+ <string name="spoken_emoji_1F23A">Squared ideograph in business</string>
+ <!-- Spoken description for Unicode code point U+1F250: "🉐" CIRCLED IDEOGRAPH ADVANTAGE -->
+ <string name="spoken_emoji_1F250">Circled ideograph advantage</string>
+ <!-- Spoken description for Unicode code point U+1F251: "🉑" CIRCLED IDEOGRAPH ACCEPT -->
+ <string name="spoken_emoji_1F251">Circled ideograph accept</string>
+ <!-- Spoken description for Unicode code point U+1F300: "🌀" CYCLONE -->
+ <string name="spoken_emoji_1F300">Cyclone</string>
+ <!-- Spoken description for Unicode code point U+1F301: "🌁" FOGGY -->
+ <string name="spoken_emoji_1F301">Foggy</string>
+ <!-- Spoken description for Unicode code point U+1F302: "🌂" CLOSED UMBRELLA -->
+ <string name="spoken_emoji_1F302">Closed umbrella</string>
+ <!-- Spoken description for Unicode code point U+1F303: "🌃" NIGHT WITH STARS -->
+ <string name="spoken_emoji_1F303">Night with stars</string>
+ <!-- Spoken description for Unicode code point U+1F304: "🌄" SUNRISE OVER MOUNTAINS -->
+ <string name="spoken_emoji_1F304">Sunrise over mountains</string>
+ <!-- Spoken description for Unicode code point U+1F305: "🌅" SUNRISE -->
+ <string name="spoken_emoji_1F305">Sunrise</string>
+ <!-- Spoken description for Unicode code point U+1F306: "🌆" CITYSCAPE AT DUSK -->
+ <string name="spoken_emoji_1F306">Cityscape at dusk</string>
+ <!-- Spoken description for Unicode code point U+1F307: "🌇" SUNSET OVER BUILDINGS -->
+ <string name="spoken_emoji_1F307">Sunset over buildings</string>
+ <!-- Spoken description for Unicode code point U+1F308: "🌈" RAINBOW -->
+ <string name="spoken_emoji_1F308">Rainbow</string>
+ <!-- Spoken description for Unicode code point U+1F309: "🌉" BRIDGE AT NIGHT -->
+ <string name="spoken_emoji_1F309">Bridge at night</string>
+ <!-- Spoken description for Unicode code point U+1F30A: "🌊" WATER WAVE -->
+ <string name="spoken_emoji_1F30A">Water wave</string>
+ <!-- Spoken description for Unicode code point U+1F30B: "🌋" VOLCANO -->
+ <string name="spoken_emoji_1F30B">Volcano</string>
+ <!-- Spoken description for Unicode code point U+1F30C: "🌌" MILKY WAY -->
+ <string name="spoken_emoji_1F30C">Milky way</string>
+ <!-- Spoken description for Unicode code point U+1F30D: "🌍" EARTH GLOBE EUROPE-AFRICA -->
+ <string name="spoken_emoji_1F30D">Earth globe europe-africa</string>
+ <!-- Spoken description for Unicode code point U+1F30E: "🌎" EARTH GLOBE AMERICAS -->
+ <string name="spoken_emoji_1F30E">Earth globe americas</string>
+ <!-- Spoken description for Unicode code point U+1F30F: "🌏" EARTH GLOBE ASIA-AUSTRALIA -->
+ <string name="spoken_emoji_1F30F">Earth globe asia-australia</string>
+ <!-- Spoken description for Unicode code point U+1F310: "🌐" GLOBE WITH MERIDIANS -->
+ <string name="spoken_emoji_1F310">Globe with meridians</string>
+ <!-- Spoken description for Unicode code point U+1F311: "🌑" NEW MOON SYMBOL -->
+ <string name="spoken_emoji_1F311">New moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F312: "🌒" WAXING CRESCENT MOON SYMBOL -->
+ <string name="spoken_emoji_1F312">Waxing crescent moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F313: "🌓" FIRST QUARTER MOON SYMBOL -->
+ <string name="spoken_emoji_1F313">First quarter moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F314: "🌔" WAXING GIBBOUS MOON SYMBOL -->
+ <string name="spoken_emoji_1F314">Waxing gibbous moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F315: "🌕" FULL MOON SYMBOL -->
+ <string name="spoken_emoji_1F315">Full moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F316: "🌖" WANING GIBBOUS MOON SYMBOL -->
+ <string name="spoken_emoji_1F316">Waning gibbous moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F317: "🌗" LAST QUARTER MOON SYMBOL -->
+ <string name="spoken_emoji_1F317">Last quarter moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F318: "🌘" WANING CRESCENT MOON SYMBOL -->
+ <string name="spoken_emoji_1F318">Waning crescent moon symbol</string>
+ <!-- Spoken description for Unicode code point U+1F319: "🌙" CRESCENT MOON -->
+ <string name="spoken_emoji_1F319">Crescent moon</string>
+ <!-- Spoken description for Unicode code point U+1F31A: "🌚" NEW MOON WITH FACE -->
+ <string name="spoken_emoji_1F31A">New moon with face</string>
+ <!-- Spoken description for Unicode code point U+1F31B: "🌛" FIRST QUARTER MOON WITH FACE -->
+ <string name="spoken_emoji_1F31B">First quarter moon with face</string>
+ <!-- Spoken description for Unicode code point U+1F31C: "🌜" LAST QUARTER MOON WITH FACE -->
+ <string name="spoken_emoji_1F31C">Last quarter moon with face</string>
+ <!-- Spoken description for Unicode code point U+1F31D: "🌝" FULL MOON WITH FACE -->
+ <string name="spoken_emoji_1F31D">Full moon with face</string>
+ <!-- Spoken description for Unicode code point U+1F31E: "🌞" SUN WITH FACE -->
+ <string name="spoken_emoji_1F31E">Sun with face</string>
+ <!-- Spoken description for Unicode code point U+1F31F: "🌟" GLOWING STAR -->
+ <string name="spoken_emoji_1F31F">Glowing star</string>
+ <!-- Spoken description for Unicode code point U+1F320: "🌠" SHOOTING STAR -->
+ <string name="spoken_emoji_1F320">Shooting star</string>
+ <!-- Spoken description for Unicode code point U+1F330: "🌰" CHESTNUT -->
+ <string name="spoken_emoji_1F330">Chestnut</string>
+ <!-- Spoken description for Unicode code point U+1F331: "🌱" SEEDLING -->
+ <string name="spoken_emoji_1F331">Seedling</string>
+ <!-- Spoken description for Unicode code point U+1F332: "🌲" EVERGREEN TREE -->
+ <string name="spoken_emoji_1F332">Evergreen tree</string>
+ <!-- Spoken description for Unicode code point U+1F333: "🌳" DECIDUOUS TREE -->
+ <string name="spoken_emoji_1F333">Deciduous tree</string>
+ <!-- Spoken description for Unicode code point U+1F334: "🌴" PALM TREE -->
+ <string name="spoken_emoji_1F334">Palm tree</string>
+ <!-- Spoken description for Unicode code point U+1F335: "🌵" CACTUS -->
+ <string name="spoken_emoji_1F335">Cactus</string>
+ <!-- Spoken description for Unicode code point U+1F337: "🌷" TULIP -->
+ <string name="spoken_emoji_1F337">Tulip</string>
+ <!-- Spoken description for Unicode code point U+1F338: "🌸" CHERRY BLOSSOM -->
+ <string name="spoken_emoji_1F338">Cherry blossom</string>
+ <!-- Spoken description for Unicode code point U+1F339: "🌹" ROSE -->
+ <string name="spoken_emoji_1F339">Rose</string>
+ <!-- Spoken description for Unicode code point U+1F33A: "🌺" HIBISCUS -->
+ <string name="spoken_emoji_1F33A">Hibiscus</string>
+ <!-- Spoken description for Unicode code point U+1F33B: "🌻" SUNFLOWER -->
+ <string name="spoken_emoji_1F33B">Sunflower</string>
+ <!-- Spoken description for Unicode code point U+1F33C: "🌼" BLOSSOM -->
+ <string name="spoken_emoji_1F33C">Blossom</string>
+ <!-- Spoken description for Unicode code point U+1F33D: "🌽" EAR OF MAIZE -->
+ <string name="spoken_emoji_1F33D">Ear of maize</string>
+ <!-- Spoken description for Unicode code point U+1F33E: "🌾" EAR OF RICE -->
+ <string name="spoken_emoji_1F33E">Ear of rice</string>
+ <!-- Spoken description for Unicode code point U+1F33F: "🌿" HERB -->
+ <string name="spoken_emoji_1F33F">Herb</string>
+ <!-- Spoken description for Unicode code point U+1F340: "🍀" FOUR LEAF CLOVER -->
+ <string name="spoken_emoji_1F340">Four leaf clover</string>
+ <!-- Spoken description for Unicode code point U+1F341: "🍁" MAPLE LEAF -->
+ <string name="spoken_emoji_1F341">Maple leaf</string>
+ <!-- Spoken description for Unicode code point U+1F342: "🍂" FALLEN LEAF -->
+ <string name="spoken_emoji_1F342">Fallen leaf</string>
+ <!-- Spoken description for Unicode code point U+1F343: "🍃" LEAF FLUTTERING IN WIND -->
+ <string name="spoken_emoji_1F343">Leaf fluttering in wind</string>
+ <!-- Spoken description for Unicode code point U+1F344: "🍄" MUSHROOM -->
+ <string name="spoken_emoji_1F344">Mushroom</string>
+ <!-- Spoken description for Unicode code point U+1F345: "🍅" TOMATO -->
+ <string name="spoken_emoji_1F345">Tomato</string>
+ <!-- Spoken description for Unicode code point U+1F346: "🍆" AUBERGINE -->
+ <string name="spoken_emoji_1F346">Aubergine</string>
+ <!-- Spoken description for Unicode code point U+1F347: "🍇" GRAPES -->
+ <string name="spoken_emoji_1F347">Grapes</string>
+ <!-- Spoken description for Unicode code point U+1F348: "🍈" MELON -->
+ <string name="spoken_emoji_1F348">Melon</string>
+ <!-- Spoken description for Unicode code point U+1F349: "🍉" WATERMELON -->
+ <string name="spoken_emoji_1F349">Watermelon</string>
+ <!-- Spoken description for Unicode code point U+1F34A: "🍊" TANGERINE -->
+ <string name="spoken_emoji_1F34A">Tangerine</string>
+ <!-- Spoken description for Unicode code point U+1F34B: "🍋" LEMON -->
+ <string name="spoken_emoji_1F34B">Lemon</string>
+ <!-- Spoken description for Unicode code point U+1F34C: "🍌" BANANA -->
+ <string name="spoken_emoji_1F34C">Banana</string>
+ <!-- Spoken description for Unicode code point U+1F34D: "🍍" PINEAPPLE -->
+ <string name="spoken_emoji_1F34D">Pineapple</string>
+ <!-- Spoken description for Unicode code point U+1F34E: "🍎" RED APPLE -->
+ <string name="spoken_emoji_1F34E">Red apple</string>
+ <!-- Spoken description for Unicode code point U+1F34F: "🍏" GREEN APPLE -->
+ <string name="spoken_emoji_1F34F">Green apple</string>
+ <!-- Spoken description for Unicode code point U+1F350: "🍐" PEAR -->
+ <string name="spoken_emoji_1F350">Pear</string>
+ <!-- Spoken description for Unicode code point U+1F351: "🍑" PEACH -->
+ <string name="spoken_emoji_1F351">Peach</string>
+ <!-- Spoken description for Unicode code point U+1F352: "🍒" CHERRIES -->
+ <string name="spoken_emoji_1F352">Cherries</string>
+ <!-- Spoken description for Unicode code point U+1F353: "🍓" STRAWBERRY -->
+ <string name="spoken_emoji_1F353">Strawberry</string>
+ <!-- Spoken description for Unicode code point U+1F354: "🍔" HAMBURGER -->
+ <string name="spoken_emoji_1F354">Hamburger</string>
+ <!-- Spoken description for Unicode code point U+1F355: "🍕" SLICE OF PIZZA -->
+ <string name="spoken_emoji_1F355">Slice of pizza</string>
+ <!-- Spoken description for Unicode code point U+1F356: "🍖" MEAT ON BONE -->
+ <string name="spoken_emoji_1F356">Meat on bone</string>
+ <!-- Spoken description for Unicode code point U+1F357: "🍗" POULTRY LEG -->
+ <string name="spoken_emoji_1F357">Poultry leg</string>
+ <!-- Spoken description for Unicode code point U+1F358: "🍘" RICE CRACKER -->
+ <string name="spoken_emoji_1F358">Rice cracker</string>
+ <!-- Spoken description for Unicode code point U+1F359: "🍙" RICE BALL -->
+ <string name="spoken_emoji_1F359">Rice ball</string>
+ <!-- Spoken description for Unicode code point U+1F35A: "🍚" COOKED RICE -->
+ <string name="spoken_emoji_1F35A">Cooked rice</string>
+ <!-- Spoken description for Unicode code point U+1F35B: "🍛" CURRY AND RICE -->
+ <string name="spoken_emoji_1F35B">Curry and rice</string>
+ <!-- Spoken description for Unicode code point U+1F35C: "🍜" STEAMING BOWL -->
+ <string name="spoken_emoji_1F35C">Steaming bowl</string>
+ <!-- Spoken description for Unicode code point U+1F35D: "🍝" SPAGHETTI -->
+ <string name="spoken_emoji_1F35D">Spaghetti</string>
+ <!-- Spoken description for Unicode code point U+1F35E: "🍞" BREAD -->
+ <string name="spoken_emoji_1F35E">Bread</string>
+ <!-- Spoken description for Unicode code point U+1F35F: "🍟" FRENCH FRIES -->
+ <string name="spoken_emoji_1F35F">French fries</string>
+ <!-- Spoken description for Unicode code point U+1F360: "🍠" ROASTED SWEET POTATO -->
+ <string name="spoken_emoji_1F360">Roasted sweet potato</string>
+ <!-- Spoken description for Unicode code point U+1F361: "🍡" DANGO -->
+ <string name="spoken_emoji_1F361">Dango</string>
+ <!-- Spoken description for Unicode code point U+1F362: "🍢" ODEN -->
+ <string name="spoken_emoji_1F362">Oden</string>
+ <!-- Spoken description for Unicode code point U+1F363: "🍣" SUSHI -->
+ <string name="spoken_emoji_1F363">Sushi</string>
+ <!-- Spoken description for Unicode code point U+1F364: "🍤" FRIED SHRIMP -->
+ <string name="spoken_emoji_1F364">Fried shrimp</string>
+ <!-- Spoken description for Unicode code point U+1F365: "🍥" FISH CAKE WITH SWIRL DESIGN -->
+ <string name="spoken_emoji_1F365">Fish cake with swirl design</string>
+ <!-- Spoken description for Unicode code point U+1F366: "🍦" SOFT ICE CREAM -->
+ <string name="spoken_emoji_1F366">Soft ice cream</string>
+ <!-- Spoken description for Unicode code point U+1F367: "🍧" SHAVED ICE -->
+ <string name="spoken_emoji_1F367">Shaved ice</string>
+ <!-- Spoken description for Unicode code point U+1F368: "🍨" ICE CREAM -->
+ <string name="spoken_emoji_1F368">Ice cream</string>
+ <!-- Spoken description for Unicode code point U+1F369: "🍩" DOUGHNUT -->
+ <string name="spoken_emoji_1F369">Doughnut</string>
+ <!-- Spoken description for Unicode code point U+1F36A: "🍪" COOKIE -->
+ <string name="spoken_emoji_1F36A">Cookie</string>
+ <!-- Spoken description for Unicode code point U+1F36B: "🍫" CHOCOLATE BAR -->
+ <string name="spoken_emoji_1F36B">Chocolate bar</string>
+ <!-- Spoken description for Unicode code point U+1F36C: "🍬" CANDY -->
+ <string name="spoken_emoji_1F36C">Candy</string>
+ <!-- Spoken description for Unicode code point U+1F36D: "🍭" LOLLIPOP -->
+ <string name="spoken_emoji_1F36D">Lollipop</string>
+ <!-- Spoken description for Unicode code point U+1F36E: "🍮" CUSTARD -->
+ <string name="spoken_emoji_1F36E">Custard</string>
+ <!-- Spoken description for Unicode code point U+1F36F: "🍯" HONEY POT -->
+ <string name="spoken_emoji_1F36F">Honey pot</string>
+ <!-- Spoken description for Unicode code point U+1F370: "🍰" SHORTCAKE -->
+ <string name="spoken_emoji_1F370">Shortcake</string>
+ <!-- Spoken description for Unicode code point U+1F371: "🍱" BENTO BOX -->
+ <string name="spoken_emoji_1F371">Bento box</string>
+ <!-- Spoken description for Unicode code point U+1F372: "🍲" POT OF FOOD -->
+ <string name="spoken_emoji_1F372">Pot of food</string>
+ <!-- Spoken description for Unicode code point U+1F373: "🍳" COOKING -->
+ <string name="spoken_emoji_1F373">Cooking</string>
+ <!-- Spoken description for Unicode code point U+1F374: "🍴" FORK AND KNIFE -->
+ <string name="spoken_emoji_1F374">Fork and knife</string>
+ <!-- Spoken description for Unicode code point U+1F375: "🍵" TEACUP WITHOUT HANDLE -->
+ <string name="spoken_emoji_1F375">Teacup without handle</string>
+ <!-- Spoken description for Unicode code point U+1F376: "🍶" SAKE BOTTLE AND CUP -->
+ <string name="spoken_emoji_1F376">Sake bottle and cup</string>
+ <!-- Spoken description for Unicode code point U+1F377: "🍷" WINE GLASS -->
+ <string name="spoken_emoji_1F377">Wine glass</string>
+ <!-- Spoken description for Unicode code point U+1F378: "🍸" COCKTAIL GLASS -->
+ <string name="spoken_emoji_1F378">Cocktail glass</string>
+ <!-- Spoken description for Unicode code point U+1F379: "🍹" TROPICAL DRINK -->
+ <string name="spoken_emoji_1F379">Tropical drink</string>
+ <!-- Spoken description for Unicode code point U+1F37A: "🍺" BEER MUG -->
+ <string name="spoken_emoji_1F37A">Beer mug</string>
+ <!-- Spoken description for Unicode code point U+1F37B: "🍻" CLINKING BEER MUGS -->
+ <string name="spoken_emoji_1F37B">Clinking beer mugs</string>
+ <!-- Spoken description for Unicode code point U+1F37C: "🍼" BABY BOTTLE -->
+ <string name="spoken_emoji_1F37C">Baby bottle</string>
+ <!-- Spoken description for Unicode code point U+1F380: "🎀" RIBBON -->
+ <string name="spoken_emoji_1F380">Ribbon</string>
+ <!-- Spoken description for Unicode code point U+1F381: "🎁" WRAPPED PRESENT -->
+ <string name="spoken_emoji_1F381">Wrapped present</string>
+ <!-- Spoken description for Unicode code point U+1F382: "🎂" BIRTHDAY CAKE -->
+ <string name="spoken_emoji_1F382">Birthday cake</string>
+ <!-- Spoken description for Unicode code point U+1F383: "🎃" JACK-O-LANTERN -->
+ <string name="spoken_emoji_1F383">Jack-o-lantern</string>
+ <!-- Spoken description for Unicode code point U+1F384: "🎄" CHRISTMAS TREE -->
+ <string name="spoken_emoji_1F384">Christmas tree</string>
+ <!-- Spoken description for Unicode code point U+1F385: "🎅" FATHER CHRISTMAS -->
+ <string name="spoken_emoji_1F385">Father christmas</string>
+ <!-- Spoken description for Unicode code point U+1F386: "🎆" FIREWORKS -->
+ <string name="spoken_emoji_1F386">Fireworks</string>
+ <!-- Spoken description for Unicode code point U+1F387: "🎇" FIREWORK SPARKLER -->
+ <string name="spoken_emoji_1F387">Firework sparkler</string>
+ <!-- Spoken description for Unicode code point U+1F388: "🎈" BALLOON -->
+ <string name="spoken_emoji_1F388">Balloon</string>
+ <!-- Spoken description for Unicode code point U+1F389: "🎉" PARTY POPPER -->
+ <string name="spoken_emoji_1F389">Party popper</string>
+ <!-- Spoken description for Unicode code point U+1F38A: "🎊" CONFETTI BALL -->
+ <string name="spoken_emoji_1F38A">Confetti ball</string>
+ <!-- Spoken description for Unicode code point U+1F38B: "🎋" TANABATA TREE -->
+ <string name="spoken_emoji_1F38B">Tanabata tree</string>
+ <!-- Spoken description for Unicode code point U+1F38C: "🎌" CROSSED FLAGS -->
+ <string name="spoken_emoji_1F38C">Crossed flags</string>
+ <!-- Spoken description for Unicode code point U+1F38D: "🎍" PINE DECORATION -->
+ <string name="spoken_emoji_1F38D">Pine decoration</string>
+ <!-- Spoken description for Unicode code point U+1F38E: "🎎" JAPANESE DOLLS -->
+ <string name="spoken_emoji_1F38E">Japanese dolls</string>
+ <!-- Spoken description for Unicode code point U+1F38F: "🎏" CARP STREAMER -->
+ <string name="spoken_emoji_1F38F">Carp streamer</string>
+ <!-- Spoken description for Unicode code point U+1F390: "🎐" WIND CHIME -->
+ <string name="spoken_emoji_1F390">Wind chime</string>
+ <!-- Spoken description for Unicode code point U+1F391: "🎑" MOON VIEWING CEREMONY -->
+ <string name="spoken_emoji_1F391">Moon viewing ceremony</string>
+ <!-- Spoken description for Unicode code point U+1F392: "🎒" SCHOOL SATCHEL -->
+ <string name="spoken_emoji_1F392">School satchel</string>
+ <!-- Spoken description for Unicode code point U+1F393: "🎓" GRADUATION CAP -->
+ <string name="spoken_emoji_1F393">Graduation cap</string>
+ <!-- Spoken description for Unicode code point U+1F3A0: "🎠" CAROUSEL HORSE -->
+ <string name="spoken_emoji_1F3A0">Carousel horse</string>
+ <!-- Spoken description for Unicode code point U+1F3A1: "🎡" FERRIS WHEEL -->
+ <string name="spoken_emoji_1F3A1">Ferris wheel</string>
+ <!-- Spoken description for Unicode code point U+1F3A2: "🎢" ROLLER COASTER -->
+ <string name="spoken_emoji_1F3A2">Roller coaster</string>
+ <!-- Spoken description for Unicode code point U+1F3A3: "🎣" FISHING POLE AND FISH -->
+ <string name="spoken_emoji_1F3A3">Fishing pole and fish</string>
+ <!-- Spoken description for Unicode code point U+1F3A4: "🎤" MICROPHONE -->
+ <string name="spoken_emoji_1F3A4">Microphone</string>
+ <!-- Spoken description for Unicode code point U+1F3A5: "🎥" MOVIE CAMERA -->
+ <string name="spoken_emoji_1F3A5">Movie camera</string>
+ <!-- Spoken description for Unicode code point U+1F3A6: "🎦" CINEMA -->
+ <string name="spoken_emoji_1F3A6">Cinema</string>
+ <!-- Spoken description for Unicode code point U+1F3A7: "🎧" HEADPHONE -->
+ <string name="spoken_emoji_1F3A7">Headphone</string>
+ <!-- Spoken description for Unicode code point U+1F3A8: "🎨" ARTIST PALETTE -->
+ <string name="spoken_emoji_1F3A8">Artist palette</string>
+ <!-- Spoken description for Unicode code point U+1F3A9: "🎩" TOP HAT -->
+ <string name="spoken_emoji_1F3A9">Top hat</string>
+ <!-- Spoken description for Unicode code point U+1F3AA: "🎪" CIRCUS TENT -->
+ <string name="spoken_emoji_1F3AA">Circus tent</string>
+ <!-- Spoken description for Unicode code point U+1F3AB: "🎫" TICKET -->
+ <string name="spoken_emoji_1F3AB">Ticket</string>
+ <!-- Spoken description for Unicode code point U+1F3AC: "🎬" CLAPPER BOARD -->
+ <string name="spoken_emoji_1F3AC">Clapper board</string>
+ <!-- Spoken description for Unicode code point U+1F3AD: "🎭" PERFORMING ARTS -->
+ <string name="spoken_emoji_1F3AD">Performing arts</string>
+ <!-- Spoken description for Unicode code point U+1F3AE: "🎮" VIDEO GAME -->
+ <string name="spoken_emoji_1F3AE">Video game</string>
+ <!-- Spoken description for Unicode code point U+1F3AF: "🎯" DIRECT HIT -->
+ <string name="spoken_emoji_1F3AF">Direct hit</string>
+ <!-- Spoken description for Unicode code point U+1F3B0: "🎰" SLOT MACHINE -->
+ <string name="spoken_emoji_1F3B0">Slot machine</string>
+ <!-- Spoken description for Unicode code point U+1F3B1: "🎱" BILLIARDS -->
+ <string name="spoken_emoji_1F3B1">Billiards</string>
+ <!-- Spoken description for Unicode code point U+1F3B2: "🎲" GAME DIE -->
+ <string name="spoken_emoji_1F3B2">Game die</string>
+ <!-- Spoken description for Unicode code point U+1F3B3: "🎳" BOWLING -->
+ <string name="spoken_emoji_1F3B3">Bowling</string>
+ <!-- Spoken description for Unicode code point U+1F3B4: "🎴" FLOWER PLAYING CARDS -->
+ <string name="spoken_emoji_1F3B4">Flower playing cards</string>
+ <!-- Spoken description for Unicode code point U+1F3B5: "🎵" MUSICAL NOTE -->
+ <string name="spoken_emoji_1F3B5">Musical note</string>
+ <!-- Spoken description for Unicode code point U+1F3B6: "🎶" MULTIPLE MUSICAL NOTES -->
+ <string name="spoken_emoji_1F3B6">Multiple musical notes</string>
+ <!-- Spoken description for Unicode code point U+1F3B7: "🎷" SAXOPHONE -->
+ <string name="spoken_emoji_1F3B7">Saxophone</string>
+ <!-- Spoken description for Unicode code point U+1F3B8: "🎸" GUITAR -->
+ <string name="spoken_emoji_1F3B8">Guitar</string>
+ <!-- Spoken description for Unicode code point U+1F3B9: "🎹" MUSICAL KEYBOARD -->
+ <string name="spoken_emoji_1F3B9">Musical keyboard</string>
+ <!-- Spoken description for Unicode code point U+1F3BA: "🎺" TRUMPET -->
+ <string name="spoken_emoji_1F3BA">Trumpet</string>
+ <!-- Spoken description for Unicode code point U+1F3BB: "🎻" VIOLIN -->
+ <string name="spoken_emoji_1F3BB">Violin</string>
+ <!-- Spoken description for Unicode code point U+1F3BC: "🎼" MUSICAL SCORE -->
+ <string name="spoken_emoji_1F3BC">Musical score</string>
+ <!-- Spoken description for Unicode code point U+1F3BD: "🎽" RUNNING SHIRT WITH SASH -->
+ <string name="spoken_emoji_1F3BD">Running shirt with sash</string>
+ <!-- Spoken description for Unicode code point U+1F3BE: "🎾" TENNIS RACQUET AND BALL -->
+ <string name="spoken_emoji_1F3BE">Tennis racquet and ball</string>
+ <!-- Spoken description for Unicode code point U+1F3BF: "🎿" SKI AND SKI BOOT -->
+ <string name="spoken_emoji_1F3BF">Ski and ski boot</string>
+ <!-- Spoken description for Unicode code point U+1F3C0: "🏀" BASKETBALL AND HOOP -->
+ <string name="spoken_emoji_1F3C0">Basketball and hoop</string>
+ <!-- Spoken description for Unicode code point U+1F3C1: "🏁" CHEQUERED FLAG -->
+ <string name="spoken_emoji_1F3C1">Chequered flag</string>
+ <!-- Spoken description for Unicode code point U+1F3C2: "🏂" SNOWBOARDER -->
+ <string name="spoken_emoji_1F3C2">Snowboarder</string>
+ <!-- Spoken description for Unicode code point U+1F3C3: "🏃" RUNNER -->
+ <string name="spoken_emoji_1F3C3">Runner</string>
+ <!-- Spoken description for Unicode code point U+1F3C4: "🏄" SURFER -->
+ <string name="spoken_emoji_1F3C4">Surfer</string>
+ <!-- Spoken description for Unicode code point U+1F3C6: "🏆" TROPHY -->
+ <string name="spoken_emoji_1F3C6">Trophy</string>
+ <!-- Spoken description for Unicode code point U+1F3C7: "🏇" HORSE RACING -->
+ <string name="spoken_emoji_1F3C7">Horse racing</string>
+ <!-- Spoken description for Unicode code point U+1F3C8: "🏈" AMERICAN FOOTBALL -->
+ <string name="spoken_emoji_1F3C8">American football</string>
+ <!-- Spoken description for Unicode code point U+1F3C9: "🏉" RUGBY FOOTBALL -->
+ <string name="spoken_emoji_1F3C9">Rugby football</string>
+ <!-- Spoken description for Unicode code point U+1F3CA: "🏊" SWIMMER -->
+ <string name="spoken_emoji_1F3CA">Swimmer</string>
+ <!-- Spoken description for Unicode code point U+1F3E0: "🏠" HOUSE BUILDING -->
+ <string name="spoken_emoji_1F3E0">House building</string>
+ <!-- Spoken description for Unicode code point U+1F3E1: "🏡" HOUSE WITH GARDEN -->
+ <string name="spoken_emoji_1F3E1">House with garden</string>
+ <!-- Spoken description for Unicode code point U+1F3E2: "🏢" OFFICE BUILDING -->
+ <string name="spoken_emoji_1F3E2">Office building</string>
+ <!-- Spoken description for Unicode code point U+1F3E3: "🏣" JAPANESE POST OFFICE -->
+ <string name="spoken_emoji_1F3E3">Japanese post office</string>
+ <!-- Spoken description for Unicode code point U+1F3E4: "🏤" EUROPEAN POST OFFICE -->
+ <string name="spoken_emoji_1F3E4">European post office</string>
+ <!-- Spoken description for Unicode code point U+1F3E5: "🏥" HOSPITAL -->
+ <string name="spoken_emoji_1F3E5">Hospital</string>
+ <!-- Spoken description for Unicode code point U+1F3E6: "🏦" BANK -->
+ <string name="spoken_emoji_1F3E6">Bank</string>
+ <!-- Spoken description for Unicode code point U+1F3E7: "🏧" AUTOMATED TELLER MACHINE -->
+ <string name="spoken_emoji_1F3E7">Automated teller machine</string>
+ <!-- Spoken description for Unicode code point U+1F3E8: "🏨" HOTEL -->
+ <string name="spoken_emoji_1F3E8">Hotel</string>
+ <!-- Spoken description for Unicode code point U+1F3E9: "🏩" LOVE HOTEL -->
+ <string name="spoken_emoji_1F3E9">Love hotel</string>
+ <!-- Spoken description for Unicode code point U+1F3EA: "🏪" CONVENIENCE STORE -->
+ <string name="spoken_emoji_1F3EA">Convenience store</string>
+ <!-- Spoken description for Unicode code point U+1F3EB: "🏫" SCHOOL -->
+ <string name="spoken_emoji_1F3EB">School</string>
+ <!-- Spoken description for Unicode code point U+1F3EC: "🏬" DEPARTMENT STORE -->
+ <string name="spoken_emoji_1F3EC">Department store</string>
+ <!-- Spoken description for Unicode code point U+1F3ED: "🏭" FACTORY -->
+ <string name="spoken_emoji_1F3ED">Factory</string>
+ <!-- Spoken description for Unicode code point U+1F3EE: "🏮" IZAKAYA LANTERN -->
+ <string name="spoken_emoji_1F3EE">Izakaya lantern</string>
+ <!-- Spoken description for Unicode code point U+1F3EF: "🏯" JAPANESE CASTLE -->
+ <string name="spoken_emoji_1F3EF">Japanese castle</string>
+ <!-- Spoken description for Unicode code point U+1F3F0: "🏰" EUROPEAN CASTLE -->
+ <string name="spoken_emoji_1F3F0">European castle</string>
+ <!-- Spoken description for Unicode code point U+1F400: "🐀" RAT -->
+ <string name="spoken_emoji_1F400">Rat</string>
+ <!-- Spoken description for Unicode code point U+1F401: "🐁" MOUSE -->
+ <string name="spoken_emoji_1F401">Mouse</string>
+ <!-- Spoken description for Unicode code point U+1F402: "🐂" OX -->
+ <string name="spoken_emoji_1F402">Ox</string>
+ <!-- Spoken description for Unicode code point U+1F403: "🐃" WATER BUFFALO -->
+ <string name="spoken_emoji_1F403">Water buffalo</string>
+ <!-- Spoken description for Unicode code point U+1F404: "🐄" COW -->
+ <string name="spoken_emoji_1F404">Cow</string>
+ <!-- Spoken description for Unicode code point U+1F406: "🐆" LEOPARD -->
+ <string name="spoken_emoji_1F406">Leopard</string>
+ <!-- Spoken description for Unicode code point U+1F407: "🐇" RABBIT -->
+ <string name="spoken_emoji_1F407">Rabbit</string>
+ <!-- Spoken description for Unicode code point U+1F408: "🐈" CAT -->
+ <string name="spoken_emoji_1F408">Cat</string>
+ <!-- Spoken description for Unicode code point U+1F409: "🐉" DRAGON -->
+ <string name="spoken_emoji_1F409">Dragon</string>
+ <!-- Spoken description for Unicode code point U+1F40A: "🐊" CROCODILE -->
+ <string name="spoken_emoji_1F40A">Crocodile</string>
+ <!-- Spoken description for Unicode code point U+1F40B: "🐋" WHALE -->
+ <string name="spoken_emoji_1F40B">Whale</string>
+ <!-- Spoken description for Unicode code point U+1F40C: "🐌" SNAIL -->
+ <string name="spoken_emoji_1F40C">Snail</string>
+ <!-- Spoken description for Unicode code point U+1F40D: "🐍" SNAKE -->
+ <string name="spoken_emoji_1F40D">Snake</string>
+ <!-- Spoken description for Unicode code point U+1F40E: "🐎" HORSE -->
+ <string name="spoken_emoji_1F40E">Horse</string>
+ <!-- Spoken description for Unicode code point U+1F40F: "🐏" RAM -->
+ <string name="spoken_emoji_1F40F">Ram</string>
+ <!-- Spoken description for Unicode code point U+1F410: "🐐" GOAT -->
+ <string name="spoken_emoji_1F410">Goat</string>
+ <!-- Spoken description for Unicode code point U+1F411: "🐑" SHEEP -->
+ <string name="spoken_emoji_1F411">Sheep</string>
+ <!-- Spoken description for Unicode code point U+1F412: "🐒" MONKEY -->
+ <string name="spoken_emoji_1F412">Monkey</string>
+ <!-- Spoken description for Unicode code point U+1F413: "🐓" ROOSTER -->
+ <string name="spoken_emoji_1F413">Rooster</string>
+ <!-- Spoken description for Unicode code point U+1F414: "🐔" CHICKEN -->
+ <string name="spoken_emoji_1F414">Chicken</string>
+ <!-- Spoken description for Unicode code point U+1F415: "🐕" DOG -->
+ <string name="spoken_emoji_1F415">Dog</string>
+ <!-- Spoken description for Unicode code point U+1F416: "🐖" PIG -->
+ <string name="spoken_emoji_1F416">Pig</string>
+ <!-- Spoken description for Unicode code point U+1F417: "🐗" BOAR -->
+ <string name="spoken_emoji_1F417">Boar</string>
+ <!-- Spoken description for Unicode code point U+1F418: "🐘" ELEPHANT -->
+ <string name="spoken_emoji_1F418">Elephant</string>
+ <!-- Spoken description for Unicode code point U+1F419: "🐙" OCTOPUS -->
+ <string name="spoken_emoji_1F419">Octopus</string>
+ <!-- Spoken description for Unicode code point U+1F41A: "🐚" SPIRAL SHELL -->
+ <string name="spoken_emoji_1F41A">Spiral shell</string>
+ <!-- Spoken description for Unicode code point U+1F41B: "🐛" BUG -->
+ <string name="spoken_emoji_1F41B">Bug</string>
+ <!-- Spoken description for Unicode code point U+1F41C: "🐜" ANT -->
+ <string name="spoken_emoji_1F41C">Ant</string>
+ <!-- Spoken description for Unicode code point U+1F41D: "🐝" HONEYBEE -->
+ <string name="spoken_emoji_1F41D">Honeybee</string>
+ <!-- Spoken description for Unicode code point U+1F41E: "🐞" LADY BEETLE -->
+ <string name="spoken_emoji_1F41E">Lady beetle</string>
+ <!-- Spoken description for Unicode code point U+1F41F: "🐟" FISH -->
+ <string name="spoken_emoji_1F41F">Fish</string>
+ <!-- Spoken description for Unicode code point U+1F420: "🐠" TROPICAL FISH -->
+ <string name="spoken_emoji_1F420">Tropical fish</string>
+ <!-- Spoken description for Unicode code point U+1F421: "🐡" BLOWFISH -->
+ <string name="spoken_emoji_1F421">Blowfish</string>
+ <!-- Spoken description for Unicode code point U+1F422: "🐢" TURTLE -->
+ <string name="spoken_emoji_1F422">Turtle</string>
+ <!-- Spoken description for Unicode code point U+1F423: "🐣" HATCHING CHICK -->
+ <string name="spoken_emoji_1F423">Hatching chick</string>
+ <!-- Spoken description for Unicode code point U+1F424: "🐤" BABY CHICK -->
+ <string name="spoken_emoji_1F424">Baby chick</string>
+ <!-- Spoken description for Unicode code point U+1F425: "🐥" FRONT-FACING BABY CHICK -->
+ <string name="spoken_emoji_1F425">Front-facing baby chick</string>
+ <!-- Spoken description for Unicode code point U+1F426: "🐦" BIRD -->
+ <string name="spoken_emoji_1F426">Bird</string>
+ <!-- Spoken description for Unicode code point U+1F427: "🐧" PENGUIN -->
+ <string name="spoken_emoji_1F427">Penguin</string>
+ <!-- Spoken description for Unicode code point U+1F428: "🐨" KOALA -->
+ <string name="spoken_emoji_1F428">Koala</string>
+ <!-- Spoken description for Unicode code point U+1F429: "🐩" POODLE -->
+ <string name="spoken_emoji_1F429">Poodle</string>
+ <!-- Spoken description for Unicode code point U+1F42A: "🐪" DROMEDARY CAMEL -->
+ <string name="spoken_emoji_1F42A">Dromedary camel</string>
+ <!-- Spoken description for Unicode code point U+1F42B: "🐫" BACTRIAN CAMEL -->
+ <string name="spoken_emoji_1F42B">Bactrian camel</string>
+ <!-- Spoken description for Unicode code point U+1F42C: "🐬" DOLPHIN -->
+ <string name="spoken_emoji_1F42C">Dolphin</string>
+ <!-- Spoken description for Unicode code point U+1F42D: "🐭" MOUSE FACE -->
+ <string name="spoken_emoji_1F42D">Mouse face</string>
+ <!-- Spoken description for Unicode code point U+1F42E: "🐮" COW FACE -->
+ <string name="spoken_emoji_1F42E">Cow face</string>
+ <!-- Spoken description for Unicode code point U+1F42F: "🐯" TIGER FACE -->
+ <string name="spoken_emoji_1F42F">Tiger face</string>
+ <!-- Spoken description for Unicode code point U+1F430: "🐰" RABBIT FACE -->
+ <string name="spoken_emoji_1F430">Rabbit face</string>
+ <!-- Spoken description for Unicode code point U+1F431: "🐱" CAT FACE -->
+ <string name="spoken_emoji_1F431">Cat face</string>
+ <!-- Spoken description for Unicode code point U+1F432: "🐲" DRAGON FACE -->
+ <string name="spoken_emoji_1F432">Dragon face</string>
+ <!-- Spoken description for Unicode code point U+1F433: "🐳" SPOUTING WHALE -->
+ <string name="spoken_emoji_1F433">Spouting whale</string>
+ <!-- Spoken description for Unicode code point U+1F434: "🐴" HORSE FACE -->
+ <string name="spoken_emoji_1F434">Horse face</string>
+ <!-- Spoken description for Unicode code point U+1F435: "🐵" MONKEY FACE -->
+ <string name="spoken_emoji_1F435">Monkey face</string>
+ <!-- Spoken description for Unicode code point U+1F436: "🐶" DOG FACE -->
+ <string name="spoken_emoji_1F436">Dog face</string>
+ <!-- Spoken description for Unicode code point U+1F437: "🐷" PIG FACE -->
+ <string name="spoken_emoji_1F437">Pig face</string>
+ <!-- Spoken description for Unicode code point U+1F438: "🐸" FROG FACE -->
+ <string name="spoken_emoji_1F438">Frog face</string>
+ <!-- Spoken description for Unicode code point U+1F439: "🐹" HAMSTER FACE -->
+ <string name="spoken_emoji_1F439">Hamster face</string>
+ <!-- Spoken description for Unicode code point U+1F43A: "🐺" WOLF FACE -->
+ <string name="spoken_emoji_1F43A">Wolf face</string>
+ <!-- Spoken description for Unicode code point U+1F43B: "🐻" BEAR FACE -->
+ <string name="spoken_emoji_1F43B">Bear face</string>
+ <!-- Spoken description for Unicode code point U+1F43C: "🐼" PANDA FACE -->
+ <string name="spoken_emoji_1F43C">Panda face</string>
+ <!-- Spoken description for Unicode code point U+1F43D: "🐽" PIG NOSE -->
+ <string name="spoken_emoji_1F43D">Pig nose</string>
+ <!-- Spoken description for Unicode code point U+1F43E: "🐾" PAW PRINTS -->
+ <string name="spoken_emoji_1F43E">Paw prints</string>
+ <!-- Spoken description for Unicode code point U+1F440: "👀" EYES -->
+ <string name="spoken_emoji_1F440">Eyes</string>
+ <!-- Spoken description for Unicode code point U+1F442: "👂" EAR -->
+ <string name="spoken_emoji_1F442">Ear</string>
+ <!-- Spoken description for Unicode code point U+1F443: "👃" NOSE -->
+ <string name="spoken_emoji_1F443">Nose</string>
+ <!-- Spoken description for Unicode code point U+1F444: "👄" MOUTH -->
+ <string name="spoken_emoji_1F444">Mouth</string>
+ <!-- Spoken description for Unicode code point U+1F445: "👅" TONGUE -->
+ <string name="spoken_emoji_1F445">Tongue</string>
+ <!-- Spoken description for Unicode code point U+1F446: "👆" WHITE UP POINTING BACKHAND INDEX -->
+ <string name="spoken_emoji_1F446">White up pointing backhand index</string>
+ <!-- Spoken description for Unicode code point U+1F447: "👇" WHITE DOWN POINTING BACKHAND INDEX -->
+ <string name="spoken_emoji_1F447">White down pointing backhand index</string>
+ <!-- Spoken description for Unicode code point U+1F448: "👈" WHITE LEFT POINTING BACKHAND INDEX -->
+ <string name="spoken_emoji_1F448">White left pointing backhand index</string>
+ <!-- Spoken description for Unicode code point U+1F449: "👉" WHITE RIGHT POINTING BACKHAND INDEX -->
+ <string name="spoken_emoji_1F449">White right pointing backhand index</string>
+ <!-- Spoken description for Unicode code point U+1F44A: "👊" FISTED HAND SIGN -->
+ <string name="spoken_emoji_1F44A">Fisted hand sign</string>
+ <!-- Spoken description for Unicode code point U+1F44B: "👋" WAVING HAND SIGN -->
+ <string name="spoken_emoji_1F44B">Waving hand sign</string>
+ <!-- Spoken description for Unicode code point U+1F44C: "👌" OK HAND SIGN -->
+ <string name="spoken_emoji_1F44C">Ok hand sign</string>
+ <!-- Spoken description for Unicode code point U+1F44D: "👍" THUMBS UP SIGN -->
+ <string name="spoken_emoji_1F44D">Thumbs up sign</string>
+ <!-- Spoken description for Unicode code point U+1F44E: "👎" THUMBS DOWN SIGN -->
+ <string name="spoken_emoji_1F44E">Thumbs down sign</string>
+ <!-- Spoken description for Unicode code point U+1F44F: "👏" CLAPPING HANDS SIGN -->
+ <string name="spoken_emoji_1F44F">Clapping hands sign</string>
+ <!-- Spoken description for Unicode code point U+1F450: "👐" OPEN HANDS SIGN -->
+ <string name="spoken_emoji_1F450">Open hands sign</string>
+ <!-- Spoken description for Unicode code point U+1F451: "👑" CROWN -->
+ <string name="spoken_emoji_1F451">Crown</string>
+ <!-- Spoken description for Unicode code point U+1F452: "👒" WOMANS HAT -->
+ <string name="spoken_emoji_1F452">Womans hat</string>
+ <!-- Spoken description for Unicode code point U+1F453: "👓" EYEGLASSES -->
+ <string name="spoken_emoji_1F453">Eyeglasses</string>
+ <!-- Spoken description for Unicode code point U+1F454: "👔" NECKTIE -->
+ <string name="spoken_emoji_1F454">Necktie</string>
+ <!-- Spoken description for Unicode code point U+1F455: "👕" T-SHIRT -->
+ <string name="spoken_emoji_1F455">T-shirt</string>
+ <!-- Spoken description for Unicode code point U+1F456: "👖" JEANS -->
+ <string name="spoken_emoji_1F456">Jeans</string>
+ <!-- Spoken description for Unicode code point U+1F457: "👗" DRESS -->
+ <string name="spoken_emoji_1F457">Dress</string>
+ <!-- Spoken description for Unicode code point U+1F458: "👘" KIMONO -->
+ <string name="spoken_emoji_1F458">Kimono</string>
+ <!-- Spoken description for Unicode code point U+1F459: "👙" BIKINI -->
+ <string name="spoken_emoji_1F459">Bikini</string>
+ <!-- Spoken description for Unicode code point U+1F45A: "👚" WOMANS CLOTHES -->
+ <string name="spoken_emoji_1F45A">Womans clothes</string>
+ <!-- Spoken description for Unicode code point U+1F45B: "👛" PURSE -->
+ <string name="spoken_emoji_1F45B">Purse</string>
+ <!-- Spoken description for Unicode code point U+1F45C: "👜" HANDBAG -->
+ <string name="spoken_emoji_1F45C">Handbag</string>
+ <!-- Spoken description for Unicode code point U+1F45D: "👝" POUCH -->
+ <string name="spoken_emoji_1F45D">Pouch</string>
+ <!-- Spoken description for Unicode code point U+1F45E: "👞" MANS SHOE -->
+ <string name="spoken_emoji_1F45E">Mans shoe</string>
+ <!-- Spoken description for Unicode code point U+1F45F: "👟" ATHLETIC SHOE -->
+ <string name="spoken_emoji_1F45F">Athletic shoe</string>
+ <!-- Spoken description for Unicode code point U+1F460: "👠" HIGH-HEELED SHOE -->
+ <string name="spoken_emoji_1F460">High-heeled shoe</string>
+ <!-- Spoken description for Unicode code point U+1F461: "👡" WOMANS SANDAL -->
+ <string name="spoken_emoji_1F461">Womans sandal</string>
+ <!-- Spoken description for Unicode code point U+1F462: "👢" WOMANS BOOTS -->
+ <string name="spoken_emoji_1F462">Womans boots</string>
+ <!-- Spoken description for Unicode code point U+1F463: "👣" FOOTPRINTS -->
+ <string name="spoken_emoji_1F463">Footprints</string>
+ <!-- Spoken description for Unicode code point U+1F464: "👤" BUST IN SILHOUETTE -->
+ <string name="spoken_emoji_1F464">Bust in silhouette</string>
+ <!-- Spoken description for Unicode code point U+1F465: "👥" BUSTS IN SILHOUETTE -->
+ <string name="spoken_emoji_1F465">Busts in silhouette</string>
+ <!-- Spoken description for Unicode code point U+1F466: "👦" BOY -->
+ <string name="spoken_emoji_1F466">Boy</string>
+ <!-- Spoken description for Unicode code point U+1F467: "👧" GIRL -->
+ <string name="spoken_emoji_1F467">Girl</string>
+ <!-- Spoken description for Unicode code point U+1F468: "👨" MAN -->
+ <string name="spoken_emoji_1F468">Man</string>
+ <!-- Spoken description for Unicode code point U+1F469: "👩" WOMAN -->
+ <string name="spoken_emoji_1F469">Woman</string>
+ <!-- Spoken description for Unicode code point U+1F46A: "👪" FAMILY -->
+ <string name="spoken_emoji_1F46A">Family</string>
+ <!-- Spoken description for Unicode code point U+1F46B: "👫" MAN AND WOMAN HOLDING HANDS -->
+ <string name="spoken_emoji_1F46B">Man and woman holding hands</string>
+ <!-- Spoken description for Unicode code point U+1F46C: "👬" TWO MEN HOLDING HANDS -->
+ <string name="spoken_emoji_1F46C">Two men holding hands</string>
+ <!-- Spoken description for Unicode code point U+1F46D: "👭" TWO WOMEN HOLDING HANDS -->
+ <string name="spoken_emoji_1F46D">Two women holding hands</string>
+ <!-- Spoken description for Unicode code point U+1F46E: "👮" POLICE OFFICER -->
+ <string name="spoken_emoji_1F46E">Police officer</string>
+ <!-- Spoken description for Unicode code point U+1F46F: "👯" WOMAN WITH BUNNY EARS -->
+ <string name="spoken_emoji_1F46F">Woman with bunny ears</string>
+ <!-- Spoken description for Unicode code point U+1F470: "👰" BRIDE WITH VEIL -->
+ <string name="spoken_emoji_1F470">Bride with veil</string>
+ <!-- Spoken description for Unicode code point U+1F471: "👱" PERSON WITH BLOND HAIR -->
+ <string name="spoken_emoji_1F471">Person with blond hair</string>
+ <!-- Spoken description for Unicode code point U+1F472: "👲" MAN WITH GUA PI MAO -->
+ <string name="spoken_emoji_1F472">Man with gua pi mao</string>
+ <!-- Spoken description for Unicode code point U+1F473: "👳" MAN WITH TURBAN -->
+ <string name="spoken_emoji_1F473">Man with turban</string>
+ <!-- Spoken description for Unicode code point U+1F474: "👴" OLDER MAN -->
+ <string name="spoken_emoji_1F474">Older man</string>
+ <!-- Spoken description for Unicode code point U+1F475: "👵" OLDER WOMAN -->
+ <string name="spoken_emoji_1F475">Older woman</string>
+ <!-- Spoken description for Unicode code point U+1F476: "👶" BABY -->
+ <string name="spoken_emoji_1F476">Baby</string>
+ <!-- Spoken description for Unicode code point U+1F477: "👷" CONSTRUCTION WORKER -->
+ <string name="spoken_emoji_1F477">Construction worker</string>
+ <!-- Spoken description for Unicode code point U+1F478: "👸" PRINCESS -->
+ <string name="spoken_emoji_1F478">Princess</string>
+ <!-- Spoken description for Unicode code point U+1F479: "👹" JAPANESE OGRE -->
+ <string name="spoken_emoji_1F479">Japanese ogre</string>
+ <!-- Spoken description for Unicode code point U+1F47A: "👺" JAPANESE GOBLIN -->
+ <string name="spoken_emoji_1F47A">Japanese goblin</string>
+ <!-- Spoken description for Unicode code point U+1F47B: "👻" GHOST -->
+ <string name="spoken_emoji_1F47B">Ghost</string>
+ <!-- Spoken description for Unicode code point U+1F47C: "👼" BABY ANGEL -->
+ <string name="spoken_emoji_1F47C">Baby angel</string>
+ <!-- Spoken description for Unicode code point U+1F47D: "👽" EXTRATERRESTRIAL ALIEN -->
+ <string name="spoken_emoji_1F47D">Extraterrestrial alien</string>
+ <!-- Spoken description for Unicode code point U+1F47E: "👾" ALIEN MONSTER -->
+ <string name="spoken_emoji_1F47E">Alien monster</string>
+ <!-- Spoken description for Unicode code point U+1F47F: "👿" IMP -->
+ <string name="spoken_emoji_1F47F">Imp</string>
+ <!-- Spoken description for Unicode code point U+1F480: "💀" SKULL -->
+ <string name="spoken_emoji_1F480">Skull</string>
+ <!-- Spoken description for Unicode code point U+1F481: "💁" INFORMATION DESK PERSON -->
+ <string name="spoken_emoji_1F481">Information desk person</string>
+ <!-- Spoken description for Unicode code point U+1F482: "💂" GUARDSMAN -->
+ <string name="spoken_emoji_1F482">Guardsman</string>
+ <!-- Spoken description for Unicode code point U+1F483: "💃" DANCER -->
+ <string name="spoken_emoji_1F483">Dancer</string>
+ <!-- Spoken description for Unicode code point U+1F484: "💄" LIPSTICK -->
+ <string name="spoken_emoji_1F484">Lipstick</string>
+ <!-- Spoken description for Unicode code point U+1F485: "💅" NAIL POLISH -->
+ <string name="spoken_emoji_1F485">Nail polish</string>
+ <!-- Spoken description for Unicode code point U+1F486: "💆" FACE MASSAGE -->
+ <string name="spoken_emoji_1F486">Face massage</string>
+ <!-- Spoken description for Unicode code point U+1F487: "💇" HAIRCUT -->
+ <string name="spoken_emoji_1F487">Haircut</string>
+ <!-- Spoken description for Unicode code point U+1F488: "💈" BARBER POLE -->
+ <string name="spoken_emoji_1F488">Barber pole</string>
+ <!-- Spoken description for Unicode code point U+1F489: "💉" SYRINGE -->
+ <string name="spoken_emoji_1F489">Syringe</string>
+ <!-- Spoken description for Unicode code point U+1F48A: "💊" PILL -->
+ <string name="spoken_emoji_1F48A">Pill</string>
+ <!-- Spoken description for Unicode code point U+1F48B: "💋" KISS MARK -->
+ <string name="spoken_emoji_1F48B">Kiss mark</string>
+ <!-- Spoken description for Unicode code point U+1F48C: "💌" LOVE LETTER -->
+ <string name="spoken_emoji_1F48C">Love letter</string>
+ <!-- Spoken description for Unicode code point U+1F48D: "💍" RING -->
+ <string name="spoken_emoji_1F48D">Ring</string>
+ <!-- Spoken description for Unicode code point U+1F48E: "💎" GEM STONE -->
+ <string name="spoken_emoji_1F48E">Gem stone</string>
+ <!-- Spoken description for Unicode code point U+1F48F: "💏" KISS -->
+ <string name="spoken_emoji_1F48F">Kiss</string>
+ <!-- Spoken description for Unicode code point U+1F490: "💐" BOUQUET -->
+ <string name="spoken_emoji_1F490">Bouquet</string>
+ <!-- Spoken description for Unicode code point U+1F491: "💑" COUPLE WITH HEART -->
+ <string name="spoken_emoji_1F491">Couple with heart</string>
+ <!-- Spoken description for Unicode code point U+1F492: "💒" WEDDING -->
+ <string name="spoken_emoji_1F492">Wedding</string>
+ <!-- Spoken description for Unicode code point U+1F493: "💓" BEATING HEART -->
+ <string name="spoken_emoji_1F493">Beating heart</string>
+ <!-- Spoken description for Unicode code point U+1F494: "💔" BROKEN HEART -->
+ <string name="spoken_emoji_1F494">Broken heart</string>
+ <!-- Spoken description for Unicode code point U+1F495: "💕" TWO HEARTS -->
+ <string name="spoken_emoji_1F495">Two hearts</string>
+ <!-- Spoken description for Unicode code point U+1F496: "💖" SPARKLING HEART -->
+ <string name="spoken_emoji_1F496">Sparkling heart</string>
+ <!-- Spoken description for Unicode code point U+1F497: "💗" GROWING HEART -->
+ <string name="spoken_emoji_1F497">Growing heart</string>
+ <!-- Spoken description for Unicode code point U+1F498: "💘" HEART WITH ARROW -->
+ <string name="spoken_emoji_1F498">Heart with arrow</string>
+ <!-- Spoken description for Unicode code point U+1F499: "💙" BLUE HEART -->
+ <string name="spoken_emoji_1F499">Blue heart</string>
+ <!-- Spoken description for Unicode code point U+1F49A: "💚" GREEN HEART -->
+ <string name="spoken_emoji_1F49A">Green heart</string>
+ <!-- Spoken description for Unicode code point U+1F49B: "💛" YELLOW HEART -->
+ <string name="spoken_emoji_1F49B">Yellow heart</string>
+ <!-- Spoken description for Unicode code point U+1F49C: "💜" PURPLE HEART -->
+ <string name="spoken_emoji_1F49C">Purple heart</string>
+ <!-- Spoken description for Unicode code point U+1F49D: "💝" HEART WITH RIBBON -->
+ <string name="spoken_emoji_1F49D">Heart with ribbon</string>
+ <!-- Spoken description for Unicode code point U+1F49E: "💞" REVOLVING HEARTS -->
+ <string name="spoken_emoji_1F49E">Revolving hearts</string>
+ <!-- Spoken description for Unicode code point U+1F49F: "💟" HEART DECORATION -->
+ <string name="spoken_emoji_1F49F">Heart decoration</string>
+ <!-- Spoken description for Unicode code point U+1F4A0: "💠" DIAMOND SHAPE WITH A DOT INSIDE -->
+ <string name="spoken_emoji_1F4A0">Diamond shape with a dot inside</string>
+ <!-- Spoken description for Unicode code point U+1F4A1: "💡" ELECTRIC LIGHT BULB -->
+ <string name="spoken_emoji_1F4A1">Electric light bulb</string>
+ <!-- Spoken description for Unicode code point U+1F4A2: "💢" ANGER SYMBOL -->
+ <string name="spoken_emoji_1F4A2">Anger symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4A3: "💣" BOMB -->
+ <string name="spoken_emoji_1F4A3">Bomb</string>
+ <!-- Spoken description for Unicode code point U+1F4A4: "💤" SLEEPING SYMBOL -->
+ <string name="spoken_emoji_1F4A4">Sleeping symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4A5: "💥" COLLISION SYMBOL -->
+ <string name="spoken_emoji_1F4A5">Collision symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4A6: "💦" SPLASHING SWEAT SYMBOL -->
+ <string name="spoken_emoji_1F4A6">Splashing sweat symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4A7: "💧" DROPLET -->
+ <string name="spoken_emoji_1F4A7">Droplet</string>
+ <!-- Spoken description for Unicode code point U+1F4A8: "💨" DASH SYMBOL -->
+ <string name="spoken_emoji_1F4A8">Dash symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4A9: "💩" PILE OF POO -->
+ <string name="spoken_emoji_1F4A9">Pile of poo</string>
+ <!-- Spoken description for Unicode code point U+1F4AA: "💪" FLEXED BICEPS -->
+ <string name="spoken_emoji_1F4AA">Flexed biceps</string>
+ <!-- Spoken description for Unicode code point U+1F4AB: "💫" DIZZY SYMBOL -->
+ <string name="spoken_emoji_1F4AB">Dizzy symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4AC: "💬" SPEECH BALLOON -->
+ <string name="spoken_emoji_1F4AC">Speech balloon</string>
+ <!-- Spoken description for Unicode code point U+1F4AD: "💭" THOUGHT BALLOON -->
+ <string name="spoken_emoji_1F4AD">Thought balloon</string>
+ <!-- Spoken description for Unicode code point U+1F4AE: "💮" WHITE FLOWER -->
+ <string name="spoken_emoji_1F4AE">White flower</string>
+ <!-- Spoken description for Unicode code point U+1F4AF: "💯" HUNDRED POINTS SYMBOL -->
+ <string name="spoken_emoji_1F4AF">Hundred points symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4B0: "💰" MONEY BAG -->
+ <string name="spoken_emoji_1F4B0">Money bag</string>
+ <!-- Spoken description for Unicode code point U+1F4B1: "💱" CURRENCY EXCHANGE -->
+ <string name="spoken_emoji_1F4B1">Currency exchange</string>
+ <!-- Spoken description for Unicode code point U+1F4B2: "💲" HEAVY DOLLAR SIGN -->
+ <string name="spoken_emoji_1F4B2">Heavy dollar sign</string>
+ <!-- Spoken description for Unicode code point U+1F4B3: "💳" CREDIT CARD -->
+ <string name="spoken_emoji_1F4B3">Credit card</string>
+ <!-- Spoken description for Unicode code point U+1F4B4: "💴" BANKNOTE WITH YEN SIGN -->
+ <string name="spoken_emoji_1F4B4">Banknote with yen sign</string>
+ <!-- Spoken description for Unicode code point U+1F4B5: "💵" BANKNOTE WITH DOLLAR SIGN -->
+ <string name="spoken_emoji_1F4B5">Banknote with dollar sign</string>
+ <!-- Spoken description for Unicode code point U+1F4B6: "💶" BANKNOTE WITH EURO SIGN -->
+ <string name="spoken_emoji_1F4B6">Banknote with euro sign</string>
+ <!-- Spoken description for Unicode code point U+1F4B7: "💷" BANKNOTE WITH POUND SIGN -->
+ <string name="spoken_emoji_1F4B7">Banknote with pound sign</string>
+ <!-- Spoken description for Unicode code point U+1F4B8: "💸" MONEY WITH WINGS -->
+ <string name="spoken_emoji_1F4B8">Money with wings</string>
+ <!-- Spoken description for Unicode code point U+1F4B9: "💹" CHART WITH UPWARDS TREND AND YEN SIGN -->
+ <string name="spoken_emoji_1F4B9">Chart with upwards trend and yen sign</string>
+ <!-- Spoken description for Unicode code point U+1F4BA: "💺" SEAT -->
+ <string name="spoken_emoji_1F4BA">Seat</string>
+ <!-- Spoken description for Unicode code point U+1F4BB: "💻" PERSONAL COMPUTER -->
+ <string name="spoken_emoji_1F4BB">Personal computer</string>
+ <!-- Spoken description for Unicode code point U+1F4BC: "💼" BRIEFCASE -->
+ <string name="spoken_emoji_1F4BC">Briefcase</string>
+ <!-- Spoken description for Unicode code point U+1F4BD: "💽" MINIDISC -->
+ <string name="spoken_emoji_1F4BD">Minidisc</string>
+ <!-- Spoken description for Unicode code point U+1F4BE: "💾" FLOPPY DISK -->
+ <string name="spoken_emoji_1F4BE">Floppy disk</string>
+ <!-- Spoken description for Unicode code point U+1F4BF: "💿" OPTICAL DISC -->
+ <string name="spoken_emoji_1F4BF">Optical disc</string>
+ <!-- Spoken description for Unicode code point U+1F4C0: "📀" DVD -->
+ <string name="spoken_emoji_1F4C0">Dvd</string>
+ <!-- Spoken description for Unicode code point U+1F4C1: "📁" FILE FOLDER -->
+ <string name="spoken_emoji_1F4C1">File folder</string>
+ <!-- Spoken description for Unicode code point U+1F4C2: "📂" OPEN FILE FOLDER -->
+ <string name="spoken_emoji_1F4C2">Open file folder</string>
+ <!-- Spoken description for Unicode code point U+1F4C3: "📃" PAGE WITH CURL -->
+ <string name="spoken_emoji_1F4C3">Page with curl</string>
+ <!-- Spoken description for Unicode code point U+1F4C4: "📄" PAGE FACING UP -->
+ <string name="spoken_emoji_1F4C4">Page facing up</string>
+ <!-- Spoken description for Unicode code point U+1F4C5: "📅" CALENDAR -->
+ <string name="spoken_emoji_1F4C5">Calendar</string>
+ <!-- Spoken description for Unicode code point U+1F4C6: "📆" TEAR-OFF CALENDAR -->
+ <string name="spoken_emoji_1F4C6">Tear-off calendar</string>
+ <!-- Spoken description for Unicode code point U+1F4C7: "📇" CARD INDEX -->
+ <string name="spoken_emoji_1F4C7">Card index</string>
+ <!-- Spoken description for Unicode code point U+1F4C8: "📈" CHART WITH UPWARDS TREND -->
+ <string name="spoken_emoji_1F4C8">Chart with upwards trend</string>
+ <!-- Spoken description for Unicode code point U+1F4C9: "📉" CHART WITH DOWNWARDS TREND -->
+ <string name="spoken_emoji_1F4C9">Chart with downwards trend</string>
+ <!-- Spoken description for Unicode code point U+1F4CA: "📊" BAR CHART -->
+ <string name="spoken_emoji_1F4CA">Bar chart</string>
+ <!-- Spoken description for Unicode code point U+1F4CB: "📋" CLIPBOARD -->
+ <string name="spoken_emoji_1F4CB">Clipboard</string>
+ <!-- Spoken description for Unicode code point U+1F4CC: "📌" PUSHPIN -->
+ <string name="spoken_emoji_1F4CC">Pushpin</string>
+ <!-- Spoken description for Unicode code point U+1F4CD: "📍" ROUND PUSHPIN -->
+ <string name="spoken_emoji_1F4CD">Round pushpin</string>
+ <!-- Spoken description for Unicode code point U+1F4CE: "📎" PAPERCLIP -->
+ <string name="spoken_emoji_1F4CE">Paperclip</string>
+ <!-- Spoken description for Unicode code point U+1F4CF: "📏" STRAIGHT RULER -->
+ <string name="spoken_emoji_1F4CF">Straight ruler</string>
+ <!-- Spoken description for Unicode code point U+1F4D0: "📐" TRIANGULAR RULER -->
+ <string name="spoken_emoji_1F4D0">Triangular ruler</string>
+ <!-- Spoken description for Unicode code point U+1F4D1: "📑" BOOKMARK TABS -->
+ <string name="spoken_emoji_1F4D1">Bookmark tabs</string>
+ <!-- Spoken description for Unicode code point U+1F4D2: "📒" LEDGER -->
+ <string name="spoken_emoji_1F4D2">Ledger</string>
+ <!-- Spoken description for Unicode code point U+1F4D3: "📓" NOTEBOOK -->
+ <string name="spoken_emoji_1F4D3">Notebook</string>
+ <!-- Spoken description for Unicode code point U+1F4D4: "📔" NOTEBOOK WITH DECORATIVE COVER -->
+ <string name="spoken_emoji_1F4D4">Notebook with decorative cover</string>
+ <!-- Spoken description for Unicode code point U+1F4D5: "📕" CLOSED BOOK -->
+ <string name="spoken_emoji_1F4D5">Closed book</string>
+ <!-- Spoken description for Unicode code point U+1F4D6: "📖" OPEN BOOK -->
+ <string name="spoken_emoji_1F4D6">Open book</string>
+ <!-- Spoken description for Unicode code point U+1F4D7: "📗" GREEN BOOK -->
+ <string name="spoken_emoji_1F4D7">Green book</string>
+ <!-- Spoken description for Unicode code point U+1F4D8: "📘" BLUE BOOK -->
+ <string name="spoken_emoji_1F4D8">Blue book</string>
+ <!-- Spoken description for Unicode code point U+1F4D9: "📙" ORANGE BOOK -->
+ <string name="spoken_emoji_1F4D9">Orange book</string>
+ <!-- Spoken description for Unicode code point U+1F4DA: "📚" BOOKS -->
+ <string name="spoken_emoji_1F4DA">Books</string>
+ <!-- Spoken description for Unicode code point U+1F4DB: "📛" NAME BADGE -->
+ <string name="spoken_emoji_1F4DB">Name badge</string>
+ <!-- Spoken description for Unicode code point U+1F4DC: "📜" SCROLL -->
+ <string name="spoken_emoji_1F4DC">Scroll</string>
+ <!-- Spoken description for Unicode code point U+1F4DD: "📝" MEMO -->
+ <string name="spoken_emoji_1F4DD">Memo</string>
+ <!-- Spoken description for Unicode code point U+1F4DE: "📞" TELEPHONE RECEIVER -->
+ <string name="spoken_emoji_1F4DE">Telephone receiver</string>
+ <!-- Spoken description for Unicode code point U+1F4DF: "📟" PAGER -->
+ <string name="spoken_emoji_1F4DF">Pager</string>
+ <!-- Spoken description for Unicode code point U+1F4E0: "📠" FAX MACHINE -->
+ <string name="spoken_emoji_1F4E0">Fax machine</string>
+ <!-- Spoken description for Unicode code point U+1F4E1: "📡" SATELLITE ANTENNA -->
+ <string name="spoken_emoji_1F4E1">Satellite antenna</string>
+ <!-- Spoken description for Unicode code point U+1F4E2: "📢" PUBLIC ADDRESS LOUDSPEAKER -->
+ <string name="spoken_emoji_1F4E2">Public address loudspeaker</string>
+ <!-- Spoken description for Unicode code point U+1F4E3: "📣" CHEERING MEGAPHONE -->
+ <string name="spoken_emoji_1F4E3">Cheering megaphone</string>
+ <!-- Spoken description for Unicode code point U+1F4E4: "📤" OUTBOX TRAY -->
+ <string name="spoken_emoji_1F4E4">Outbox tray</string>
+ <!-- Spoken description for Unicode code point U+1F4E5: "📥" INBOX TRAY -->
+ <string name="spoken_emoji_1F4E5">Inbox tray</string>
+ <!-- Spoken description for Unicode code point U+1F4E6: "📦" PACKAGE -->
+ <string name="spoken_emoji_1F4E6">Package</string>
+ <!-- Spoken description for Unicode code point U+1F4E7: "📧" E-MAIL SYMBOL -->
+ <string name="spoken_emoji_1F4E7">E-mail symbol</string>
+ <!-- Spoken description for Unicode code point U+1F4E8: "📨" INCOMING ENVELOPE -->
+ <string name="spoken_emoji_1F4E8">Incoming envelope</string>
+ <!-- Spoken description for Unicode code point U+1F4E9: "📩" ENVELOPE WITH DOWNWARDS ARROW ABOVE -->
+ <string name="spoken_emoji_1F4E9">Envelope with downwards arrow above</string>
+ <!-- Spoken description for Unicode code point U+1F4EA: "📪" CLOSED MAILBOX WITH LOWERED FLAG -->
+ <string name="spoken_emoji_1F4EA">Closed mailbox with lowered flag</string>
+ <!-- Spoken description for Unicode code point U+1F4EB: "📫" CLOSED MAILBOX WITH RAISED FLAG -->
+ <string name="spoken_emoji_1F4EB">Closed mailbox with raised flag</string>
+ <!-- Spoken description for Unicode code point U+1F4EC: "📬" OPEN MAILBOX WITH RAISED FLAG -->
+ <string name="spoken_emoji_1F4EC">Open mailbox with raised flag</string>
+ <!-- Spoken description for Unicode code point U+1F4ED: "📭" OPEN MAILBOX WITH LOWERED FLAG -->
+ <string name="spoken_emoji_1F4ED">Open mailbox with lowered flag</string>
+ <!-- Spoken description for Unicode code point U+1F4EE: "📮" POSTBOX -->
+ <string name="spoken_emoji_1F4EE">Postbox</string>
+ <!-- Spoken description for Unicode code point U+1F4EF: "📯" POSTAL HORN -->
+ <string name="spoken_emoji_1F4EF">Postal horn</string>
+ <!-- Spoken description for Unicode code point U+1F4F0: "📰" NEWSPAPER -->
+ <string name="spoken_emoji_1F4F0">Newspaper</string>
+ <!-- Spoken description for Unicode code point U+1F4F1: "📱" MOBILE PHONE -->
+ <string name="spoken_emoji_1F4F1">Mobile phone</string>
+ <!-- Spoken description for Unicode code point U+1F4F2: "📲" MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT -->
+ <string name="spoken_emoji_1F4F2">Mobile phone with rightwards arrow at left</string>
+ <!-- Spoken description for Unicode code point U+1F4F3: "📳" VIBRATION MODE -->
+ <string name="spoken_emoji_1F4F3">Vibration mode</string>
+ <!-- Spoken description for Unicode code point U+1F4F4: "📴" MOBILE PHONE OFF -->
+ <string name="spoken_emoji_1F4F4">Mobile phone off</string>
+ <!-- Spoken description for Unicode code point U+1F4F5: "📵" NO MOBILE PHONES -->
+ <string name="spoken_emoji_1F4F5">No mobile phones</string>
+ <!-- Spoken description for Unicode code point U+1F4F6: "📶" ANTENNA WITH BARS -->
+ <string name="spoken_emoji_1F4F6">Antenna with bars</string>
+ <!-- Spoken description for Unicode code point U+1F4F7: "📷" CAMERA -->
+ <string name="spoken_emoji_1F4F7">Camera</string>
+ <!-- Spoken description for Unicode code point U+1F4F9: "📹" VIDEO CAMERA -->
+ <string name="spoken_emoji_1F4F9">Video camera</string>
+ <!-- Spoken description for Unicode code point U+1F4FA: "📺" TELEVISION -->
+ <string name="spoken_emoji_1F4FA">Television</string>
+ <!-- Spoken description for Unicode code point U+1F4FB: "📻" RADIO -->
+ <string name="spoken_emoji_1F4FB">Radio</string>
+ <!-- Spoken description for Unicode code point U+1F4FC: "📼" VIDEOCASSETTE -->
+ <string name="spoken_emoji_1F4FC">Videocassette</string>
+ <!-- Spoken description for Unicode code point U+1F500: "🔀" TWISTED RIGHTWARDS ARROWS -->
+ <string name="spoken_emoji_1F500">Twisted rightwards arrows</string>
+ <!-- Spoken description for Unicode code point U+1F501: "🔁" CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS -->
+ <string name="spoken_emoji_1F501">Clockwise rightwards and leftwards open circle arrows</string>
+ <!-- Spoken description for Unicode code point U+1F502: "🔂" CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY -->
+ <string name="spoken_emoji_1F502">Clockwise rightwards and leftwards open circle arrows with circled one overlay</string>
+ <!-- Spoken description for Unicode code point U+1F503: "🔃" CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS -->
+ <string name="spoken_emoji_1F503">Clockwise downwards and upwards open circle arrows</string>
+ <!-- Spoken description for Unicode code point U+1F504: "🔄" ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS -->
+ <string name="spoken_emoji_1F504">Anticlockwise downwards and upwards open circle arrows</string>
+ <!-- Spoken description for Unicode code point U+1F505: "🔅" LOW BRIGHTNESS SYMBOL -->
+ <string name="spoken_emoji_1F505">Low brightness symbol</string>
+ <!-- Spoken description for Unicode code point U+1F506: "🔆" HIGH BRIGHTNESS SYMBOL -->
+ <string name="spoken_emoji_1F506">High brightness symbol</string>
+ <!-- Spoken description for Unicode code point U+1F507: "🔇" SPEAKER WITH CANCELLATION STROKE -->
+ <string name="spoken_emoji_1F507">Speaker with cancellation stroke</string>
+ <!-- Spoken description for Unicode code point U+1F508: "🔈" SPEAKER -->
+ <string name="spoken_emoji_1F508">Speaker</string>
+ <!-- Spoken description for Unicode code point U+1F509: "🔉" SPEAKER WITH ONE SOUND WAVE -->
+ <string name="spoken_emoji_1F509">Speaker with one sound wave</string>
+ <!-- Spoken description for Unicode code point U+1F50A: "🔊" SPEAKER WITH THREE SOUND WAVES -->
+ <string name="spoken_emoji_1F50A">Speaker with three sound waves</string>
+ <!-- Spoken description for Unicode code point U+1F50B: "🔋" BATTERY -->
+ <string name="spoken_emoji_1F50B">Battery</string>
+ <!-- Spoken description for Unicode code point U+1F50C: "🔌" ELECTRIC PLUG -->
+ <string name="spoken_emoji_1F50C">Electric plug</string>
+ <!-- Spoken description for Unicode code point U+1F50D: "🔍" LEFT-POINTING MAGNIFYING GLASS -->
+ <string name="spoken_emoji_1F50D">Left-pointing magnifying glass</string>
+ <!-- Spoken description for Unicode code point U+1F50E: "🔎" RIGHT-POINTING MAGNIFYING GLASS -->
+ <string name="spoken_emoji_1F50E">Right-pointing magnifying glass</string>
+ <!-- Spoken description for Unicode code point U+1F50F: "🔏" LOCK WITH INK PEN -->
+ <string name="spoken_emoji_1F50F">Lock with ink pen</string>
+ <!-- Spoken description for Unicode code point U+1F510: "🔐" CLOSED LOCK WITH KEY -->
+ <string name="spoken_emoji_1F510">Closed lock with key</string>
+ <!-- Spoken description for Unicode code point U+1F511: "🔑" KEY -->
+ <string name="spoken_emoji_1F511">Key</string>
+ <!-- Spoken description for Unicode code point U+1F512: "🔒" LOCK -->
+ <string name="spoken_emoji_1F512">Lock</string>
+ <!-- Spoken description for Unicode code point U+1F513: "🔓" OPEN LOCK -->
+ <string name="spoken_emoji_1F513">Open lock</string>
+ <!-- Spoken description for Unicode code point U+1F514: "🔔" BELL -->
+ <string name="spoken_emoji_1F514">Bell</string>
+ <!-- Spoken description for Unicode code point U+1F515: "🔕" BELL WITH CANCELLATION STROKE -->
+ <string name="spoken_emoji_1F515">Bell with cancellation stroke</string>
+ <!-- Spoken description for Unicode code point U+1F516: "🔖" BOOKMARK -->
+ <string name="spoken_emoji_1F516">Bookmark</string>
+ <!-- Spoken description for Unicode code point U+1F517: "🔗" LINK SYMBOL -->
+ <string name="spoken_emoji_1F517">Link symbol</string>
+ <!-- Spoken description for Unicode code point U+1F518: "🔘" RADIO BUTTON -->
+ <string name="spoken_emoji_1F518">Radio button</string>
+ <!-- Spoken description for Unicode code point U+1F519: "🔙" BACK WITH LEFTWARDS ARROW ABOVE -->
+ <string name="spoken_emoji_1F519">Back with leftwards arrow above</string>
+ <!-- Spoken description for Unicode code point U+1F51A: "🔚" END WITH LEFTWARDS ARROW ABOVE -->
+ <string name="spoken_emoji_1F51A">End with leftwards arrow above</string>
+ <!-- Spoken description for Unicode code point U+1F51B: "🔛" ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE -->
+ <string name="spoken_emoji_1F51B">On with exclamation mark with left right arrow above</string>
+ <!-- Spoken description for Unicode code point U+1F51C: "🔜" SOON WITH RIGHTWARDS ARROW ABOVE -->
+ <string name="spoken_emoji_1F51C">Soon with rightwards arrow above</string>
+ <!-- Spoken description for Unicode code point U+1F51D: "🔝" TOP WITH UPWARDS ARROW ABOVE -->
+ <string name="spoken_emoji_1F51D">Top with upwards arrow above</string>
+ <!-- Spoken description for Unicode code point U+1F51E: "🔞" NO ONE UNDER EIGHTEEN SYMBOL -->
+ <string name="spoken_emoji_1F51E">No one under eighteen symbol</string>
+ <!-- Spoken description for Unicode code point U+1F51F: "🔟" KEYCAP TEN -->
+ <string name="spoken_emoji_1F51F">Keycap ten</string>
+ <!-- Spoken description for Unicode code point U+1F520: "🔠" INPUT SYMBOL FOR LATIN CAPITAL LETTERS -->
+ <string name="spoken_emoji_1F520">Input symbol for latin capital letters</string>
+ <!-- Spoken description for Unicode code point U+1F521: "🔡" INPUT SYMBOL FOR LATIN SMALL LETTERS -->
+ <string name="spoken_emoji_1F521">Input symbol for latin small letters</string>
+ <!-- Spoken description for Unicode code point U+1F522: "🔢" INPUT SYMBOL FOR NUMBERS -->
+ <string name="spoken_emoji_1F522">Input symbol for numbers</string>
+ <!-- Spoken description for Unicode code point U+1F523: "🔣" INPUT SYMBOL FOR SYMBOLS -->
+ <string name="spoken_emoji_1F523">Input symbol for symbols</string>
+ <!-- Spoken description for Unicode code point U+1F524: "🔤" INPUT SYMBOL FOR LATIN LETTERS -->
+ <string name="spoken_emoji_1F524">Input symbol for latin letters</string>
+ <!-- Spoken description for Unicode code point U+1F525: "🔥" FIRE -->
+ <string name="spoken_emoji_1F525">Fire</string>
+ <!-- Spoken description for Unicode code point U+1F526: "🔦" ELECTRIC TORCH -->
+ <string name="spoken_emoji_1F526">Electric torch</string>
+ <!-- Spoken description for Unicode code point U+1F527: "🔧" WRENCH -->
+ <string name="spoken_emoji_1F527">Wrench</string>
+ <!-- Spoken description for Unicode code point U+1F528: "🔨" HAMMER -->
+ <string name="spoken_emoji_1F528">Hammer</string>
+ <!-- Spoken description for Unicode code point U+1F529: "🔩" NUT AND BOLT -->
+ <string name="spoken_emoji_1F529">Nut and bolt</string>
+ <!-- Spoken description for Unicode code point U+1F52A: "🔪" HOCHO -->
+ <string name="spoken_emoji_1F52A">Hocho</string>
+ <!-- Spoken description for Unicode code point U+1F52B: "🔫" PISTOL -->
+ <string name="spoken_emoji_1F52B">Pistol</string>
+ <!-- Spoken description for Unicode code point U+1F52C: "🔬" MICROSCOPE -->
+ <string name="spoken_emoji_1F52C">Microscope</string>
+ <!-- Spoken description for Unicode code point U+1F52D: "🔭" TELESCOPE -->
+ <string name="spoken_emoji_1F52D">Telescope</string>
+ <!-- Spoken description for Unicode code point U+1F52E: "🔮" CRYSTAL BALL -->
+ <string name="spoken_emoji_1F52E">Crystal ball</string>
+ <!-- Spoken description for Unicode code point U+1F52F: "🔯" SIX POINTED STAR WITH MIDDLE DOT -->
+ <string name="spoken_emoji_1F52F">Six pointed star with middle dot</string>
+ <!-- Spoken description for Unicode code point U+1F530: "🔰" JAPANESE SYMBOL FOR BEGINNER -->
+ <string name="spoken_emoji_1F530">Japanese symbol for beginner</string>
+ <!-- Spoken description for Unicode code point U+1F531: "🔱" TRIDENT EMBLEM -->
+ <string name="spoken_emoji_1F531">Trident emblem</string>
+ <!-- Spoken description for Unicode code point U+1F532: "🔲" BLACK SQUARE BUTTON -->
+ <string name="spoken_emoji_1F532">Black square button</string>
+ <!-- Spoken description for Unicode code point U+1F533: "🔳" WHITE SQUARE BUTTON -->
+ <string name="spoken_emoji_1F533">White square button</string>
+ <!-- Spoken description for Unicode code point U+1F534: "🔴" LARGE RED CIRCLE -->
+ <string name="spoken_emoji_1F534">Large red circle</string>
+ <!-- Spoken description for Unicode code point U+1F535: "🔵" LARGE BLUE CIRCLE -->
+ <string name="spoken_emoji_1F535">Large blue circle</string>
+ <!-- Spoken description for Unicode code point U+1F536: "🔶" LARGE ORANGE DIAMOND -->
+ <string name="spoken_emoji_1F536">Large orange diamond</string>
+ <!-- Spoken description for Unicode code point U+1F537: "🔷" LARGE BLUE DIAMOND -->
+ <string name="spoken_emoji_1F537">Large blue diamond</string>
+ <!-- Spoken description for Unicode code point U+1F538: "🔸" SMALL ORANGE DIAMOND -->
+ <string name="spoken_emoji_1F538">Small orange diamond</string>
+ <!-- Spoken description for Unicode code point U+1F539: "🔹" SMALL BLUE DIAMOND -->
+ <string name="spoken_emoji_1F539">Small blue diamond</string>
+ <!-- Spoken description for Unicode code point U+1F53A: "🔺" UP-POINTING RED TRIANGLE -->
+ <string name="spoken_emoji_1F53A">Up-pointing red triangle</string>
+ <!-- Spoken description for Unicode code point U+1F53B: "🔻" DOWN-POINTING RED TRIANGLE -->
+ <string name="spoken_emoji_1F53B">Down-pointing red triangle</string>
+ <!-- Spoken description for Unicode code point U+1F53C: "🔼" UP-POINTING SMALL RED TRIANGLE -->
+ <string name="spoken_emoji_1F53C">Up-pointing small red triangle</string>
+ <!-- Spoken description for Unicode code point U+1F53D: "🔽" DOWN-POINTING SMALL RED TRIANGLE -->
+ <string name="spoken_emoji_1F53D">Down-pointing small red triangle</string>
+ <!-- Spoken description for Unicode code point U+1F550: "🕐" CLOCK FACE ONE OCLOCK -->
+ <string name="spoken_emoji_1F550">Clock face one oclock</string>
+ <!-- Spoken description for Unicode code point U+1F551: "🕑" CLOCK FACE TWO OCLOCK -->
+ <string name="spoken_emoji_1F551">Clock face two oclock</string>
+ <!-- Spoken description for Unicode code point U+1F552: "🕒" CLOCK FACE THREE OCLOCK -->
+ <string name="spoken_emoji_1F552">Clock face three oclock</string>
+ <!-- Spoken description for Unicode code point U+1F553: "🕓" CLOCK FACE FOUR OCLOCK -->
+ <string name="spoken_emoji_1F553">Clock face four oclock</string>
+ <!-- Spoken description for Unicode code point U+1F554: "🕔" CLOCK FACE FIVE OCLOCK -->
+ <string name="spoken_emoji_1F554">Clock face five oclock</string>
+ <!-- Spoken description for Unicode code point U+1F555: "🕕" CLOCK FACE SIX OCLOCK -->
+ <string name="spoken_emoji_1F555">Clock face six oclock</string>
+ <!-- Spoken description for Unicode code point U+1F556: "🕖" CLOCK FACE SEVEN OCLOCK -->
+ <string name="spoken_emoji_1F556">Clock face seven oclock</string>
+ <!-- Spoken description for Unicode code point U+1F557: "🕗" CLOCK FACE EIGHT OCLOCK -->
+ <string name="spoken_emoji_1F557">Clock face eight oclock</string>
+ <!-- Spoken description for Unicode code point U+1F558: "🕘" CLOCK FACE NINE OCLOCK -->
+ <string name="spoken_emoji_1F558">Clock face nine oclock</string>
+ <!-- Spoken description for Unicode code point U+1F559: "🕙" CLOCK FACE TEN OCLOCK -->
+ <string name="spoken_emoji_1F559">Clock face ten oclock</string>
+ <!-- Spoken description for Unicode code point U+1F55A: "🕚" CLOCK FACE ELEVEN OCLOCK -->
+ <string name="spoken_emoji_1F55A">Clock face eleven oclock</string>
+ <!-- Spoken description for Unicode code point U+1F55B: "🕛" CLOCK FACE TWELVE OCLOCK -->
+ <string name="spoken_emoji_1F55B">Clock face twelve oclock</string>
+ <!-- Spoken description for Unicode code point U+1F55C: "🕜" CLOCK FACE ONE-THIRTY -->
+ <string name="spoken_emoji_1F55C">Clock face one-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F55D: "🕝" CLOCK FACE TWO-THIRTY -->
+ <string name="spoken_emoji_1F55D">Clock face two-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F55E: "🕞" CLOCK FACE THREE-THIRTY -->
+ <string name="spoken_emoji_1F55E">Clock face three-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F55F: "🕟" CLOCK FACE FOUR-THIRTY -->
+ <string name="spoken_emoji_1F55F">Clock face four-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F560: "🕠" CLOCK FACE FIVE-THIRTY -->
+ <string name="spoken_emoji_1F560">Clock face five-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F561: "🕡" CLOCK FACE SIX-THIRTY -->
+ <string name="spoken_emoji_1F561">Clock face six-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F562: "🕢" CLOCK FACE SEVEN-THIRTY -->
+ <string name="spoken_emoji_1F562">Clock face seven-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F563: "🕣" CLOCK FACE EIGHT-THIRTY -->
+ <string name="spoken_emoji_1F563">Clock face eight-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F564: "🕤" CLOCK FACE NINE-THIRTY -->
+ <string name="spoken_emoji_1F564">Clock face nine-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F565: "🕥" CLOCK FACE TEN-THIRTY -->
+ <string name="spoken_emoji_1F565">Clock face ten-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F566: "🕦" CLOCK FACE ELEVEN-THIRTY -->
+ <string name="spoken_emoji_1F566">Clock face eleven-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F567: "🕧" CLOCK FACE TWELVE-THIRTY -->
+ <string name="spoken_emoji_1F567">Clock face twelve-thirty</string>
+ <!-- Spoken description for Unicode code point U+1F5FB: "🗻" MOUNT FUJI -->
+ <string name="spoken_emoji_1F5FB">Mount fuji</string>
+ <!-- Spoken description for Unicode code point U+1F5FC: "🗼" TOKYO TOWER -->
+ <string name="spoken_emoji_1F5FC">Tokyo tower</string>
+ <!-- Spoken description for Unicode code point U+1F5FD: "🗽" STATUE OF LIBERTY -->
+ <string name="spoken_emoji_1F5FD">Statue of liberty</string>
+ <!-- Spoken description for Unicode code point U+1F5FE: "🗾" SILHOUETTE OF JAPAN -->
+ <string name="spoken_emoji_1F5FE">Silhouette of japan</string>
+ <!-- Spoken description for Unicode code point U+1F5FF: "🗿" MOYAI -->
+ <string name="spoken_emoji_1F5FF">Moyai</string>
+ <!-- Spoken description for Unicode code point U+1F600: "😀" GRINNING FACE -->
+ <string name="spoken_emoji_1F600">Grinning face</string>
+ <!-- Spoken description for Unicode code point U+1F601: "😁" GRINNING FACE WITH SMILING EYES -->
+ <string name="spoken_emoji_1F601">Grinning face with smiling eyes</string>
+ <!-- Spoken description for Unicode code point U+1F602: "😂" FACE WITH TEARS OF JOY -->
+ <string name="spoken_emoji_1F602">Face with tears of joy</string>
+ <!-- Spoken description for Unicode code point U+1F603: "😃" SMILING FACE WITH OPEN MOUTH -->
+ <string name="spoken_emoji_1F603">Smiling face with open mouth</string>
+ <!-- Spoken description for Unicode code point U+1F604: "😄" SMILING FACE WITH OPEN MOUTH AND SMILING EYES -->
+ <string name="spoken_emoji_1F604">Smiling face with open mouth and smiling eyes</string>
+ <!-- Spoken description for Unicode code point U+1F605: "😅" SMILING FACE WITH OPEN MOUTH AND COLD SWEAT -->
+ <string name="spoken_emoji_1F605">Smiling face with open mouth and cold sweat</string>
+ <!-- Spoken description for Unicode code point U+1F606: "😆" SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES -->
+ <string name="spoken_emoji_1F606">Smiling face with open mouth and tightly-closed eyes</string>
+ <!-- Spoken description for Unicode code point U+1F607: "😇" SMILING FACE WITH HALO -->
+ <string name="spoken_emoji_1F607">Smiling face with halo</string>
+ <!-- Spoken description for Unicode code point U+1F608: "😈" SMILING FACE WITH HORNS -->
+ <string name="spoken_emoji_1F608">Smiling face with horns</string>
+ <!-- Spoken description for Unicode code point U+1F609: "😉" WINKING FACE -->
+ <string name="spoken_emoji_1F609">Winking face</string>
+ <!-- Spoken description for Unicode code point U+1F60A: "😊" SMILING FACE WITH SMILING EYES -->
+ <string name="spoken_emoji_1F60A">Smiling face with smiling eyes</string>
+ <!-- Spoken description for Unicode code point U+1F60B: "😋" FACE SAVOURING DELICIOUS FOOD -->
+ <string name="spoken_emoji_1F60B">Face savouring delicious food</string>
+ <!-- Spoken description for Unicode code point U+1F60C: "😌" RELIEVED FACE -->
+ <string name="spoken_emoji_1F60C">Relieved face</string>
+ <!-- Spoken description for Unicode code point U+1F60D: "😍" SMILING FACE WITH HEART-SHAPED EYES -->
+ <string name="spoken_emoji_1F60D">Smiling face with heart-shaped eyes</string>
+ <!-- Spoken description for Unicode code point U+1F60E: "😎" SMILING FACE WITH SUNGLASSES -->
+ <string name="spoken_emoji_1F60E">Smiling face with sunglasses</string>
+ <!-- Spoken description for Unicode code point U+1F60F: "😏" SMIRKING FACE -->
+ <string name="spoken_emoji_1F60F">Smirking face</string>
+ <!-- Spoken description for Unicode code point U+1F610: "😐" NEUTRAL FACE -->
+ <string name="spoken_emoji_1F610">Neutral face</string>
+ <!-- Spoken description for Unicode code point U+1F611: "😑" EXPRESSIONLESS FACE -->
+ <string name="spoken_emoji_1F611">Expressionless face</string>
+ <!-- Spoken description for Unicode code point U+1F612: "😒" UNAMUSED FACE -->
+ <string name="spoken_emoji_1F612">Unamused face</string>
+ <!-- Spoken description for Unicode code point U+1F613: "😓" FACE WITH COLD SWEAT -->
+ <string name="spoken_emoji_1F613">Face with cold sweat</string>
+ <!-- Spoken description for Unicode code point U+1F614: "😔" PENSIVE FACE -->
+ <string name="spoken_emoji_1F614">Pensive face</string>
+ <!-- Spoken description for Unicode code point U+1F615: "😕" CONFUSED FACE -->
+ <string name="spoken_emoji_1F615">Confused face</string>
+ <!-- Spoken description for Unicode code point U+1F616: "😖" CONFOUNDED FACE -->
+ <string name="spoken_emoji_1F616">Confounded face</string>
+ <!-- Spoken description for Unicode code point U+1F617: "😗" KISSING FACE -->
+ <string name="spoken_emoji_1F617">Kissing face</string>
+ <!-- Spoken description for Unicode code point U+1F618: "😘" FACE THROWING A KISS -->
+ <string name="spoken_emoji_1F618">Face throwing a kiss</string>
+ <!-- Spoken description for Unicode code point U+1F619: "😙" KISSING FACE WITH SMILING EYES -->
+ <string name="spoken_emoji_1F619">Kissing face with smiling eyes</string>
+ <!-- Spoken description for Unicode code point U+1F61A: "😚" KISSING FACE WITH CLOSED EYES -->
+ <string name="spoken_emoji_1F61A">Kissing face with closed eyes</string>
+ <!-- Spoken description for Unicode code point U+1F61B: "😛" FACE WITH STUCK-OUT TONGUE -->
+ <string name="spoken_emoji_1F61B">Face with stuck-out tongue</string>
+ <!-- Spoken description for Unicode code point U+1F61C: "😜" FACE WITH STUCK-OUT TONGUE AND WINKING EYE -->
+ <string name="spoken_emoji_1F61C">Face with stuck-out tongue and winking eye</string>
+ <!-- Spoken description for Unicode code point U+1F61D: "😝" FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES -->
+ <string name="spoken_emoji_1F61D">Face with stuck-out tongue and tightly-closed eyes</string>
+ <!-- Spoken description for Unicode code point U+1F61E: "😞" DISAPPOINTED FACE -->
+ <string name="spoken_emoji_1F61E">Disappointed face</string>
+ <!-- Spoken description for Unicode code point U+1F61F: "😟" WORRIED FACE -->
+ <string name="spoken_emoji_1F61F">Worried face</string>
+ <!-- Spoken description for Unicode code point U+1F620: "😠" ANGRY FACE -->
+ <string name="spoken_emoji_1F620">Angry face</string>
+ <!-- Spoken description for Unicode code point U+1F621: "😡" POUTING FACE -->
+ <string name="spoken_emoji_1F621">Pouting face</string>
+ <!-- Spoken description for Unicode code point U+1F622: "😢" CRYING FACE -->
+ <string name="spoken_emoji_1F622">Crying face</string>
+ <!-- Spoken description for Unicode code point U+1F623: "😣" PERSEVERING FACE -->
+ <string name="spoken_emoji_1F623">Persevering face</string>
+ <!-- Spoken description for Unicode code point U+1F624: "😤" FACE WITH LOOK OF TRIUMPH -->
+ <string name="spoken_emoji_1F624">Face with look of triumph</string>
+ <!-- Spoken description for Unicode code point U+1F625: "😥" DISAPPOINTED BUT RELIEVED FACE -->
+ <string name="spoken_emoji_1F625">Disappointed but relieved face</string>
+ <!-- Spoken description for Unicode code point U+1F626: "😦" FROWNING FACE WITH OPEN MOUTH -->
+ <string name="spoken_emoji_1F626">Frowning face with open mouth</string>
+ <!-- Spoken description for Unicode code point U+1F627: "😧" ANGUISHED FACE -->
+ <string name="spoken_emoji_1F627">Anguished face</string>
+ <!-- Spoken description for Unicode code point U+1F628: "😨" FEARFUL FACE -->
+ <string name="spoken_emoji_1F628">Fearful face</string>
+ <!-- Spoken description for Unicode code point U+1F629: "😩" WEARY FACE -->
+ <string name="spoken_emoji_1F629">Weary face</string>
+ <!-- Spoken description for Unicode code point U+1F62A: "😪" SLEEPY FACE -->
+ <string name="spoken_emoji_1F62A">Sleepy face</string>
+ <!-- Spoken description for Unicode code point U+1F62B: "😫" TIRED FACE -->
+ <string name="spoken_emoji_1F62B">Tired face</string>
+ <!-- Spoken description for Unicode code point U+1F62C: "😬" GRIMACING FACE -->
+ <string name="spoken_emoji_1F62C">Grimacing face</string>
+ <!-- Spoken description for Unicode code point U+1F62D: "😭" LOUDLY CRYING FACE -->
+ <string name="spoken_emoji_1F62D">Loudly crying face</string>
+ <!-- Spoken description for Unicode code point U+1F62E: "😮" FACE WITH OPEN MOUTH -->
+ <string name="spoken_emoji_1F62E">Face with open mouth</string>
+ <!-- Spoken description for Unicode code point U+1F62F: "😯" HUSHED FACE -->
+ <string name="spoken_emoji_1F62F">Hushed face</string>
+ <!-- Spoken description for Unicode code point U+1F630: "😰" FACE WITH OPEN MOUTH AND COLD SWEAT -->
+ <string name="spoken_emoji_1F630">Face with open mouth and cold sweat</string>
+ <!-- Spoken description for Unicode code point U+1F631: "😱" FACE SCREAMING IN FEAR -->
+ <string name="spoken_emoji_1F631">Face screaming in fear</string>
+ <!-- Spoken description for Unicode code point U+1F632: "😲" ASTONISHED FACE -->
+ <string name="spoken_emoji_1F632">Astonished face</string>
+ <!-- Spoken description for Unicode code point U+1F633: "😳" FLUSHED FACE -->
+ <string name="spoken_emoji_1F633">Flushed face</string>
+ <!-- Spoken description for Unicode code point U+1F634: "😴" SLEEPING FACE -->
+ <string name="spoken_emoji_1F634">Sleeping face</string>
+ <!-- Spoken description for Unicode code point U+1F635: "😵" DIZZY FACE -->
+ <string name="spoken_emoji_1F635">Dizzy face</string>
+ <!-- Spoken description for Unicode code point U+1F636: "😶" FACE WITHOUT MOUTH -->
+ <string name="spoken_emoji_1F636">Face without mouth</string>
+ <!-- Spoken description for Unicode code point U+1F637: "😷" FACE WITH MEDICAL MASK -->
+ <string name="spoken_emoji_1F637">Face with medical mask</string>
+ <!-- Spoken description for Unicode code point U+1F638: "😸" GRINNING CAT FACE WITH SMILING EYES -->
+ <string name="spoken_emoji_1F638">Grinning cat face with smiling eyes</string>
+ <!-- Spoken description for Unicode code point U+1F639: "😹" CAT FACE WITH TEARS OF JOY -->
+ <string name="spoken_emoji_1F639">Cat face with tears of joy</string>
+ <!-- Spoken description for Unicode code point U+1F63A: "😺" SMILING CAT FACE WITH OPEN MOUTH -->
+ <string name="spoken_emoji_1F63A">Smiling cat face with open mouth</string>
+ <!-- Spoken description for Unicode code point U+1F63B: "😻" SMILING CAT FACE WITH HEART-SHAPED EYES -->
+ <string name="spoken_emoji_1F63B">Smiling cat face with heart-shaped eyes</string>
+ <!-- Spoken description for Unicode code point U+1F63C: "😼" CAT FACE WITH WRY SMILE -->
+ <string name="spoken_emoji_1F63C">Cat face with wry smile</string>
+ <!-- Spoken description for Unicode code point U+1F63D: "😽" KISSING CAT FACE WITH CLOSED EYES -->
+ <string name="spoken_emoji_1F63D">Kissing cat face with closed eyes</string>
+ <!-- Spoken description for Unicode code point U+1F63E: "😾" POUTING CAT FACE -->
+ <string name="spoken_emoji_1F63E">Pouting cat face</string>
+ <!-- Spoken description for Unicode code point U+1F63F: "😿" CRYING CAT FACE -->
+ <string name="spoken_emoji_1F63F">Crying cat face</string>
+ <!-- Spoken description for Unicode code point U+1F640: "🙀" WEARY CAT FACE -->
+ <string name="spoken_emoji_1F640">Weary cat face</string>
+ <!-- Spoken description for Unicode code point U+1F645: "🙅" FACE WITH NO GOOD GESTURE -->
+ <string name="spoken_emoji_1F645">Face with no good gesture</string>
+ <!-- Spoken description for Unicode code point U+1F646: "🙆" FACE WITH OK GESTURE -->
+ <string name="spoken_emoji_1F646">Face with ok gesture</string>
+ <!-- Spoken description for Unicode code point U+1F647: "🙇" PERSON BOWING DEEPLY -->
+ <string name="spoken_emoji_1F647">Person bowing deeply</string>
+ <!-- Spoken description for Unicode code point U+1F648: "🙈" SEE-NO-EVIL MONKEY -->
+ <string name="spoken_emoji_1F648">See-no-evil monkey</string>
+ <!-- Spoken description for Unicode code point U+1F649: "🙉" HEAR-NO-EVIL MONKEY -->
+ <string name="spoken_emoji_1F649">Hear-no-evil monkey</string>
+ <!-- Spoken description for Unicode code point U+1F64A: "🙊" SPEAK-NO-EVIL MONKEY -->
+ <string name="spoken_emoji_1F64A">Speak-no-evil monkey</string>
+ <!-- Spoken description for Unicode code point U+1F64B: "🙋" HAPPY PERSON RAISING ONE HAND -->
+ <string name="spoken_emoji_1F64B">Happy person raising one hand</string>
+ <!-- Spoken description for Unicode code point U+1F64C: "🙌" PERSON RAISING BOTH HANDS IN CELEBRATION -->
+ <string name="spoken_emoji_1F64C">Person raising both hands in celebration</string>
+ <!-- Spoken description for Unicode code point U+1F64D: "🙍" PERSON FROWNING -->
+ <string name="spoken_emoji_1F64D">Person frowning</string>
+ <!-- Spoken description for Unicode code point U+1F64E: "🙎" PERSON WITH POUTING FACE -->
+ <string name="spoken_emoji_1F64E">Person with pouting face</string>
+ <!-- Spoken description for Unicode code point U+1F64F: "🙏" PERSON WITH FOLDED HANDS -->
+ <string name="spoken_emoji_1F64F">Person with folded hands</string>
+ <!-- Spoken description for Unicode code point U+1F680: "🚀" ROCKET -->
+ <string name="spoken_emoji_1F680">Rocket</string>
+ <!-- Spoken description for Unicode code point U+1F681: "🚁" HELICOPTER -->
+ <string name="spoken_emoji_1F681">Helicopter</string>
+ <!-- Spoken description for Unicode code point U+1F682: "🚂" STEAM LOCOMOTIVE -->
+ <string name="spoken_emoji_1F682">Steam locomotive</string>
+ <!-- Spoken description for Unicode code point U+1F683: "🚃" RAILWAY CAR -->
+ <string name="spoken_emoji_1F683">Railway car</string>
+ <!-- Spoken description for Unicode code point U+1F684: "🚄" HIGH-SPEED TRAIN -->
+ <string name="spoken_emoji_1F684">High-speed train</string>
+ <!-- Spoken description for Unicode code point U+1F685: "🚅" HIGH-SPEED TRAIN WITH BULLET NOSE -->
+ <string name="spoken_emoji_1F685">High-speed train with bullet nose</string>
+ <!-- Spoken description for Unicode code point U+1F686: "🚆" TRAIN -->
+ <string name="spoken_emoji_1F686">Train</string>
+ <!-- Spoken description for Unicode code point U+1F687: "🚇" METRO -->
+ <string name="spoken_emoji_1F687">Metro</string>
+ <!-- Spoken description for Unicode code point U+1F688: "🚈" LIGHT RAIL -->
+ <string name="spoken_emoji_1F688">Light rail</string>
+ <!-- Spoken description for Unicode code point U+1F689: "🚉" STATION -->
+ <string name="spoken_emoji_1F689">Station</string>
+ <!-- Spoken description for Unicode code point U+1F68A: "🚊" TRAM -->
+ <string name="spoken_emoji_1F68A">Tram</string>
+ <!-- Spoken description for Unicode code point U+1F68B: "🚋" TRAM CAR -->
+ <string name="spoken_emoji_1F68B">Tram car</string>
+ <!-- Spoken description for Unicode code point U+1F68C: "🚌" BUS -->
+ <string name="spoken_emoji_1F68C">Bus</string>
+ <!-- Spoken description for Unicode code point U+1F68D: "🚍" ONCOMING BUS -->
+ <string name="spoken_emoji_1F68D">Oncoming bus</string>
+ <!-- Spoken description for Unicode code point U+1F68E: "🚎" TROLLEYBUS -->
+ <string name="spoken_emoji_1F68E">Trolleybus</string>
+ <!-- Spoken description for Unicode code point U+1F68F: "🚏" BUS STOP -->
+ <string name="spoken_emoji_1F68F">Bus stop</string>
+ <!-- Spoken description for Unicode code point U+1F690: "🚐" MINIBUS -->
+ <string name="spoken_emoji_1F690">Minibus</string>
+ <!-- Spoken description for Unicode code point U+1F691: "🚑" AMBULANCE -->
+ <string name="spoken_emoji_1F691">Ambulance</string>
+ <!-- Spoken description for Unicode code point U+1F692: "🚒" FIRE ENGINE -->
+ <string name="spoken_emoji_1F692">Fire engine</string>
+ <!-- Spoken description for Unicode code point U+1F693: "🚓" POLICE CAR -->
+ <string name="spoken_emoji_1F693">Police car</string>
+ <!-- Spoken description for Unicode code point U+1F694: "🚔" ONCOMING POLICE CAR -->
+ <string name="spoken_emoji_1F694">Oncoming police car</string>
+ <!-- Spoken description for Unicode code point U+1F695: "🚕" TAXI -->
+ <string name="spoken_emoji_1F695">Taxi</string>
+ <!-- Spoken description for Unicode code point U+1F696: "🚖" ONCOMING TAXI -->
+ <string name="spoken_emoji_1F696">Oncoming taxi</string>
+ <!-- Spoken description for Unicode code point U+1F697: "🚗" AUTOMOBILE -->
+ <string name="spoken_emoji_1F697">Automobile</string>
+ <!-- Spoken description for Unicode code point U+1F698: "🚘" ONCOMING AUTOMOBILE -->
+ <string name="spoken_emoji_1F698">Oncoming automobile</string>
+ <!-- Spoken description for Unicode code point U+1F699: "🚙" RECREATIONAL VEHICLE -->
+ <string name="spoken_emoji_1F699">Recreational vehicle</string>
+ <!-- Spoken description for Unicode code point U+1F69A: "🚚" DELIVERY TRUCK -->
+ <string name="spoken_emoji_1F69A">Delivery truck</string>
+ <!-- Spoken description for Unicode code point U+1F69B: "🚛" ARTICULATED LORRY -->
+ <string name="spoken_emoji_1F69B">Articulated lorry</string>
+ <!-- Spoken description for Unicode code point U+1F69C: "🚜" TRACTOR -->
+ <string name="spoken_emoji_1F69C">Tractor</string>
+ <!-- Spoken description for Unicode code point U+1F69D: "🚝" MONORAIL -->
+ <string name="spoken_emoji_1F69D">Monorail</string>
+ <!-- Spoken description for Unicode code point U+1F69E: "🚞" MOUNTAIN RAILWAY -->
+ <string name="spoken_emoji_1F69E">Mountain railway</string>
+ <!-- Spoken description for Unicode code point U+1F69F: "🚟" SUSPENSION RAILWAY -->
+ <string name="spoken_emoji_1F69F">Suspension railway</string>
+ <!-- Spoken description for Unicode code point U+1F6A0: "🚠" MOUNTAIN CABLEWAY -->
+ <string name="spoken_emoji_1F6A0">Mountain cableway</string>
+ <!-- Spoken description for Unicode code point U+1F6A1: "🚡" AERIAL TRAMWAY -->
+ <string name="spoken_emoji_1F6A1">Aerial tramway</string>
+ <!-- Spoken description for Unicode code point U+1F6A2: "🚢" SHIP -->
+ <string name="spoken_emoji_1F6A2">Ship</string>
+ <!-- Spoken description for Unicode code point U+1F6A3: "🚣" ROWBOAT -->
+ <string name="spoken_emoji_1F6A3">Rowboat</string>
+ <!-- Spoken description for Unicode code point U+1F6A4: "🚤" SPEEDBOAT -->
+ <string name="spoken_emoji_1F6A4">Speedboat</string>
+ <!-- Spoken description for Unicode code point U+1F6A5: "🚥" HORIZONTAL TRAFFIC LIGHT -->
+ <string name="spoken_emoji_1F6A5">Horizontal traffic light</string>
+ <!-- Spoken description for Unicode code point U+1F6A6: "🚦" VERTICAL TRAFFIC LIGHT -->
+ <string name="spoken_emoji_1F6A6">Vertical traffic light</string>
+ <!-- Spoken description for Unicode code point U+1F6A7: "🚧" CONSTRUCTION SIGN -->
+ <string name="spoken_emoji_1F6A7">Construction sign</string>
+ <!-- Spoken description for Unicode code point U+1F6A8: "🚨" POLICE CARS REVOLVING LIGHT -->
+ <string name="spoken_emoji_1F6A8">Police cars revolving light</string>
+ <!-- Spoken description for Unicode code point U+1F6A9: "🚩" TRIANGULAR FLAG ON POST -->
+ <string name="spoken_emoji_1F6A9">Triangular flag on post</string>
+ <!-- Spoken description for Unicode code point U+1F6AA: "🚪" DOOR -->
+ <string name="spoken_emoji_1F6AA">Door</string>
+ <!-- Spoken description for Unicode code point U+1F6AB: "🚫" NO ENTRY SIGN -->
+ <string name="spoken_emoji_1F6AB">No entry sign</string>
+ <!-- Spoken description for Unicode code point U+1F6AC: "🚬" SMOKING SYMBOL -->
+ <string name="spoken_emoji_1F6AC">Smoking symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6AD: "🚭" NO SMOKING SYMBOL -->
+ <string name="spoken_emoji_1F6AD">No smoking symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6AE: "🚮" PUT LITTER IN ITS PLACE SYMBOL -->
+ <string name="spoken_emoji_1F6AE">Put litter in its place symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6AF: "🚯" DO NOT LITTER SYMBOL -->
+ <string name="spoken_emoji_1F6AF">Do not litter symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6B0: "🚰" POTABLE WATER SYMBOL -->
+ <string name="spoken_emoji_1F6B0">Potable water symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6B1: "🚱" NON-POTABLE WATER SYMBOL -->
+ <string name="spoken_emoji_1F6B1">Non-potable water symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6B2: "🚲" BICYCLE -->
+ <string name="spoken_emoji_1F6B2">Bicycle</string>
+ <!-- Spoken description for Unicode code point U+1F6B3: "🚳" NO BICYCLES -->
+ <string name="spoken_emoji_1F6B3">No bicycles</string>
+ <!-- Spoken description for Unicode code point U+1F6B4: "🚴" BICYCLIST -->
+ <string name="spoken_emoji_1F6B4">Bicyclist</string>
+ <!-- Spoken description for Unicode code point U+1F6B5: "🚵" MOUNTAIN BICYCLIST -->
+ <string name="spoken_emoji_1F6B5">Mountain bicyclist</string>
+ <!-- Spoken description for Unicode code point U+1F6B6: "🚶" PEDESTRIAN -->
+ <string name="spoken_emoji_1F6B6">Pedestrian</string>
+ <!-- Spoken description for Unicode code point U+1F6B7: "🚷" NO PEDESTRIANS -->
+ <string name="spoken_emoji_1F6B7">No pedestrians</string>
+ <!-- Spoken description for Unicode code point U+1F6B8: "🚸" CHILDREN CROSSING -->
+ <string name="spoken_emoji_1F6B8">Children crossing</string>
+ <!-- Spoken description for Unicode code point U+1F6B9: "🚹" MENS SYMBOL -->
+ <string name="spoken_emoji_1F6B9">Mens symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6BA: "🚺" WOMENS SYMBOL -->
+ <string name="spoken_emoji_1F6BA">Womens symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6BB: "🚻" RESTROOM -->
+ <string name="spoken_emoji_1F6BB">Restroom</string>
+ <!-- Spoken description for Unicode code point U+1F6BC: "🚼" BABY SYMBOL -->
+ <string name="spoken_emoji_1F6BC">Baby symbol</string>
+ <!-- Spoken description for Unicode code point U+1F6BD: "🚽" TOILET -->
+ <string name="spoken_emoji_1F6BD">Toilet</string>
+ <!-- Spoken description for Unicode code point U+1F6BE: "🚾" WATER CLOSET -->
+ <string name="spoken_emoji_1F6BE">Water closet</string>
+ <!-- Spoken description for Unicode code point U+1F6BF: "🚿" SHOWER -->
+ <string name="spoken_emoji_1F6BF">Shower</string>
+ <!-- Spoken description for Unicode code point U+1F6C0: "🛀" BATH -->
+ <string name="spoken_emoji_1F6C0">Bath</string>
+ <!-- Spoken description for Unicode code point U+1F6C1: "🛁" BATHTUB -->
+ <string name="spoken_emoji_1F6C1">Bathtub</string>
+ <!-- Spoken description for Unicode code point U+1F6C2: "🛂" PASSPORT CONTROL -->
+ <string name="spoken_emoji_1F6C2">Passport control</string>
+ <!-- Spoken description for Unicode code point U+1F6C3: "🛃" CUSTOMS -->
+ <string name="spoken_emoji_1F6C3">Customs</string>
+ <!-- Spoken description for Unicode code point U+1F6C4: "🛄" BAGGAGE CLAIM -->
+ <string name="spoken_emoji_1F6C4">Baggage claim</string>
+ <!-- Spoken description for Unicode code point U+1F6C5: "🛅" LEFT LUGGAGE -->
+ <string name="spoken_emoji_1F6C5">Left luggage</string>
+</resources>
diff --git a/java/res/values/strings-letter-descriptions.xml b/java/res/values/strings-letter-descriptions.xml
new file mode 100644
index 000000000..297b6bed2
--- /dev/null
+++ b/java/res/values/strings-letter-descriptions.xml
@@ -0,0 +1,384 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<!--
+ These accented letters (spoken_accented_letter_*) are unsupported by TTS.
+ These symbols (spoken_symbol_*) are also unsupported by TTS.
+ TODO: Remove these string resources when TTS/TalkBack support these letters.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Spoken description for Unicode code point U+00AA: "ª" FEMININE ORDINAL INDICATOR -->
+ <string name="spoken_accented_letter_00AA">Feminine ordinal indicator</string>
+ <!-- Spoken description for Unicode code point U+00B5: "µ" MICRO SIGN -->
+ <string name="spoken_accented_letter_00B5">Micro sign</string>
+ <!-- Spoken description for Unicode code point U+00BA: "º" MASCULINE ORDINAL INDICATOR -->
+ <string name="spoken_accented_letter_00BA">Masculine ordinal indicator</string>
+ <!-- Spoken description for Unicode code point U+00DF: "ß" LATIN SMALL LETTER SHARP S -->
+ <string name="spoken_accented_letter_00DF">Sharp S</string>
+ <!-- Spoken description for Unicode code point U+00E0: "à" LATIN SMALL LETTER A WITH GRAVE -->
+ <string name="spoken_accented_letter_00E0">A, grave</string>
+ <!-- Spoken description for Unicode code point U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE -->
+ <string name="spoken_accented_letter_00E1">A, acute</string>
+ <!-- Spoken description for Unicode code point U+00E2: "â" LATIN SMALL LETTER A WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_00E2">A, circumflex</string>
+ <!-- Spoken description for Unicode code point U+00E3: "ã" LATIN SMALL LETTER A WITH TILDE -->
+ <string name="spoken_accented_letter_00E3">A, tilde</string>
+ <!-- Spoken description for Unicode code point U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS -->
+ <string name="spoken_accented_letter_00E4">A, diaeresis</string>
+ <!-- Spoken description for Unicode code point U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE -->
+ <string name="spoken_accented_letter_00E5">A, ring above</string>
+ <!-- Spoken description for Unicode code point U+00E6: "æ" LATIN SMALL LETTER AE -->
+ <string name="spoken_accented_letter_00E6">A, E, ligature</string>
+ <!-- Spoken description for Unicode code point U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA -->
+ <string name="spoken_accented_letter_00E7">C, cedilla</string>
+ <!-- Spoken description for Unicode code point U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE -->
+ <string name="spoken_accented_letter_00E8">E, grave</string>
+ <!-- Spoken description for Unicode code point U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE -->
+ <string name="spoken_accented_letter_00E9">E, acute</string>
+ <!-- Spoken description for Unicode code point U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_00EA">E, circumflex</string>
+ <!-- Spoken description for Unicode code point U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS -->
+ <string name="spoken_accented_letter_00EB">E, diaeresis</string>
+ <!-- Spoken description for Unicode code point U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE -->
+ <string name="spoken_accented_letter_00EC">I, grave</string>
+ <!-- Spoken description for Unicode code point U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE -->
+ <string name="spoken_accented_letter_00ED">I, acute</string>
+ <!-- Spoken description for Unicode code point U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_00EE">I, circumflex</string>
+ <!-- Spoken description for Unicode code point U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS -->
+ <string name="spoken_accented_letter_00EF">I, diaeresis</string>
+ <!-- Spoken description for Unicode code point U+00F0: "ð" LATIN SMALL LETTER ETH -->
+ <string name="spoken_accented_letter_00F0">Eth</string>
+ <!-- Spoken description for Unicode code point U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE -->
+ <string name="spoken_accented_letter_00F1">N, tilde</string>
+ <!-- Spoken description for Unicode code point U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE -->
+ <string name="spoken_accented_letter_00F2">O, grave</string>
+ <!-- Spoken description for Unicode code point U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE -->
+ <string name="spoken_accented_letter_00F3">O, acute</string>
+ <!-- Spoken description for Unicode code point U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_00F4">O, circumflex</string>
+ <!-- Spoken description for Unicode code point U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE -->
+ <string name="spoken_accented_letter_00F5">O, tilde</string>
+ <!-- Spoken description for Unicode code point U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS -->
+ <string name="spoken_accented_letter_00F6">O, diaeresis</string>
+ <!-- Spoken description for Unicode code point U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE -->
+ <string name="spoken_accented_letter_00F8">O, stroke</string>
+ <!-- Spoken description for Unicode code point U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE -->
+ <string name="spoken_accented_letter_00F9">U, grave</string>
+ <!-- Spoken description for Unicode code point U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE -->
+ <string name="spoken_accented_letter_00FA">U, acute</string>
+ <!-- Spoken description for Unicode code point U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_00FB">U, circumflex</string>
+ <!-- Spoken description for Unicode code point U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS -->
+ <string name="spoken_accented_letter_00FC">U, diaeresis</string>
+ <!-- Spoken description for Unicode code point U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE -->
+ <string name="spoken_accented_letter_00FD">Y, acute</string>
+ <!-- Spoken description for Unicode code point U+00FE: "þ" LATIN SMALL LETTER THORN -->
+ <string name="spoken_accented_letter_00FE">Thorn</string>
+ <!-- Spoken description for Unicode code point U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS -->
+ <string name="spoken_accented_letter_00FF">Y, diaeresis</string>
+ <!-- Spoken description for Unicode code point U+0101: "ā" LATIN SMALL LETTER A WITH MACRON -->
+ <string name="spoken_accented_letter_0101">A, macron</string>
+ <!-- Spoken description for Unicode code point U+0103: "ă" LATIN SMALL LETTER A WITH BREVE -->
+ <string name="spoken_accented_letter_0103">A, breve</string>
+ <!-- Spoken description for Unicode code point U+0105: "ą" LATIN SMALL LETTER A WITH OGONEK -->
+ <string name="spoken_accented_letter_0105">A, ogonek</string>
+ <!-- Spoken description for Unicode code point U+0107: "ć" LATIN SMALL LETTER C WITH ACUTE -->
+ <string name="spoken_accented_letter_0107">C, acute</string>
+ <!-- Spoken description for Unicode code point U+0109: "ĉ" LATIN SMALL LETTER C WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_0109">C, circumflex</string>
+ <!-- Spoken description for Unicode code point U+010B: "ċ" LATIN SMALL LETTER C WITH DOT ABOVE -->
+ <string name="spoken_accented_letter_010B">C, dot above</string>
+ <!-- Spoken description for Unicode code point U+010D: "č" LATIN SMALL LETTER C WITH CARON -->
+ <string name="spoken_accented_letter_010D">C, caron</string>
+ <!-- Spoken description for Unicode code point U+010F: "ď" LATIN SMALL LETTER D WITH CARON -->
+ <string name="spoken_accented_letter_010F">D, caron</string>
+ <!-- Spoken description for Unicode code point U+0111: "đ" LATIN SMALL LETTER D WITH STROKE -->
+ <string name="spoken_accented_letter_0111">D, stroke</string>
+ <!-- Spoken description for Unicode code point U+0113: "ē" LATIN SMALL LETTER E WITH MACRON -->
+ <string name="spoken_accented_letter_0113">E, macron</string>
+ <!-- Spoken description for Unicode code point U+0115: "ĕ" LATIN SMALL LETTER E WITH BREVE -->
+ <string name="spoken_accented_letter_0115">E, breve</string>
+ <!-- Spoken description for Unicode code point U+0117: "ė" LATIN SMALL LETTER E WITH DOT ABOVE -->
+ <string name="spoken_accented_letter_0117">E, dot above</string>
+ <!-- Spoken description for Unicode code point U+0119: "ę" LATIN SMALL LETTER E WITH OGONEK -->
+ <string name="spoken_accented_letter_0119">E, ogonek</string>
+ <!-- Spoken description for Unicode code point U+011B: "ě" LATIN SMALL LETTER E WITH CARON -->
+ <string name="spoken_accented_letter_011B">E, caron</string>
+ <!-- Spoken description for Unicode code point U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_011D">G, circumflex</string>
+ <!-- Spoken description for Unicode code point U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE -->
+ <string name="spoken_accented_letter_011F">G, breve</string>
+ <!-- Spoken description for Unicode code point U+0121: "ġ" LATIN SMALL LETTER G WITH DOT ABOVE -->
+ <string name="spoken_accented_letter_0121">G, dot above</string>
+ <!-- Spoken description for Unicode code point U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA -->
+ <string name="spoken_accented_letter_0123">G, cedilla</string>
+ <!-- Spoken description for Unicode code point U+0125: "ĥ" LATIN SMALL LETTER H WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_0125">H, circumflex</string>
+ <!-- Spoken description for Unicode code point U+0127: "ħ" LATIN SMALL LETTER H WITH STROKE -->
+ <string name="spoken_accented_letter_0127">H, stroke</string>
+ <!-- Spoken description for Unicode code point U+0129: "ĩ" LATIN SMALL LETTER I WITH TILDE -->
+ <string name="spoken_accented_letter_0129">I, tilde</string>
+ <!-- Spoken description for Unicode code point U+012B: "ī" LATIN SMALL LETTER I WITH MACRON -->
+ <string name="spoken_accented_letter_012B">I, macron</string>
+ <!-- Spoken description for Unicode code point U+012D: "ĭ" LATIN SMALL LETTER I WITH BREVE -->
+ <string name="spoken_accented_letter_012D">I, breve</string>
+ <!-- Spoken description for Unicode code point U+012F: "į" LATIN SMALL LETTER I WITH OGONEK -->
+ <string name="spoken_accented_letter_012F">I, ogonek</string>
+ <!-- Spoken description for Unicode code point U+0131: "ı" LATIN SMALL LETTER DOTLESS I -->
+ <string name="spoken_accented_letter_0131">Dotless I</string>
+ <!-- Spoken description for Unicode code point U+0133: "ij" LATIN SMALL LIGATURE IJ -->
+ <string name="spoken_accented_letter_0133">I, J, ligature</string>
+ <!-- Spoken description for Unicode code point U+0135: "ĵ" LATIN SMALL LETTER J WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_0135">J, circumflex</string>
+ <!-- Spoken description for Unicode code point U+0137: "ķ" LATIN SMALL LETTER K WITH CEDILLA -->
+ <string name="spoken_accented_letter_0137">K, cedilla</string>
+ <!-- Spoken description for Unicode code point U+0138: "ĸ" LATIN SMALL LETTER KRA -->
+ <string name="spoken_accented_letter_0138">Kra</string>
+ <!-- Spoken description for Unicode code point U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE -->
+ <string name="spoken_accented_letter_013A">L, acute</string>
+ <!-- Spoken description for Unicode code point U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA -->
+ <string name="spoken_accented_letter_013C">L, cedilla</string>
+ <!-- Spoken description for Unicode code point U+013E: "ľ" LATIN SMALL LETTER L WITH CARON -->
+ <string name="spoken_accented_letter_013E">L, caron</string>
+ <!-- Spoken description for Unicode code point U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT -->
+ <string name="spoken_accented_letter_0140">L, middle dot</string>
+ <!-- Spoken description for Unicode code point U+0142: "ł" LATIN SMALL LETTER L WITH STROKE -->
+ <string name="spoken_accented_letter_0142">L, stroke</string>
+ <!-- Spoken description for Unicode code point U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE -->
+ <string name="spoken_accented_letter_0144">N, acute</string>
+ <!-- Spoken description for Unicode code point U+0146: "ņ" LATIN SMALL LETTER N WITH CEDILLA -->
+ <string name="spoken_accented_letter_0146">N, cedilla</string>
+ <!-- Spoken description for Unicode code point U+0148: "ň" LATIN SMALL LETTER N WITH CARON -->
+ <string name="spoken_accented_letter_0148">N, caron</string>
+ <!-- Spoken description for Unicode code point U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE -->
+ <string name="spoken_accented_letter_0149">N, preceded by apostrophe</string>
+ <!-- Spoken description for Unicode code point U+014B: "ŋ" LATIN SMALL LETTER ENG -->
+ <string name="spoken_accented_letter_014B">Eng</string>
+ <!-- Spoken description for Unicode code point U+014D: "ō" LATIN SMALL LETTER O WITH MACRON -->
+ <string name="spoken_accented_letter_014D">O, macron</string>
+ <!-- Spoken description for Unicode code point U+014F: "ŏ" LATIN SMALL LETTER O WITH BREVE -->
+ <string name="spoken_accented_letter_014F">O, breve</string>
+ <!-- Spoken description for Unicode code point U+0151: "ő" LATIN SMALL LETTER O WITH DOUBLE ACUTE -->
+ <string name="spoken_accented_letter_0151">O, double acute</string>
+ <!-- Spoken description for Unicode code point U+0153: "œ" LATIN SMALL LIGATURE OE -->
+ <string name="spoken_accented_letter_0153">O, E, ligature</string>
+ <!-- Spoken description for Unicode code point U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE -->
+ <string name="spoken_accented_letter_0155">R, acute</string>
+ <!-- Spoken description for Unicode code point U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA -->
+ <string name="spoken_accented_letter_0157">R, cedilla</string>
+ <!-- Spoken description for Unicode code point U+0159: "ř" LATIN SMALL LETTER R WITH CARON -->
+ <string name="spoken_accented_letter_0159">R, caron</string>
+ <!-- Spoken description for Unicode code point U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE -->
+ <string name="spoken_accented_letter_015B">S, acute</string>
+ <!-- Spoken description for Unicode code point U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_015D">S, circumflex</string>
+ <!-- Spoken description for Unicode code point U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA -->
+ <string name="spoken_accented_letter_015F">S, cedilla</string>
+ <!-- Spoken description for Unicode code point U+0161: "š" LATIN SMALL LETTER S WITH CARON -->
+ <string name="spoken_accented_letter_0161">S, caron</string>
+ <!-- Spoken description for Unicode code point U+0163: "ţ" LATIN SMALL LETTER T WITH CEDILLA -->
+ <string name="spoken_accented_letter_0163">T, cedilla</string>
+ <!-- Spoken description for Unicode code point U+0165: "ť" LATIN SMALL LETTER T WITH CARON -->
+ <string name="spoken_accented_letter_0165">T, caron</string>
+ <!-- Spoken description for Unicode code point U+0167: "ŧ" LATIN SMALL LETTER T WITH STROKE -->
+ <string name="spoken_accented_letter_0167">T, stroke</string>
+ <!-- Spoken description for Unicode code point U+0169: "ũ" LATIN SMALL LETTER U WITH TILDE -->
+ <string name="spoken_accented_letter_0169">U, tilde</string>
+ <!-- Spoken description for Unicode code point U+016B: "ū" LATIN SMALL LETTER U WITH MACRON -->
+ <string name="spoken_accented_letter_016B">U, macron</string>
+ <!-- Spoken description for Unicode code point U+016D: "ŭ" LATIN SMALL LETTER U WITH BREVE -->
+ <string name="spoken_accented_letter_016D">U, breve</string>
+ <!-- Spoken description for Unicode code point U+016F: "ů" LATIN SMALL LETTER U WITH RING ABOVE -->
+ <string name="spoken_accented_letter_016F">U, ring above</string>
+ <!-- Spoken description for Unicode code point U+0171: "ű" LATIN SMALL LETTER U WITH DOUBLE ACUTE -->
+ <string name="spoken_accented_letter_0171">U, double acute</string>
+ <!-- Spoken description for Unicode code point U+0173: "ų" LATIN SMALL LETTER U WITH OGONEK -->
+ <string name="spoken_accented_letter_0173">U, ogonek</string>
+ <!-- Spoken description for Unicode code point U+0175: "ŵ" LATIN SMALL LETTER W WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_0175">W, circumflex</string>
+ <!-- Spoken description for Unicode code point U+0177: "ŷ" LATIN SMALL LETTER Y WITH CIRCUMFLEX -->
+ <string name="spoken_accented_letter_0177">Y, circumflex</string>
+ <!-- Spoken description for Unicode code point U+017A: "ź" LATIN SMALL LETTER Z WITH ACUTE -->
+ <string name="spoken_accented_letter_017A">Z, acute</string>
+ <!-- Spoken description for Unicode code point U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE -->
+ <string name="spoken_accented_letter_017C">Z, dot above</string>
+ <!-- Spoken description for Unicode code point U+017E: "ž" LATIN SMALL LETTER Z WITH CARON -->
+ <string name="spoken_accented_letter_017E">Z, caron</string>
+ <!-- Spoken description for Unicode code point U+017F: "ſ" LATIN SMALL LETTER LONG S -->
+ <string name="spoken_accented_letter_017F">Long S</string>
+ <!-- Spoken description for Unicode code point U+01A1: "ơ" LATIN SMALL LETTER O WITH HORN -->
+ <string name="spoken_accented_letter_01A1">O, horn</string>
+ <!-- Spoken description for Unicode code point U+01B0: "ư" LATIN SMALL LETTER U WITH HORN -->
+ <string name="spoken_accented_letter_01B0">U, horn</string>
+ <!-- Spoken description for Unicode code point U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW -->
+ <string name="spoken_accented_letter_0219">S, comma below</string>
+ <!-- Spoken description for Unicode code point U+021B: "ț" LATIN SMALL LETTER T WITH COMMA BELOW -->
+ <string name="spoken_accented_letter_021B">T, comma below</string>
+ <!-- Spoken description for Unicode code point U+0259: "ə" LATIN SMALL LETTER SCHWA -->
+ <string name="spoken_accented_letter_0259">Schwa</string>
+ <!-- Spoken description for Unicode code point U+1EA1: "ạ" LATIN SMALL LETTER A WITH DOT BELOW -->
+ <string name="spoken_accented_letter_1EA1">A, dot below</string>
+ <!-- Spoken description for Unicode code point U+1EA3: "ả" LATIN SMALL LETTER A WITH HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EA3">A, hook above</string>
+ <!-- Spoken description for Unicode code point U+1EA5: "ấ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE -->
+ <string name="spoken_accented_letter_1EA5">A, circumflex and acute</string>
+ <!-- Spoken description for Unicode code point U+1EA7: "ầ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE -->
+ <string name="spoken_accented_letter_1EA7">A, circumflex and grave</string>
+ <!-- Spoken description for Unicode code point U+1EA9: "ẩ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EA9">A, circumflex and hook above</string>
+ <!-- Spoken description for Unicode code point U+1EAB: "ẫ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE -->
+ <string name="spoken_accented_letter_1EAB">A, circumflex and tilde</string>
+ <!-- Spoken description for Unicode code point U+1EAD: "ậ" LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW -->
+ <string name="spoken_accented_letter_1EAD">A, circumflex and dot below</string>
+ <!-- Spoken description for Unicode code point U+1EAF: "ắ" LATIN SMALL LETTER A WITH BREVE AND ACUTE -->
+ <string name="spoken_accented_letter_1EAF">A, breve and acute</string>
+ <!-- Spoken description for Unicode code point U+1EB1: "ằ" LATIN SMALL LETTER A WITH BREVE AND GRAVE -->
+ <string name="spoken_accented_letter_1EB1">A, breve and grave</string>
+ <!-- Spoken description for Unicode code point U+1EB3: "ẳ" LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EB3">A, breve and hook above</string>
+ <!-- Spoken description for Unicode code point U+1EB5: "ẵ" LATIN SMALL LETTER A WITH BREVE AND TILDE -->
+ <string name="spoken_accented_letter_1EB5">A, breve and tilde</string>
+ <!-- Spoken description for Unicode code point U+1EB7: "ặ" LATIN SMALL LETTER A WITH BREVE AND DOT BELOW -->
+ <string name="spoken_accented_letter_1EB7">A, breve and dot below</string>
+ <!-- Spoken description for Unicode code point U+1EB9: "ẹ" LATIN SMALL LETTER E WITH DOT BELOW -->
+ <string name="spoken_accented_letter_1EB9">E, dot below</string>
+ <!-- Spoken description for Unicode code point U+1EBB: "ẻ" LATIN SMALL LETTER E WITH HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EBB">E, hook above</string>
+ <!-- Spoken description for Unicode code point U+1EBD: "ẽ" LATIN SMALL LETTER E WITH TILDE -->
+ <string name="spoken_accented_letter_1EBD">E, tilde</string>
+ <!-- Spoken description for Unicode code point U+1EBF: "ế" LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE -->
+ <string name="spoken_accented_letter_1EBF">E, circumflex and acute</string>
+ <!-- Spoken description for Unicode code point U+1EC1: "ề" LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE -->
+ <string name="spoken_accented_letter_1EC1">E, circumflex and grave</string>
+ <!-- Spoken description for Unicode code point U+1EC3: "ể" LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EC3">E, circumflex and hook above</string>
+ <!-- Spoken description for Unicode code point U+1EC5: "ễ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE -->
+ <string name="spoken_accented_letter_1EC5">E, circumflex and tilde</string>
+ <!-- Spoken description for Unicode code point U+1EC7: "ệ" LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW -->
+ <string name="spoken_accented_letter_1EC7">E, circumflex and dot below</string>
+ <!-- Spoken description for Unicode code point U+1EC9: "ỉ" LATIN SMALL LETTER I WITH HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EC9">I, hook above</string>
+ <!-- Spoken description for Unicode code point U+1ECB: "ị" LATIN SMALL LETTER I WITH DOT BELOW -->
+ <string name="spoken_accented_letter_1ECB">I, dot below</string>
+ <!-- Spoken description for Unicode code point U+1ECD: "ọ" LATIN SMALL LETTER O WITH DOT BELOW -->
+ <string name="spoken_accented_letter_1ECD">O, dot below</string>
+ <!-- Spoken description for Unicode code point U+1ECF: "ỏ" LATIN SMALL LETTER O WITH HOOK ABOVE -->
+ <string name="spoken_accented_letter_1ECF">O, hook above</string>
+ <!-- Spoken description for Unicode code point U+1ED1: "ố" LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE -->
+ <string name="spoken_accented_letter_1ED1">O, circumflex and acute</string>
+ <!-- Spoken description for Unicode code point U+1ED3: "ồ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE -->
+ <string name="spoken_accented_letter_1ED3">O, circumflex and grave</string>
+ <!-- Spoken description for Unicode code point U+1ED5: "ổ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE -->
+ <string name="spoken_accented_letter_1ED5">O, circumflex and hook above</string>
+ <!-- Spoken description for Unicode code point U+1ED7: "ỗ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE -->
+ <string name="spoken_accented_letter_1ED7">O, circumflex and tilde</string>
+ <!-- Spoken description for Unicode code point U+1ED9: "ộ" LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW -->
+ <string name="spoken_accented_letter_1ED9">O, circumflex and dot below</string>
+ <!-- Spoken description for Unicode code point U+1EDB: "ớ" LATIN SMALL LETTER O WITH HORN AND ACUTE -->
+ <string name="spoken_accented_letter_1EDB">O, horn and acute</string>
+ <!-- Spoken description for Unicode code point U+1EDD: "ờ" LATIN SMALL LETTER O WITH HORN AND GRAVE -->
+ <string name="spoken_accented_letter_1EDD">O, horn and grave</string>
+ <!-- Spoken description for Unicode code point U+1EDF: "ở" LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EDF">O, horn and hook above</string>
+ <!-- Spoken description for Unicode code point U+1EE1: "ỡ" LATIN SMALL LETTER O WITH HORN AND TILDE -->
+ <string name="spoken_accented_letter_1EE1">O, horn and tilde</string>
+ <!-- Spoken description for Unicode code point U+1EE3: "ợ" LATIN SMALL LETTER O WITH HORN AND DOT BELOW -->
+ <string name="spoken_accented_letter_1EE3">O, horn and dot below</string>
+ <!-- Spoken description for Unicode code point U+1EE5: "ụ" LATIN SMALL LETTER U WITH DOT BELOW -->
+ <string name="spoken_accented_letter_1EE5">U, dot below</string>
+ <!-- Spoken description for Unicode code point U+1EE7: "ủ" LATIN SMALL LETTER U WITH HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EE7">U, hook above</string>
+ <!-- Spoken description for Unicode code point U+1EE9: "ứ" LATIN SMALL LETTER U WITH HORN AND ACUTE -->
+ <string name="spoken_accented_letter_1EE9">U, horn and acute</string>
+ <!-- Spoken description for Unicode code point U+1EEB: "ừ" LATIN SMALL LETTER U WITH HORN AND GRAVE -->
+ <string name="spoken_accented_letter_1EEB">U, horn and grave</string>
+ <!-- Spoken description for Unicode code point U+1EED: "ử" LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EED">U, horn and hook above</string>
+ <!-- Spoken description for Unicode code point U+1EEF: "ữ" LATIN SMALL LETTER U WITH HORN AND TILDE -->
+ <string name="spoken_accented_letter_1EEF">U, horn and tilde</string>
+ <!-- Spoken description for Unicode code point U+1EF1: "ự" LATIN SMALL LETTER U WITH HORN AND DOT BELOW -->
+ <string name="spoken_accented_letter_1EF1">U, horn and dot below</string>
+ <!-- Spoken description for Unicode code point U+1EF3: "ỳ" LATIN SMALL LETTER Y WITH GRAVE -->
+ <string name="spoken_accented_letter_1EF3">Y, grave</string>
+ <!-- Spoken description for Unicode code point U+1EF5: "ỵ" LATIN SMALL LETTER Y WITH DOT BELOW -->
+ <string name="spoken_accented_letter_1EF5">Y, dot below</string>
+ <!-- Spoken description for Unicode code point U+1EF7: "ỷ" LATIN SMALL LETTER Y WITH HOOK ABOVE -->
+ <string name="spoken_accented_letter_1EF7">Y, hook above</string>
+ <!-- Spoken description for Unicode code point U+1EF9: "ỹ" LATIN SMALL LETTER Y WITH TILDE -->
+ <string name="spoken_accented_letter_1EF9">Y, tilde</string>
+ <!-- Spoken description for Unicode code point U+00A1: "¡" INVERTED EXCLAMATION MARK -->
+ <string name="spoken_symbol_00A1">Inverted exclamation mark</string>
+ <!-- Spoken description for Unicode code point U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -->
+ <string name="spoken_symbol_00AB">Left-pointing double angle quotation mark</string>
+ <!-- Spoken description for Unicode code point U+00B7: "·" MIDDLE DOT -->
+ <string name="spoken_symbol_00B7">Middle dot</string>
+ <!-- Spoken description for Unicode code point U+00B9: "¹" SUPERSCRIPT ONE -->
+ <string name="spoken_symbol_00B9">Superscript one</string>
+ <!-- Spoken description for Unicode code point U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -->
+ <string name="spoken_symbol_00BB">Right-pointing double angle quotation mark</string>
+ <!-- Spoken description for Unicode code point U+00BF: "¿" INVERTED QUESTION MARK -->
+ <string name="spoken_symbol_00BF">Inverted question mark</string>
+ <!-- Spoken description for Unicode code point U+2018: "‘" LEFT SINGLE QUOTATION MARK -->
+ <string name="spoken_symbol_2018">Left single quotation mark</string>
+ <!-- Spoken description for Unicode code point U+2019: "’" RIGHT SINGLE QUOTATION MARK -->
+ <string name="spoken_symbol_2019">Right single quotation mark</string>
+ <!-- Spoken description for Unicode code point U+201A: "‚" SINGLE LOW-9 QUOTATION MARK -->
+ <string name="spoken_symbol_201A">Single low-9 quotation mark</string>
+ <!-- Spoken description for Unicode code point U+201C: "“" LEFT DOUBLE QUOTATION MARK -->
+ <string name="spoken_symbol_201C">Left double quotation mark</string>
+ <!-- Spoken description for Unicode code point U+201D: "”" RIGHT DOUBLE QUOTATION MARK -->
+ <string name="spoken_symbol_201D">Right double quotation mark</string>
+ <!-- Spoken description for Unicode code point U+2020: "†" DAGGER -->
+ <string name="spoken_symbol_2020">Dagger</string>
+ <!-- Spoken description for Unicode code point U+2021: "‡" DOUBLE DAGGER -->
+ <string name="spoken_symbol_2021">Double dagger</string>
+ <!-- Spoken description for Unicode code point U+2030: "‰" PER MILLE SIGN -->
+ <string name="spoken_symbol_2030">Per mille sign</string>
+ <!-- Spoken description for Unicode code point U+2032: "′" PRIME -->
+ <string name="spoken_symbol_2032">Prime</string>
+ <!-- Spoken description for Unicode code point U+2033: "″" DOUBLE PRIME -->
+ <string name="spoken_symbol_2033">Double prime</string>
+ <!-- Spoken description for Unicode code point U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK -->
+ <string name="spoken_symbol_2039">Single left-pointing angle quotation mark</string>
+ <!-- Spoken description for Unicode code point U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -->
+ <string name="spoken_symbol_203A">Single right-pointing angle quotation mark</string>
+ <!-- Spoken description for Unicode code point U+2074: "⁴" SUPERSCRIPT FOUR -->
+ <string name="spoken_symbol_2074">Superscript four</string>
+ <!-- Spoken description for Unicode code point U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N -->
+ <string name="spoken_symbol_207F">Superscript latin small letter n</string>
+ <!-- Spoken description for Unicode code point U+20B1: "₱" PESO SIGN -->
+ <string name="spoken_symbol_20B1">Peso sign</string>
+ <!-- Spoken description for Unicode code point U+2105: "℅" CARE OF -->
+ <string name="spoken_symbol_2105">Care of</string>
+ <!-- Spoken description for Unicode code point U+2192: "→" RIGHTWARDS ARROW -->
+ <string name="spoken_symbol_2192">Rightwards arrow</string>
+ <!-- Spoken description for Unicode code point U+2193: "↓" DOWNWARDS ARROW -->
+ <string name="spoken_symbol_2193">Downwards arrow</string>
+ <!-- Spoken description for Unicode code point U+2205: "∅" EMPTY SET -->
+ <string name="spoken_symbol_2205">Empty set</string>
+ <!-- Spoken description for Unicode code point U+2206: "∆" INCREMENT -->
+ <string name="spoken_symbol_2206">Increment</string>
+ <!-- Spoken description for Unicode code point U+2264: "≤" LESS-THAN OR EQUAL TO -->
+ <string name="spoken_symbol_2264">Less-than or equal to</string>
+ <!-- Spoken description for Unicode code point U+2265: "≥" GREATER-THAN OR EQUAL TO -->
+ <string name="spoken_symbol_2265">Greater-than or equal to</string>
+ <!-- Spoken description for Unicode code point U+2605: "★" BLACK STAR -->
+ <string name="spoken_symbol_2605">Black star</string>
+</resources>
diff --git a/java/res/values/urls.xml b/java/res/values/strings-production.xml
index a8e9ad7d3..8064b9949 100644
--- a/java/res/values/urls.xml
+++ b/java/res/values/strings-production.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
** limitations under the License.
*/
-->
+
<resources>
- <string name="research_logger_upload_url" translatable="false"></string>
+ <!-- Description for option to enable sending usage statistics -->
+ <string name="enable_metrics_logging_summary" translatable="false"></string>
</resources>
diff --git a/java/res/values/strings-talkback-descriptions.xml b/java/res/values/strings-talkback-descriptions.xml
index 9c1e652b0..80c7bdbf0 100644
--- a/java/res/values/strings-talkback-descriptions.xml
+++ b/java/res/values/strings-talkback-descriptions.xml
@@ -32,13 +32,17 @@
<string name="spoken_auto_correct_obscured"><xliff:g id="KEY_NAME" example="Space">%1$s</xliff:g> performs auto-correction</string>
<!-- Spoken description for unknown keyboard keys. -->
- <string name="spoken_description_unknown">Key code %d</string>
+ <string name="spoken_description_unknown">Unknown character</string>
<!-- Spoken description for the "Shift" keyboard key when "Shift" is off. -->
<string name="spoken_description_shift">Shift</string>
+ <!-- Spoken description for the "Shift" keyboard key in symbols mode. -->
+ <string name="spoken_description_symbols_shift">More symbols</string>
<!-- Spoken description for the "Shift" keyboard key when "Shift" is on. -->
- <string name="spoken_description_shift_shifted">Shift on (tap to disable)</string>
+ <string name="spoken_description_shift_shifted">Shift</string>
+ <!-- Spoken description for the "Shift" keyboard key in 2nd symbols (a.k.a. symbols shift) mode. -->
+ <string name="spoken_description_symbols_shift_shifted">Symbols</string>
<!-- Spoken description for the "Shift" keyboard key when "Caps lock" is on. -->
- <string name="spoken_description_caps_lock">Caps lock on (tap to disable)</string>
+ <string name="spoken_description_caps_lock">Shift</string>
<!-- Spoken description for the "Delete" keyboard key. -->
<string name="spoken_description_delete">Delete</string>
<!-- Spoken description for the "To Symbol" keyboard key. -->
@@ -74,11 +78,10 @@
<string name="spoken_description_shiftmode_on">Shift enabled</string>
<!-- Spoken feedback after turning "Caps lock" mode on. -->
<string name="spoken_description_shiftmode_locked">Caps lock enabled</string>
- <!-- Spoken feedback after turning "Shift" mode off. -->
- <string name="spoken_description_shiftmode_off">Shift disabled</string>
-
<!-- Spoken feedback after changing to the symbols keyboard. -->
<string name="spoken_description_mode_symbol">Symbols mode</string>
+ <!-- Spoken feedback after changing to the 2nd symbols (a.k.a. symbols shift) keyboard. -->
+ <string name="spoken_description_mode_symbol_shift">More symbols mode</string>
<!-- Spoken feedback after changing to the alphanumeric keyboard. -->
<string name="spoken_description_mode_alpha">Letters mode</string>
<!-- Spoken feedback after changing to the phone dialer keyboard. -->
@@ -123,4 +126,27 @@
<string name="spoken_descrption_emoji_category_symbols">Symbols</string>
<!-- Description of the emoji category icon of Emoticons. -->
<string name="spoken_descrption_emoji_category_emoticons">Emoticons</string>
+
+ <!-- Description of an upper case letter of LOWER_LETTER. -->
+ <string name="spoken_description_upper_case">Capital <xliff:g id="LOWER_LETTER" example="A, E, ligature">%s</xliff:g></string>
+ <!-- Spoken description for Unicode code point U+0049: "I" LATIN CAPITAL LETTER I
+ Note that depending on locale, the lower-case of this letter is U+0069 or U+0131. -->
+ <string name="spoken_letter_0049">Capital I</string>
+ <!-- Spoken description for Unicode code point U+0130: "İ" LATIN CAPITAL LETTER I WITH DOT ABOVE
+ Note that depending on locale, the lower-case of this letter is U+0069 or U+0131. -->
+ <string name="spoken_letter_0130">Capital I, dot above</string>
+ <!-- Spoken description for unknown symbol code point. -->
+ <string name="spoken_symbol_unknown">Unknown symbol</string>
+ <!-- Spoken description for unknown emoji code point. -->
+ <string name="spoken_emoji_unknown">Unknown emoji</string>
+
+ <!-- Spoken descriptions when opening a more keys keyboard that has alternative characters. -->
+ <string name="spoken_open_more_keys_keyboard">Alternative characters are available</string>
+ <!-- Spoken descriptions when closing a more keys keyboard that has alternative characters. -->
+ <string name="spoken_close_more_keys_keyboard">Alternative characters are dismissed</string>
+
+ <!-- Spoken descriptions when opening a more suggestions panel that has alternative suggested words. -->
+ <string name="spoken_open_more_suggestions">Alternative suggestions are available</string>
+ <!-- Spoken descriptions when closing a more suggestions panel that has alternative suggested words. -->
+ <string name="spoken_close_more_suggestions">Alternative suggestions are dismissed</string>
</resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 9f93055e2..884911565 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -21,9 +21,6 @@
<!-- Title for Latin keyboard input options dialog [CHAR LIMIT=25] -->
<string name="english_ime_input_options">Input options</string>
- <!-- Title for Latin keyboard research log dialog, which contains special commands for users that contribute data for research. [CHAR LIMIT=33] -->
- <string name="english_ime_research_log">Research Log Commands</string>
-
<!-- Title for the spell checker option to turn on/off contact names lookup [CHAR LIMIT=25] -->
<string name="use_contacts_for_spellchecking_option_title">Look up contact names</string>
@@ -90,6 +87,9 @@
<!-- Option name for enabling the use by the keyboards of sent/received messages, e-mail and typing history to improve suggestion accuracy [CHAR LIMIT=25] -->
<string name="use_personalized_dicts">Personalized suggestions</string>
+ <!-- Option to enable sending usage statistics -->
+ <string name="enable_metrics_logging">"Improve <xliff:g id="APPLICATION_NAME" example="Android Keyboard">%s</xliff:g>"</string>
+
<!-- Option name for enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=30] -->
<string name="use_double_space_period">Double-space period</string>
<!-- Description for option enabling or disabling the double-space period feature that lets double tap on spacebar insert a period followed by a space [CHAR LIMIT=65] -->
@@ -166,68 +166,8 @@
<!-- Title for input language selection screen -->
<string name="language_selection_title">Input languages</string>
- <!-- Title for dialog option to let users cancel logging and delete log for this session [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_do_not_log_this_session" translatable="false">Suspend logging</string>
- <!-- Title for dialog option to let users reenable logging [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_enable_session_logging" translatable="false">Enable logging</string>
- <!-- Toast notification that the system is processing the request to delete the log for this session [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_notify_session_log_deleting" translatable="false">Deleting session log</string>
- <!-- Toast notification that the system has successfully deleted the log for this session [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_notify_logging_suspended" translatable="false">Logging temporarily suspended. To disable permanently, go to Android Keyboard Settings</string>
- <!-- Toast notification that the system has failed to delete the log for this session [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_notify_session_log_not_deleted" translatable="false">Session log NOT deleted</string>
- <!-- Toast notification that the system is enabling logging [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_notify_session_logging_enabled" translatable="false">Session logging enabled</string>
-
- <!-- Text for checkbox option to include user data in feedback for research purposes [CHAR LIMIT=50] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_include_history_label" translatable="false">Include session history</string>
- <!-- Text for checkbox option to include user account name in feedback for research purposes [CHAR LIMIT=50] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_include_account_name_label" translatable="false">Include account name</string>
- <!-- Text for checkbox option to include a recording in feedback for research purposes [CHAR LIMIT=50] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_include_recording_label" translatable="false">Include recorded demonstration</string>
- <!-- Dialog button choice to send research feedback [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_send" translatable="false">Send</string>
- <!-- Dialog button choice to cancel sending research feedback [CHAR LIMIT=35] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_cancel" translatable="false">Cancel</string>
- <!-- Temporary notification to provide user with instructions about stopping a recording
- - operation[CHAR LIMIT=100] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_demonstration_instructions" translatable="false">Please demonstrate the issue you are writing about.\n\nWhen finished, select the \"Bug?\" button again."</string>
<!-- Title of a preference to send feedback. [CHAR LIMIT=30]-->
<string name="send_feedback">Send feedback</string>
- <!-- Temporary notification of recording failure [CHAR LIMIT=100] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_feedback_recording_failure" translatable="false">Recording cancelled due to timeout</string>
- <!-- Toast notification to ask user to quit the research feedback dialog to perform this operation [CHAR LIMIT=100] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_please_exit_feedback_form" translatable="false">Please exit the feedback dialog to access the research log menu</string>
-
- <!-- Title of dialog shown at start informing users about contributing research usage data-->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_splash_title" translatable="false">Warning</string>
-
- <!-- Toast message informing users that logging has been disabled -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_logging_disabled" translatable="false">Logging Disabled</string>
-
- <!-- Name for the research uploading service to be displayed to users. [CHAR LIMIT=50] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_log_uploader_name" translatable="false">Research Uploader Service</string>
-
- <!-- Name for the research replaying service to be displayed to users. [CHAR LIMIT=50] -->
- <!-- TODO: remove translatable=false attribute once text is stable -->
- <string name="research_log_replayer_name" translatable="false">Research Replayer Service</string>
<!-- Preference for input language selection -->
<string name="select_language">Input languages</string>
@@ -238,11 +178,6 @@
<!-- Inform the user that a particular language has an available dictionary -->
<string name="has_dictionary">Dictionary available</string>
- <!-- Preferences item for enabling to send user statistics for development only diagnostics -->
- <string name="prefs_enable_log">Enable user feedback</string>
- <!-- Description for enabling to send user statistics for development only diagnostics -->
- <string name="prefs_description_log">Help improve this input method editor by automatically sending usage statistics and crash reports</string>
-
<!-- Title of the item to change the keyboard theme [CHAR LIMIT=20]-->
<string name="keyboard_layout">Keyboard theme</string>
@@ -390,8 +325,6 @@ mobile devices. [CHAR LIMIT=25] -->
<!-- Toast text to describe the same input style already exists [CHAR LIMIT=64]-->
<string name="custom_input_style_already_exists">"The same input style already exists: <xliff:g id="INPUT_STYLE_NAME" example="English (Dvorak)">%s</xliff:g>"</string>
- <!-- Title of an option for usability study mode -->
- <string name="prefs_usability_study_mode">Usability study mode</string>
<!-- Title of the settings for key long press delay [CHAR LIMIT=35] -->
<string name="prefs_key_longpress_timeout_settings">Key long press delay</string>
<!-- Title of the settings for keypress vibration duration [CHAR LIMIT=35] -->
@@ -416,14 +349,8 @@ mobile devices. [CHAR LIMIT=25] -->
<string name="read_external_dictionary_confirm_install_message">Really install this file for <xliff:g id="LANGUAGE_NAME" example="English">%s</xliff:g>?</string>
<!-- Title for an error dialog that contains the details of the error in the body [CHAR LIMIT=80] -->
<string name="error">There was an error</string>
- <!-- Title of the settings for dumpping contacts dictionary file [CHAR LIMIT=35] -->
- <string name="prefs_dump_contacts_dict">Dump contacts dictionary</string>
- <!-- Title of the settings for dumpping personal dictionary file [CHAR LIMIT=35] -->
- <string name="prefs_dump_user_dict">Dump personal dictionary</string>
- <!-- Title of the settings for dumpping user history dictionary file [CHAR LIMIT=35] -->
- <string name="prefs_dump_user_history_dict">Dump user history dictionary</string>
- <!-- Title of the settings for dumpping personalization dictionary file [CHAR LIMIT=35] -->
- <string name="prefs_dump_personalization_dict">Dump personalization dictionary</string>
+ <!-- Title of the settings group for dumpping dictionary files that have been created on the device [CHAR LIMIT=35] -->
+ <string name="prefs_dump_dynamic_dicts" translatable="false">Dump dictionary</string>
<!-- Title of the button to revert to the default value of the device in the settings dialog [CHAR LIMIT=15] -->
<string name="button_default">Default</string>
diff --git a/java/res/values/themes-common.xml b/java/res/values/themes-common.xml
index eb6cdd975..02a93ca82 100644
--- a/java/res/values/themes-common.xml
+++ b/java/res/values/themes-common.xml
@@ -109,23 +109,13 @@
<style name="KeyPreviewTextView" />
<!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
for instance delete button, need themed {@link KeyboardView} attributes. -->
- <style
- name="EmojiPalettesView"
- parent="KeyboardView"
- >
- <item name="emojiTabLabelColor">@color/emoji_tab_label_color_holo</item>
- </style>
+ <style name="EmojiPalettesView" />
<style name="MoreKeysKeyboard" />
<style
name="MoreKeysKeyboardView"
parent="MainKeyboardView" />
<style name="MoreKeysKeyboardContainer" />
- <style name="SuggestionStripView">
- <item name="suggestionsCountInStrip">@integer/config_suggestions_count_in_strip</item>
- <item name="centerSuggestionPercentile">@fraction/config_center_suggestion_percentile</item>
- <item name="maxMoreSuggestionsRow">@integer/config_max_more_suggestions_row</item>
- <item name="minMoreSuggestionsWidth">@fraction/config_min_more_suggestions_width</item>
- </style>
+ <style name="SuggestionStripView" />
<style name="SuggestionWord">
<item name="android:minWidth">@dimen/config_suggestion_min_width</item>
<item name="android:textSize">@dimen/config_suggestion_text_size</item>
@@ -134,9 +124,10 @@
<item name="android:paddingTop">0dp</item>
<item name="android:paddingRight">@dimen/config_suggestion_text_horizontal_padding</item>
<item name="android:paddingBottom">0dp</item>
- <!-- Provide a haptic feedback by ourselves based on the keyboard settings.
- We just need to ignore the system's haptic feedback settings. -->
+ <!-- Provide audio and haptic feedback by ourselves based on the keyboard settings.
+ We just need to ignore the system's audio and haptic feedback settings. -->
<item name="android:hapticFeedbackEnabled">false</item>
+ <item name="android:soundEffectsEnabled">false</item>
<item name="android:focusable">false</item>
<item name="android:clickable">false</item>
<item name="android:singleLine">true</item>
diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml
index 720eda9ce..319b4aeed 100644
--- a/java/res/values/themes-ics.xml
+++ b/java/res/values/themes-ics.xml
@@ -48,16 +48,19 @@
>
<item name="android:background">@drawable/keyboard_background_holo</item>
<item name="keyBackground">@drawable/btn_keyboard_key_ics</item>
+ <item name="functionalKeyBackground">@drawable/btn_keyboard_key_functional_ics</item>
+ <item name="spacebarBackground">@drawable/btn_keyboard_spacebar_ics</item>
<item name="keyTypeface">bold</item>
<item name="keyTextColor">@color/key_text_color_holo</item>
<item name="keyTextInactivatedColor">@color/key_text_inactivated_color_holo</item>
+ <item name="functionalTextColor">@color/key_text_color_holo</item>
<item name="keyHintLetterColor">@color/key_hint_letter_color_holo</item>
<item name="keyHintLabelColor">@color/key_hint_label_color_holo</item>
<item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_holo</item>
<item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_holo</item>
<item name="keyPreviewTextColor">@color/key_text_color_holo</item>
- <item name="keyTextShadowColor">@color/key_text_shadow_color_holo</item>
- <item name="keyTextShadowRadius">0.0</item>
+ <!-- A negative value to disable key text shadow layer. -->
+ <item name="keyTextShadowRadius">-1.0</item>
</style>
<style
name="MainKeyboardView.ICS"
@@ -68,11 +71,9 @@
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
<item name="gestureTrailColor">@color/highlight_color_ics</item>
<item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_ics</item>
- <item name="autoCorrectionSpacebarLedEnabled">false</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
<item name="languageOnSpacebarTextColor">@color/spacebar_text_color_holo</item>
+ <item name="languageOnSpacebarTextShadowRadius">1.0</item>
<item name="languageOnSpacebarTextShadowColor">@color/spacebar_text_shadow_color_holo</item>
- <item name="spacebarBackground">@drawable/btn_keyboard_spacebar_ics</item>
</style>
<style
name="KeyPreviewTextView.ICS"
@@ -84,10 +85,20 @@
for instance delete button, need themed {@link KeyboardView} attributes. -->
<style
name="EmojiPalettesView.ICS"
- parent="KeyboardView.ICS"
+ parent="MainKeyboardView.ICS"
>
- <item name="keyBackgroundEmojiFunctional">@drawable/btn_keyboard_key_functional_ics</item>
- <item name="emojiTabLabelColor">@color/emoji_tab_label_color_holo</item>
+ <item name="categoryIndicatorEnabled">true</item>
+ <item name="categoryIndicatorDrawable">@drawable/emoji_category_tab_selected_ics</item>
+ <item name="categoryIndicatorBackground">@drawable/emoji_category_tab_unselected_holo_dark</item>
+ <item name="categoryPageIndicatorColor">@color/highlight_color_ics</item>
+ <item name="categoryPageIndicatorBackground">@color/emoji_tab_page_indicator_background_holo</item>
+ <item name="iconEmojiRecentsTab">@drawable/ic_emoji_recents_holo_dark</item>
+ <item name="iconEmojiCategory1Tab">@drawable/ic_emoji_people_holo_dark</item>
+ <item name="iconEmojiCategory2Tab">@drawable/ic_emoji_objects_holo_dark</item>
+ <item name="iconEmojiCategory3Tab">@drawable/ic_emoji_nature_holo_dark</item>
+ <item name="iconEmojiCategory4Tab">@drawable/ic_emoji_places_holo_dark</item>
+ <item name="iconEmojiCategory5Tab">@drawable/ic_emoji_symbols_holo_dark</item>
+ <item name="iconEmojiCategory6Tab">@drawable/ic_emoji_emoticons_holo_dark</item>
</style>
<style
name="MoreKeysKeyboard.ICS"
@@ -109,8 +120,12 @@
</style>
<style
name="SuggestionStripView.ICS"
- parent="SuggestionStripView"
+ parent="KeyboardView.ICS"
>
+ <item name="suggestionsCountInStrip">@integer/config_suggestions_count_in_strip</item>
+ <item name="centerSuggestionPercentile">@fraction/config_center_suggestion_percentile</item>
+ <item name="maxMoreSuggestionsRow">@integer/config_max_more_suggestions_row</item>
+ <item name="minMoreSuggestionsWidth">@fraction/config_min_more_suggestions_width</item>
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
<item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item>
<item name="colorValidTypedWord">@color/typed_word_color_ics</item>
diff --git a/java/res/values/themes-klp.xml b/java/res/values/themes-klp.xml
index 830527171..208723dd3 100644
--- a/java/res/values/themes-klp.xml
+++ b/java/res/values/themes-klp.xml
@@ -48,16 +48,19 @@
>
<item name="android:background">@drawable/keyboard_background_holo</item>
<item name="keyBackground">@drawable/btn_keyboard_key_klp</item>
+ <item name="functionalKeyBackground">@drawable/btn_keyboard_key_functional_klp</item>
+ <item name="spacebarBackground">@drawable/btn_keyboard_spacebar_klp</item>
<item name="keyTypeface">bold</item>
<item name="keyTextColor">@color/key_text_color_holo</item>
<item name="keyTextInactivatedColor">@color/key_text_inactivated_color_holo</item>
+ <item name="functionalTextColor">@color/key_text_color_holo</item>
<item name="keyHintLetterColor">@color/key_hint_letter_color_holo</item>
<item name="keyHintLabelColor">@color/key_hint_label_color_holo</item>
<item name="keyShiftedLetterHintInactivatedColor">@color/key_shifted_letter_hint_inactivated_color_holo</item>
<item name="keyShiftedLetterHintActivatedColor">@color/key_shifted_letter_hint_activated_color_holo</item>
<item name="keyPreviewTextColor">@color/key_text_color_holo</item>
- <item name="keyTextShadowColor">@color/key_text_shadow_color_holo</item>
- <item name="keyTextShadowRadius">0.0</item>
+ <!-- A negative value to disable key text shadow layer. -->
+ <item name="keyTextShadowRadius">-1.0</item>
</style>
<style
name="MainKeyboardView.KLP"
@@ -68,11 +71,9 @@
<item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_holo</item>
<item name="gestureTrailColor">@color/highlight_color_klp</item>
<item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_klp</item>
- <item name="autoCorrectionSpacebarLedEnabled">false</item>
- <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item>
<item name="languageOnSpacebarTextColor">@color/spacebar_text_color_holo</item>
+ <item name="languageOnSpacebarTextShadowRadius">1.0</item>
<item name="languageOnSpacebarTextShadowColor">@color/spacebar_text_shadow_color_holo</item>
- <item name="spacebarBackground">@drawable/btn_keyboard_spacebar_klp</item>
</style>
<style
name="KeyPreviewTextView.KLP"
@@ -84,10 +85,20 @@
for instance delete button, need themed {@link KeyboardView} attributes. -->
<style
name="EmojiPalettesView.KLP"
- parent="KeyboardView.KLP"
+ parent="MainKeyboardView.KLP"
>
- <item name="keyBackgroundEmojiFunctional">@drawable/btn_keyboard_key_functional_klp</item>
- <item name="emojiTabLabelColor">@color/emoji_tab_label_color_holo</item>
+ <item name="categoryIndicatorEnabled">true</item>
+ <item name="categoryIndicatorDrawable">@drawable/emoji_category_tab_selected_klp</item>
+ <item name="categoryIndicatorBackground">@drawable/emoji_category_tab_unselected_holo_dark</item>
+ <item name="categoryPageIndicatorColor">@color/highlight_color_klp</item>
+ <item name="categoryPageIndicatorBackground">@color/emoji_tab_page_indicator_background_holo</item>
+ <item name="iconEmojiRecentsTab">@drawable/ic_emoji_recents_holo_dark</item>
+ <item name="iconEmojiCategory1Tab">@drawable/ic_emoji_people_holo_dark</item>
+ <item name="iconEmojiCategory2Tab">@drawable/ic_emoji_objects_holo_dark</item>
+ <item name="iconEmojiCategory3Tab">@drawable/ic_emoji_nature_holo_dark</item>
+ <item name="iconEmojiCategory4Tab">@drawable/ic_emoji_places_holo_dark</item>
+ <item name="iconEmojiCategory5Tab">@drawable/ic_emoji_symbols_holo_dark</item>
+ <item name="iconEmojiCategory6Tab">@drawable/ic_emoji_emoticons_holo_dark</item>
</style>
<style
name="MoreKeysKeyboard.KLP"
@@ -109,8 +120,12 @@
</style>
<style
name="SuggestionStripView.KLP"
- parent="SuggestionStripView"
+ parent="KeyboardView.KLP"
>
+ <item name="suggestionsCountInStrip">@integer/config_suggestions_count_in_strip</item>
+ <item name="centerSuggestionPercentile">@fraction/config_center_suggestion_percentile</item>
+ <item name="maxMoreSuggestionsRow">@integer/config_max_more_suggestions_row</item>
+ <item name="minMoreSuggestionsWidth">@fraction/config_min_more_suggestions_width</item>
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>
<item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item>
<item name="colorValidTypedWord">@color/typed_word_color_klp</item>
diff --git a/java/res/values/themes-lxx-dark.xml b/java/res/values/themes-lxx-dark.xml
new file mode 100644
index 000000000..e9a295c67
--- /dev/null
+++ b/java/res/values/themes-lxx-dark.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+ <style name="KeyboardTheme.LXX_Dark" parent="KeyboardIcons.LXX_Dark">
+ <item name="keyboardStyle">@style/Keyboard.LXX_Dark</item>
+ <item name="keyboardViewStyle">@style/KeyboardView.LXX_Dark</item>
+ <item name="mainKeyboardViewStyle">@style/MainKeyboardView.LXX_Dark</item>
+ <item name="keyPreviewTextViewStyle">@style/KeyPreviewTextView.LXX_Dark</item>
+ <item name="emojiPalettesViewStyle">@style/EmojiPalettesView.LXX_Dark</item>
+ <item name="moreKeysKeyboardStyle">@style/MoreKeysKeyboard.LXX_Dark</item>
+ <item name="moreKeysKeyboardViewStyle">@style/MoreKeysKeyboardView.LXX_Dark</item>
+ <item name="suggestionStripViewStyle">@style/SuggestionStripView.LXX_Dark</item>
+ <item name="suggestionWordStyle">@style/SuggestionWord.LXX_Dark</item>
+ </style>
+ <style
+ name="Keyboard.LXX_Dark"
+ parent="Keyboard"
+ >
+ <!-- This should be aligned with KeyboardSwitcher.KEYBOARD_THEMES[] -->
+ <item name="themeId">3</item>
+ <item name="keyboardTopPadding">@fraction/config_keyboard_top_padding_holo</item>
+ <item name="keyboardBottomPadding">@fraction/config_keyboard_bottom_padding_holo</item>
+ <item name="horizontalGap">@fraction/config_key_horizontal_gap_holo</item>
+ <item name="verticalGap">@fraction/config_key_vertical_gap_holo</item>
+ <item name="touchPositionCorrectionData">@array/touch_position_correction_data_holo</item>
+ </style>
+ <style
+ name="KeyboardView.LXX_Dark"
+ parent="KeyboardView"
+ >
+ <item name="android:background">@color/keyboard_background_lxx_dark</item>
+ <item name="keyBackground">@drawable/btn_keyboard_key_lxx_dark</item>
+ <item name="functionalKeyBackground">@drawable/btn_keyboard_key_functional_lxx_dark</item>
+ <item name="spacebarBackground">@drawable/btn_keyboard_spacebar_lxx_dark</item>
+ <item name="spacebarIconWidthRatio">0.9</item>
+ <item name="keyTypeface">normal</item>
+ <item name="keyTextColor">@color/key_text_color_lxx_dark</item>
+ <item name="keyTextInactivatedColor">@color/key_text_inactive_color_lxx_dark</item>
+ <item name="functionalTextColor">@color/key_hint_letter_color_lxx_dark</item>
+ <item name="keyHintLetterColor">@color/key_hint_letter_color_lxx_dark</item>
+ <item name="keyHintLabelColor">@color/key_text_inactive_color_lxx_dark</item>
+ <item name="keyShiftedLetterHintInactivatedColor">@color/key_text_inactive_color_lxx_dark</item>
+ <item name="keyShiftedLetterHintActivatedColor">@color/key_text_color_lxx_dark</item>
+ <item name="keyPreviewTextColor">@color/key_text_color_lxx_dark</item>
+ <!-- A negative value to disable key text shadow layer. -->
+ <item name="keyTextShadowRadius">-1.0</item>
+ </style>
+ <style
+ name="MainKeyboardView.LXX_Dark"
+ parent="KeyboardView.LXX_Dark"
+ >
+ <item name="keyPreviewOffset">@dimen/config_key_preview_offset_holo</item>
+ <item name="gestureFloatingPreviewTextColor">@color/highlight_color_lxx_dark</item>
+ <item name="gestureFloatingPreviewColor">@color/gesture_floating_preview_color_lxx_dark</item>
+ <item name="gestureTrailColor">@color/highlight_color_lxx_dark</item>
+ <item name="slidingKeyInputPreviewColor">@color/highlight_translucent_color_lxx_dark</item>
+ <item name="languageOnSpacebarTextColor">@color/key_text_inactive_color_lxx_dark</item>
+ <!-- A negative value to disable text shadow layer. -->
+ <item name="languageOnSpacebarTextShadowRadius">-1.0</item>
+ </style>
+ <style
+ name="KeyPreviewTextView.LXX_Dark"
+ parent="KeyPreviewTextView"
+ >
+ <item name="android:background">@drawable/keyboard_key_feedback_lxx_dark</item>
+ </style>
+ <!-- Though {@link EmojiPalettesView} doesn't extend {@link KeyboardView}, some views inside it,
+ for instance delete button, need themed {@link KeyboardView} attributes. -->
+ <style
+ name="EmojiPalettesView.LXX_Dark"
+ parent="MainKeyboardView.LXX_Dark"
+ >
+ <item name="categoryIndicatorEnabled">false</item>
+ <item name="categoryPageIndicatorColor">@color/highlight_color_lxx_dark</item>
+ <item name="categoryPageIndicatorBackground">@color/emoji_tab_page_indicator_background_lxx_dark</item>
+ <!-- TODO: Update those icons to LXX_Dark theme. -->
+ <item name="iconEmojiRecentsTab">@drawable/ic_emoji_recents_holo_dark</item>
+ <item name="iconEmojiCategory1Tab">@drawable/ic_emoji_people_holo_dark</item>
+ <item name="iconEmojiCategory2Tab">@drawable/ic_emoji_objects_holo_dark</item>
+ <item name="iconEmojiCategory3Tab">@drawable/ic_emoji_nature_holo_dark</item>
+ <item name="iconEmojiCategory4Tab">@drawable/ic_emoji_places_holo_dark</item>
+ <item name="iconEmojiCategory5Tab">@drawable/ic_emoji_symbols_holo_dark</item>
+ <item name="iconEmojiCategory6Tab">@drawable/ic_emoji_emoticons_holo_dark</item>
+ </style>
+ <style
+ name="MoreKeysKeyboard.LXX_Dark"
+ parent="Keyboard.LXX_Dark"
+ >
+ <item name="keyboardTopPadding">0%p</item>
+ <item name="keyboardBottomPadding">0%p</item>
+ <item name="horizontalGap">0%p</item>
+ <item name="touchPositionCorrectionData">@null</item>
+ </style>
+ <style
+ name="MoreKeysKeyboardView.LXX_Dark"
+ parent="KeyboardView.LXX_Dark"
+ >
+ <item name="android:background">@drawable/keyboard_popup_panel_background_lxx_dark</item>
+ <!-- Reuse KLP key background -->
+ <item name="keyBackground">@drawable/btn_keyboard_key_popup_klp</item>
+ <item name="keyTypeface">normal</item>
+ <item name="verticalCorrection">@dimen/config_more_keys_keyboard_vertical_correction_holo</item>
+ </style>
+ <style
+ name="SuggestionStripView.LXX_Dark"
+ parent="KeyboardView.LXX_Dark"
+ >
+ <item name="suggestionsCountInStrip">@integer/config_suggestions_count_in_strip</item>
+ <item name="centerSuggestionPercentile">@fraction/config_center_suggestion_percentile</item>
+ <item name="maxMoreSuggestionsRow">@integer/config_max_more_suggestions_row</item>
+ <item name="minMoreSuggestionsWidth">@fraction/config_min_more_suggestions_width</item>
+ <item name="android:background">@color/suggestions_strip_background_lxx_dark</item>
+ <item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item>
+ <item name="colorValidTypedWord">@color/typed_word_color_lxx_dark</item>
+ <item name="colorTypedWord">@color/typed_word_color_lxx_dark</item>
+ <item name="colorAutoCorrect">@color/highlight_color_lxx_dark</item>
+ <item name="colorSuggested">@color/suggested_word_color_lxx_dark</item>
+ <item name="alphaObsoleted">70%</item>
+ </style>
+ <style
+ name="SuggestionWord.LXX_Dark"
+ parent="SuggestionWord"
+ >
+ <item name="android:background">@drawable/btn_suggestion_lxx_dark</item>
+ <item name="android:textColor">@color/highlight_color_lxx_dark</item>
+ </style>
+</resources>
diff --git a/java/res/xml-sw600dp/key_shortcut.xml b/java/res/xml-sw600dp/key_comma.xml
index d24e81f73..67199e237 100644
--- a/java/res/xml-sw600dp/key_shortcut.xml
+++ b/java/res/xml-sw600dp/key_comma.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2012, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -21,33 +21,27 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
+ <!-- The table comma key which may have settings as popup key. -->
+ <!-- Kept as a separate file for cleaner overriding by an overlay. -->
+ <key-style
+ latin:styleName="baseTabletCommaKeyStyle"
+ latin:keySpec="!text/keyspec_tablet_comma"
+ latin:keyHintLabel="!text/keyhintlabel_tablet_comma"
+ latin:keyLabelFlags="hasPopupHint"
+ latin:parentStyle="hasShiftedLetterHintStyle" />
<switch>
<case
- latin:supportsSwitchingToShortcutIme="true"
- latin:clobberSettingsKey="false"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle"
- latin:keyLabelFlags="hasPopupHint|preserveCase"
- latin:moreKeys="!text/keyspec_settings" />
- </case>
- <case
- latin:supportsSwitchingToShortcutIme="true"
latin:clobberSettingsKey="true"
>
<Key
- latin:keyStyle="shortcutKeyStyle" />
+ latin:moreKeys="!text/morekeys_tablet_comma"
+ latin:keyStyle="baseTabletCommaKeyStyle" />
</case>
- <case
- latin:supportsSwitchingToShortcutIme="false"
- latin:clobberSettingsKey="false"
- >
- <Key
- latin:keyStyle="settingsKeyStyle" />
- </case>
- <!-- supportsSwitchingToShortcutIme="false" clobberSettingsKey="true" -->
+ <!-- clobberSettingsKey="false" -->
<default>
- <Spacer />
+ <Key
+ latin:moreKeys="!text/morekeys_tablet_comma,!text/keyspec_settings"
+ latin:keyStyle="baseTabletCommaKeyStyle" />
</default>
</switch>
</merge>
diff --git a/java/res/xml-sw600dp/keys_comma_period.xml b/java/res/xml-sw600dp/key_period.xml
index 23172cf18..d2909d82d 100644
--- a/java/res/xml-sw600dp/keys_comma_period.xml
+++ b/java/res/xml-sw600dp/key_period.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2013, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -21,13 +21,8 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <Key
- latin:keySpec="!text/keyspec_tablet_comma"
- latin:keyHintLabel="!text/keyhintlabel_tablet_comma"
- latin:keyLabelFlags="hasPopupHint"
- latin:moreKeys="!text/morekeys_tablet_comma"
- latin:backgroundType="functional"
- latin:keyStyle="hasShiftedLetterHintStyle" />
+ <!-- The table period key which may have different label depending on locale -->
+ <!-- Kept as a separate file for cleaner overriding by an overlay. -->
<switch>
<case
latin:languageCode="hi"
diff --git a/java/res/layout/emoji_keyboard_tab_label.xml b/java/res/xml-sw600dp/key_settings.xml
index 62c552dd8..45915e948 100644
--- a/java/res/layout/emoji_keyboard_tab_label.xml
+++ b/java/res/xml-sw600dp/key_settings.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2013, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,9 +18,19 @@
*/
-->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="0dip"
- android:layout_weight="1.0"
- android:layout_height="wrap_content"
- android:gravity="center"
-/>
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <switch>
+ <case
+ latin:clobberSettingsKey="false"
+ >
+ <Key
+ latin:keyStyle="settingsKeyStyle" />
+ </case>
+ <!-- clobberSettingsKey="true" -->
+ <default>
+ <Spacer />
+ </default>
+ </switch>
+</merge>
diff --git a/java/res/xml-sw600dp/key_styles_common.xml b/java/res/xml-sw600dp/key_styles_common.xml
index 3d5556fe5..7de276901 100644
--- a/java/res/xml-sw600dp/key_styles_common.xml
+++ b/java/res/xml-sw600dp/key_styles_common.xml
@@ -35,6 +35,9 @@
latin:keyLabelFlags="hasShiftedLetterHint" />
</default>
</switch>
+ <!-- Base key style for the key which may have settings key as more keys. -->
+ <include
+ latin:keyboardLayout="@xml/key_styles_settings" />
<!-- Functional key styles -->
<!-- Base style for shift key. A single space is used for dummy label in moreKeys. -->
<key-style
@@ -76,9 +79,10 @@
latin:backgroundType="functional" />
<include
latin:keyboardLayout="@xml/key_styles_enter" />
+ <!-- TODO: Currently there is no way to specify icon alignment per theme. -->
<key-style
latin:styleName="spaceKeyStyle"
- latin:keySpec=" |!code/key_space"
+ latin:keySpec="!icon/space_key|!code/key_space"
latin:keyActionFlags="noKeyPreview|enableLongPress" />
<!-- U+200C: ZERO WIDTH NON-JOINER
U+200D: ZERO WIDTH JOINER -->
@@ -140,7 +144,7 @@
</switch>
<key-style
latin:styleName="baseForLayoutSwitchKeyStyle"
- latin:keyLabelFlags="preserveCase"
+ latin:keyLabelFlags="preserveCase|followFunctionalTextColor"
latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
diff --git a/java/res/xml-sw600dp/key_styles_enter.xml b/java/res/xml-sw600dp/key_styles_enter.xml
index 0699e4527..740bf3543 100644
--- a/java/res/xml-sw600dp/key_styles_enter.xml
+++ b/java/res/xml-sw600dp/key_styles_enter.xml
@@ -100,9 +100,9 @@
<key-style
latin:styleName="defaultEnterKeyStyle"
latin:keySpec="!icon/enter_key|!code/key_enter"
- latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio"
+ latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="functional"
+ latin:backgroundType="action"
latin:parentStyle="navigateMoreKeysStyle" />
<switch>
<!-- Shift + Enter in textMultiLine field. -->
@@ -117,10 +117,29 @@
</case>
<case
latin:imeAction="actionGo"
+ latin:isIconDefined="go_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/go_key|!code/key_enter"
+ latin:backgroundType="action"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionGo"
>
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_go_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionNext"
+ latin:isIconDefined="next_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/next_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -130,6 +149,15 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_next_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionPrevious"
+ latin:isIconDefined="previous_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/previous_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -139,6 +167,15 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_previous_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionDone"
+ latin:isIconDefined="done_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/done_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -148,6 +185,15 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_done_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionSend"
+ latin:isIconDefined="send_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/send_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -157,11 +203,11 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_send_key|!code/key_enter"
- latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<case
latin:imeAction="actionSearch"
+ latin:isIconDefined="search_key"
>
<key-style
latin:styleName="enterKeyStyle"
@@ -170,13 +216,20 @@
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<case
+ latin:imeAction="actionSearch"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!text/label_search_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
latin:imeAction="actionCustomLabel"
>
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="dummy_label|!code/key_enter"
latin:keyLabelFlags="fromCustomActionLabel"
- latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<!-- imeAction is either actionNone or actionUnspecified. -->
diff --git a/java/res/xml-sw600dp/row_dvorak4.xml b/java/res/xml-sw600dp/row_dvorak4.xml
index 2ba6a491b..ab2b5603d 100644
--- a/java/res/xml-sw600dp/row_dvorak4.xml
+++ b/java/res/xml-sw600dp/row_dvorak4.xml
@@ -29,20 +29,20 @@
latin:keyStyle="toSymbolKeyStyle"
latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/key_shortcut" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
+ latin:keyboardLayout="@xml/key_settings" />
+ <Key
+ latin:keySpec="_"
+ latin:keyHintLabel="-"
+ latin:moreKeys="-"
+ latin:keyStyle="hasShiftedLetterHintStyle" />
<include
latin:keyXPos="28.0%p"
latin:keyboardLayout="@xml/key_space_5kw"
latin:backgroundType="normal" />
<include
+ latin:keyboardLayout="@xml/key_f1" />
+ <include
latin:keyboardLayout="@xml/key_question_exclamation" />
- <Key
- latin:keySpec="-"
- latin:keyHintLabel="_"
- latin:moreKeys="_"
- latin:keyStyle="hasShiftedLetterHintStyle" />
<include
latin:keyboardLayout="@xml/key_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/row_pcqwerty5.xml b/java/res/xml-sw600dp/row_pcqwerty5.xml
index 52b581ae6..ac07f11c2 100644
--- a/java/res/xml-sw600dp/row_pcqwerty5.xml
+++ b/java/res/xml-sw600dp/row_pcqwerty5.xml
@@ -26,7 +26,7 @@
>
<include
latin:keyWidth="9.0%p"
- latin:keyboardLayout="@xml/key_shortcut" />
+ latin:keyboardLayout="@xml/key_settings" />
<switch>
<case
latin:languageSwitchKeyEnabled="true"
diff --git a/java/res/xml-sw600dp/row_qwerty4.xml b/java/res/xml-sw600dp/row_qwerty4.xml
index 7969dd8a5..0eb86f2d4 100644
--- a/java/res/xml-sw600dp/row_qwerty4.xml
+++ b/java/res/xml-sw600dp/row_qwerty4.xml
@@ -29,15 +29,18 @@
latin:keyStyle="toSymbolKeyStyle"
latin:keyWidth="10.0%p" />
<include
- latin:keyboardLayout="@xml/key_shortcut" />
- <include
- latin:keyboardLayout="@xml/key_f1" />
+ latin:keyboardLayout="@xml/key_comma" />
+ <Key
+ latin:keySpec="_" />
+ <!-- Space key. -->
<include
latin:keyXPos="28.0%p"
latin:keyboardLayout="@xml/key_space_5kw"
latin:backgroundType="normal" />
<include
- latin:keyboardLayout="@xml/keys_comma_period" />
+ latin:keyboardLayout="@xml/key_f1" />
+ <include
+ latin:keyboardLayout="@xml/key_period" />
<include
latin:keyboardLayout="@xml/key_f2" />
</Row>
diff --git a/java/res/xml-sw600dp/rows_marathi.xml b/java/res/xml-sw600dp/rows_marathi.xml
new file mode 100644
index 000000000..51dc7a2b9
--- /dev/null
+++ b/java/res/xml-sw600dp/rows_marathi.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="8.182%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_marathi1" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="8.182%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_marathi2" />
+ <Key
+ latin:keyStyle="enterKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <Row
+ latin:keyWidth="8.182%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_marathi3" />
+ <include
+ latin:keyboardLayout="@xml/keys_exclamation_question" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_sign_anusvara.xml b/java/res/xml-v16/keystyle_devanagari_sign_anusvara.xml
index 71439d68c..405aebc50 100644
--- a/java/res/xml-v16/keystyle_devanagari_sign_anusvara.xml
+++ b/java/res/xml-v16/keystyle_devanagari_sign_anusvara.xml
@@ -36,6 +36,15 @@
latin:styleName="moreKeysDevanagariSignAnusvara"
latin:moreKeys="&#x0903;,&#x0901;,&#x093C;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0903: "ः‍" DEVANAGARI SIGN VISARGA
+ U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignAnusvara"
+ latin:moreKeys="&#x0903;,&#x0901;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariSignAnusvara" />
diff --git a/java/res/xml-v16/keystyle_devanagari_sign_virama.xml b/java/res/xml-v16/keystyle_devanagari_sign_virama.xml
index 0c3a29b16..73248e4c2 100644
--- a/java/res/xml-v16/keystyle_devanagari_sign_virama.xml
+++ b/java/res/xml-v16/keystyle_devanagari_sign_virama.xml
@@ -34,6 +34,14 @@
latin:styleName="moreKeysDevanagariSignVirama"
latin:moreKeys="&#x094D;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0905: "अ" DEVANAGARI LETTER A -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignVirama"
+ latin:moreKeys="&#x0905;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariSignVirama" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml
index 5bb0351ec..cd07999b5 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_aa.xml
@@ -43,6 +43,14 @@
latin:styleName="moreKeysDevanagariVowelSignAa"
latin:moreKeys="&#x093E;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0906: "आ" DEVANAGARI LETTER AA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAa"
+ latin:moreKeys="&#x0906;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignAa" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml
index 8edf6eb1c..75a49b19d 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ai.xml
@@ -43,6 +43,14 @@
latin:moreKeys="&#x0948;,%" />
</case>
<case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0910: "ऐ" DEVANAGARI LETTER AI -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi"
+ latin:moreKeys="&#x0910;,%" />
+ </case>
+ <case
latin:keyboardLayoutSet="nepali_traditional"
>
<!-- U+0936/U+094D/U+0930: "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA -->
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml
index 212e058d1..26f1aca5a 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_au.xml
@@ -42,6 +42,14 @@
latin:styleName="moreKeysDevanagariVowelSignAu"
latin:moreKeys="&#x094C;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0914: "औ" DEVANAGARI LETTER AU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAu"
+ latin:moreKeys="&#x0914;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignAu" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_e.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_e.xml
index ef2c3f14b..ec056a380 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_e.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_e.xml
@@ -34,9 +34,23 @@
latin:styleName="moreKeysDevanagariVowelSignCandraE"
latin:moreKeys="&#x0945;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+090D: "ऍ" DEVANAGARI LETTER CANDRA E -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignCandraE"
+ latin:moreKeys="&#x090D;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignCandraE" />
</default>
</switch>
+ <!-- U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignCandraE"
+ latin:parentStyle="moreKeysDevanagariVowelSignCandraE"
+ latin:keySpec="&#x0945;"
+ latin:keyLabelFlags="fontNormal" />
</merge>
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_o.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_o.xml
index ac01d37b7..fb4d4eb17 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_o.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_candra_o.xml
@@ -34,6 +34,14 @@
latin:styleName="moreKeysDevanagariVowelSignCandraO"
latin:moreKeys="&#x0949;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0911: "ऑ" DEVANAGARI LETTER CANDRA O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignCandraO"
+ latin:moreKeys="&#x0911;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignCandraO" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml
index 77d6eb5e0..965bccbd2 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_e.xml
@@ -43,6 +43,14 @@
latin:moreKeys="&#x0947;" />
</case>
<case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+090F: "ए" DEVANAGARI LETTER SHORT E -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE"
+ latin:moreKeys="&#x090F;" />
+ </case>
+ <case
latin:keyboardLayoutSet="nepali_traditional"
>
<!-- U+0903: "ः‍" DEVANAGARI SIGN VISARGA
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml
index d79447be5..ec71c4dcd 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_i.xml
@@ -42,6 +42,14 @@
latin:styleName="moreKeysDevanagariVowelSignI"
latin:moreKeys="&#x093F;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0907: "इ" DEVANAGARI LETTER I -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignI"
+ latin:moreKeys="&#x0907;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignI" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml
index 0e10f3172..9a9f9158c 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_ii.xml
@@ -42,6 +42,14 @@
latin:styleName="moreKeysDevanagariVowelSignIi"
latin:moreKeys="&#x0940;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0908: "ई" DEVANAGARI LETTER II -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignIi"
+ latin:moreKeys="&#x0908;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignIi" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml
index 47ca906ce..77389c22d 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_o.xml
@@ -44,6 +44,14 @@
latin:styleName="moreKeysDevanagariVowelSignO"
latin:moreKeys="&#x094B;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0913: "ओ" DEVANAGARI LETTER O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignO"
+ latin:moreKeys="&#x0913;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignO" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml
index 694e4abe7..e2167bf24 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_u.xml
@@ -43,6 +43,14 @@
latin:styleName="moreKeysDevanagariVowelSignU"
latin:moreKeys="&#x0941;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0909: "उ" DEVANAGARI LETTER U -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignU"
+ latin:moreKeys="&#x0909;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignU" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml
index f17489e3a..745236816 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_uu.xml
@@ -43,6 +43,14 @@
latin:styleName="moreKeysDevanagariVowelSignUu"
latin:moreKeys="&#x0942;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+090A: "ऊ" DEVANAGARI LETTER UU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignUu"
+ latin:moreKeys="&#x090A;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignUu" />
diff --git a/java/res/xml-v16/keystyle_devanagari_vowel_sign_vocalic_r.xml b/java/res/xml-v16/keystyle_devanagari_vowel_sign_vocalic_r.xml
index 27098466d..9c930d348 100644
--- a/java/res/xml-v16/keystyle_devanagari_vowel_sign_vocalic_r.xml
+++ b/java/res/xml-v16/keystyle_devanagari_vowel_sign_vocalic_r.xml
@@ -44,6 +44,16 @@
latin:moreKeys="&#x090B;,&#x0943;" />
</case>
<case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0931: "ऱ" DEVANAGARI LETTER RRA
+ U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
+ U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR"
+ latin:moreKeys="&#x0931;,&#x090B;,&#x0943;" />
+ </case>
+ <case
latin:keyboardLayoutSet="nepali_traditional"
>
<!-- U+0913: "ओ" DEVANAGARI LETTER O -->
diff --git a/java/res/xml/keys_comma_period_symbols.xml b/java/res/xml/kbd_marathi.xml
index 843595c27..4328cd6d3 100644
--- a/java/res/xml/keys_comma_period_symbols.xml
+++ b/java/res/xml/kbd_marathi.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2013, The Android Open Source Project
+** Copyright 2014, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -18,13 +18,9 @@
*/
-->
-<merge
+<Keyboard
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <Key
- latin:keySpec="!text/keyspec_comma" />
- <!-- U+2026: "…" HORIZONTAL ELLIPSIS -->
- <Key
- latin:keySpec="."
- latin:moreKeys="&#x2026;" />
-</merge>
+ <include
+ latin:keyboardLayout="@xml/rows_marathi" />
+</Keyboard>
diff --git a/java/res/xml/key_f1.xml b/java/res/xml/key_f1.xml
index c96ddcac1..7bd7385a1 100644
--- a/java/res/xml/key_f1.xml
+++ b/java/res/xml/key_f1.xml
@@ -27,37 +27,20 @@
>
<Key
latin:keySpec="/"
- latin:keyStyle="f1MoreKeysStyle" />
+ latin:keyStyle="settingsMoreKeysStyle" />
</case>
<case
latin:mode="email"
>
<Key
latin:keySpec="\@"
- latin:keyStyle="f1MoreKeysStyle" />
+ latin:keyStyle="settingsMoreKeysStyle" />
</case>
- <case
- latin:supportsSwitchingToShortcutIme="false"
- >
- <Key
- latin:keySpec="!text/keyspec_comma"
- latin:keyLabelFlags="hasPopupHint"
- latin:keyStyle="f1MoreKeysStyle" />
- </case>
- <!-- latin:supportsSwitchingToShortcutIme="true" -->
- <case
- latin:hasShortcutKey="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle" />
- </case>
- <!-- latin:hasShortcutKey="false" -->
<default>
<Key
latin:keySpec="!text/keyspec_comma"
latin:keyLabelFlags="hasPopupHint"
- latin:additionalMoreKeys="!text/keyspec_shortcut"
- latin:keyStyle="f1MoreKeysStyle" />
+ latin:keyStyle="settingsMoreKeysStyle" />
</default>
</switch>
</merge>
diff --git a/java/res/xml/key_styles_common.xml b/java/res/xml/key_styles_common.xml
index 78e030132..8b3bb2e5c 100644
--- a/java/res/xml/key_styles_common.xml
+++ b/java/res/xml/key_styles_common.xml
@@ -35,9 +35,9 @@
latin:keyLabelFlags="hasShiftedLetterHint" />
</default>
</switch>
- <!-- Base key style for the key which may have settings or tab key as popup key. -->
+ <!-- Base key style for the key which may have settings key as more keys. -->
<include
- latin:keyboardLayout="@xml/key_styles_f1" />
+ latin:keyboardLayout="@xml/key_styles_settings" />
<!-- Functional key styles -->
<!-- Base style for shift key. A single space is used for dummy label in moreKeys. -->
<key-style
@@ -82,12 +82,13 @@
latin:styleName="emojiKeyStyle"
latin:keySpec="!icon/emoji_key|!code/key_emoji"
latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="functional" />
+ latin:backgroundType="action" />
<include
latin:keyboardLayout="@xml/key_styles_enter" />
+ <!-- TODO: Currently there is no way to specify icon alignment per theme. -->
<key-style
latin:styleName="spaceKeyStyle"
- latin:keySpec=" |!code/key_space"
+ latin:keySpec="!icon/space_key|!code/key_space"
latin:keyActionFlags="noKeyPreview|enableLongPress" />
<!-- U+200C: ZERO WIDTH NON-JOINER
U+200D: ZERO WIDTH JOINER -->
@@ -103,7 +104,7 @@
latin:keyIconDisabled="!icon/shortcut_key_disabled"
latin:keyActionFlags="noKeyPreview|altCodeWhileTyping"
latin:altCode="!code/key_space"
- latin:parentStyle="f1MoreKeysStyle" />
+ latin:parentStyle="settingsMoreKeysStyle" />
<key-style
latin:styleName="settingsKeyStyle"
latin:keySpec="!icon/settings_key|!code/key_settings"
@@ -128,7 +129,7 @@
latin:keyIconPreview="!icon/tab_key_preview" />
<key-style
latin:styleName="baseForLayoutSwitchKeyStyle"
- latin:keyLabelFlags="preserveCase"
+ latin:keyLabelFlags="preserveCase|followFunctionalTextColor"
latin:keyActionFlags="noKeyPreview"
latin:backgroundType="functional" />
<key-style
diff --git a/java/res/xml/key_styles_enter.xml b/java/res/xml/key_styles_enter.xml
index acb27abb1..50530e1bf 100644
--- a/java/res/xml/key_styles_enter.xml
+++ b/java/res/xml/key_styles_enter.xml
@@ -255,9 +255,9 @@
<!-- Enter key style -->
<key-style
latin:styleName="defaultEnterKeyStyle"
- latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio"
+ latin:keyLabelFlags="preserveCase|autoXScale|followKeyLabelRatio|followFunctionalTextColor"
latin:keyActionFlags="noKeyPreview"
- latin:backgroundType="functional"
+ latin:backgroundType="action"
latin:parentStyle="navigateMoreKeysStyle" />
<key-style
latin:styleName="shiftEnterKeyStyle"
@@ -284,10 +284,29 @@
</case>
<case
latin:imeAction="actionGo"
+ latin:isIconDefined="go_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/go_key|!code/key_enter"
+ latin:backgroundType="action"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionGo"
>
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_go_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionNext"
+ latin:isIconDefined="next_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/next_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -297,6 +316,15 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_next_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionPrevious"
+ latin:isIconDefined="previous_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/previous_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -306,6 +334,15 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_previous_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionDone"
+ latin:isIconDefined="done_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/done_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -315,6 +352,15 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_done_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
+ latin:imeAction="actionSend"
+ latin:isIconDefined="send_key"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!icon/send_key|!code/key_enter"
latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
@@ -324,11 +370,11 @@
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="!text/label_send_key|!code/key_enter"
- latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<case
latin:imeAction="actionSearch"
+ latin:isIconDefined="search_key"
>
<key-style
latin:styleName="enterKeyStyle"
@@ -337,13 +383,20 @@
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<case
+ latin:imeAction="actionSearch"
+ >
+ <key-style
+ latin:styleName="enterKeyStyle"
+ latin:keySpec="!text/label_search_key|!code/key_enter"
+ latin:parentStyle="defaultEnterKeyStyle" />
+ </case>
+ <case
latin:imeAction="actionCustomLabel"
>
<key-style
latin:styleName="enterKeyStyle"
latin:keySpec="dummy_label|!code/key_enter"
latin:keyLabelFlags="fromCustomActionLabel"
- latin:backgroundType="action"
latin:parentStyle="defaultEnterKeyStyle" />
</case>
<!-- imeAction is either actionNone or actionUnspecified. -->
diff --git a/java/res/xml/keys_less_greater.xml b/java/res/xml/key_styles_less_greater.xml
index 778de02a1..db4c7984b 100644
--- a/java/res/xml/keys_less_greater.xml
+++ b/java/res/xml/key_styles_less_greater.xml
@@ -21,25 +21,31 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
+ <!-- The less and greater keys' style which may have different label depending on locale. -->
+ <!-- Kept as a separate file for cleaner overriding by an overlay. -->
<switch>
<case
latin:languageCode="fa"
>
- <Key
+ <key-style
+ latin:styleName="lessKeyStyle"
latin:keySpec="!text/keyspec_left_double_angle_quote"
latin:backgroundType="functional"
latin:moreKeys="!text/morekeys_less_than" />
- <Key
+ <key-style
+ latin:styleName="greaterKeyStyle"
latin:keySpec="!text/keyspec_right_double_angle_quote"
latin:backgroundType="functional"
latin:moreKeys="!text/morekeys_greater_than" />
</case>
<default>
- <Key
+ <key-style
+ latin:styleName="lessKeyStyle"
latin:keySpec="!text/keyspec_less_than"
latin:backgroundType="functional"
latin:moreKeys="!text/morekeys_less_than" />
- <Key
+ <key-style
+ latin:styleName="greaterKeyStyle"
latin:keySpec="!text/keyspec_greater_than"
latin:backgroundType="functional"
latin:moreKeys="!text/morekeys_greater_than" />
diff --git a/java/res/xml/key_styles_number.xml b/java/res/xml/key_styles_number.xml
index 5c108cf58..8a76fe397 100644
--- a/java/res/xml/key_styles_number.xml
+++ b/java/res/xml/key_styles_number.xml
@@ -30,7 +30,7 @@
latin:parentStyle="numKeyBaseStyle" />
<key-style
latin:styleName="numModeKeyStyle"
- latin:keyLabelFlags="fontNormal|followKeyLetterRatio"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio|followFunctionalTextColor"
latin:parentStyle="numKeyBaseStyle" />
<key-style
latin:styleName="numFunctionalKeyStyle"
@@ -120,6 +120,7 @@
<key-style
latin:styleName="numSpaceKeyStyle"
latin:keySpec="!icon/space_key_for_number_layout|!code/key_space"
+ latin:keyLabelFlags="alignButtom"
latin:keyActionFlags="enableLongPress"
latin:parentStyle="numKeyBaseStyle" />
<!-- Override defaultEnterKeyStyle in key_styles_enter.xml -->
diff --git a/java/res/xml/key_styles_f1.xml b/java/res/xml/key_styles_settings.xml
index 8a07827fa..956b40235 100644
--- a/java/res/xml/key_styles_f1.xml
+++ b/java/res/xml/key_styles_settings.xml
@@ -21,20 +21,20 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
- <!-- Base key style for the key which may have settings or tab key as popup key. -->
+ <!-- Base key style for the key which may have settings key as more keys. -->
<!-- Kept as a separate file for cleaner overriding by an overlay. -->
<switch>
<case
latin:clobberSettingsKey="true"
>
<key-style
- latin:styleName="f1MoreKeysStyle"
+ latin:styleName="settingsMoreKeysStyle"
latin:backgroundType="functional" />
</case>
<!-- clobberSettingsKey="false" -->
<default>
<key-style
- latin:styleName="f1MoreKeysStyle"
+ latin:styleName="settingsMoreKeysStyle"
latin:keyLabelFlags="hasPopupHint"
latin:moreKeys="!text/keyspec_settings"
latin:backgroundType="functional" />
diff --git a/java/res/xml/keyboard_layout_set_marathi.xml b/java/res/xml/keyboard_layout_set_marathi.xml
new file mode 100644
index 000000000..e5c68e7ce
--- /dev/null
+++ b/java/res/xml/keyboard_layout_set_marathi.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<KeyboardLayoutSet
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin">
+ <Element
+ latin:elementName="alphabet"
+ latin:elementKeyboard="@xml/kbd_marathi"
+ latin:enableProximityCharsCorrection="true" />
+ <Element
+ latin:elementName="symbols"
+ latin:elementKeyboard="@xml/kbd_symbols" />
+ <Element
+ latin:elementName="symbolsShifted"
+ latin:elementKeyboard="@xml/kbd_symbols_shift" />
+ <Element
+ latin:elementName="phone"
+ latin:elementKeyboard="@xml/kbd_phone" />
+ <Element
+ latin:elementName="phoneSymbols"
+ latin:elementKeyboard="@xml/kbd_phone_symbols" />
+ <Element
+ latin:elementName="number"
+ latin:elementKeyboard="@xml/kbd_number" />
+</KeyboardLayoutSet>
diff --git a/java/res/xml/keystyle_devanagari_sign_anusvara.xml b/java/res/xml/keystyle_devanagari_sign_anusvara.xml
index 6dc9b7e3a..a7e421d17 100644
--- a/java/res/xml/keystyle_devanagari_sign_anusvara.xml
+++ b/java/res/xml/keystyle_devanagari_sign_anusvara.xml
@@ -37,6 +37,16 @@
latin:styleName="moreKeysDevanagariSignAnusvara"
latin:moreKeys="&#x25CC;&#x0903;|&#x0903;,&#x25CC;&#x0901;|&#x0901;,&#x25CC;&#x093C;|&#x093C;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0903: "ः‍" DEVANAGARI SIGN VISARGA
+ U+0901: "ँ" DEVANAGARI SIGN CANDRABINDU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignAnusvara"
+ latin:moreKeys="&#x25CC;&#x0903;|&#x0903;,&#x25CC;&#x0901;|&#x0901;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariSignAnusvara" />
diff --git a/java/res/xml/keystyle_devanagari_sign_virama.xml b/java/res/xml/keystyle_devanagari_sign_virama.xml
index 96506e2fc..58dd42a2a 100644
--- a/java/res/xml/keystyle_devanagari_sign_virama.xml
+++ b/java/res/xml/keystyle_devanagari_sign_virama.xml
@@ -35,6 +35,14 @@
latin:styleName="moreKeysDevanagariSignVirama"
latin:moreKeys="&#x25CC;&#x094D;|&#x094D;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0905: "अ" DEVANAGARI LETTER A -->
+ <key-style
+ latin:styleName="moreKeysDevanagariSignVirama"
+ latin:moreKeys="&#x0905;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariSignVirama" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml b/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml
index 4b876505a..1a60ca22f 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_aa.xml
@@ -45,6 +45,14 @@
latin:styleName="moreKeysDevanagariVowelSignAa"
latin:moreKeys="&#x25CC;&#x093E;|&#x093E;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0906: "आ" DEVANAGARI LETTER AA -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAa"
+ latin:moreKeys="&#x0906;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignAa" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml b/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml
index 050a7ce0e..e6b64e56c 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_ai.xml
@@ -45,6 +45,14 @@
latin:moreKeys="&#x25CC;&#x0948;|&#x0948;,%" />
</case>
<case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0910: "ऐ" DEVANAGARI LETTER AI -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAi"
+ latin:moreKeys="&#x0910;,%" />
+ </case>
+ <case
latin:keyboardLayoutSet="nepali_traditional"
>
<!-- U+0936/U+094D/U+0930: "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA -->
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_au.xml b/java/res/xml/keystyle_devanagari_vowel_sign_au.xml
index 49e67da38..3e129ec87 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_au.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_au.xml
@@ -44,6 +44,14 @@
latin:styleName="moreKeysDevanagariVowelSignAu"
latin:moreKeys="&#x25CC;&#x094C;|&#x094C;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0914: "औ" DEVANAGARI LETTER AU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignAu"
+ latin:moreKeys="&#x0914;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignAu" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml b/java/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml
index 86f68d355..b7d0908e1 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_candra_e.xml
@@ -35,9 +35,24 @@
latin:styleName="moreKeysDevanagariVowelSignCandraE"
latin:moreKeys="&#x25CC;&#x0945;|&#x0945;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+090D: "ऍ" DEVANAGARI LETTER CANDRA E -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignCandraE"
+ latin:moreKeys="&#x090D;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignCandraE" />
</default>
</switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0945: "ॅ" DEVANAGARI VOWEL SIGN CANDRA E -->
+ <key-style
+ latin:styleName="baseKeyDevanagariVowelSignCandraE"
+ latin:parentStyle="moreKeysDevanagariVowelSignCandraE"
+ latin:keySpec="&#x25CC;&#x0945;|&#x0945;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
</merge>
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml b/java/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml
index fd711e049..861dd1a3d 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_candra_o.xml
@@ -35,6 +35,14 @@
latin:styleName="moreKeysDevanagariVowelSignCandraO"
latin:moreKeys="&#x25CC;&#x0949;|&#x0949;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0911: "ऑ" DEVANAGARI LETTER CANDRA O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignCandraO"
+ latin:moreKeys="&#x0911;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignCandraO" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_e.xml b/java/res/xml/keystyle_devanagari_vowel_sign_e.xml
index 88f6a74f4..95d85a91d 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_e.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_e.xml
@@ -45,6 +45,14 @@
latin:moreKeys="&#x25CC;&#x0947;|&#x0947;" />
</case>
<case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+090F: "ए" DEVANAGARI LETTER SHORT E -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignE"
+ latin:moreKeys="&#x090F;" />
+ </case>
+ <case
latin:keyboardLayoutSet="nepali_traditional"
>
<!-- U+25CC: "◌" DOTTED CIRCLE
@@ -59,6 +67,8 @@
latin:styleName="moreKeysDevanagariVowelSignE" />
</default>
</switch>
+ <!-- U+25CC: "◌" DOTTED CIRCLE
+ U+0947: "े" DEVANAGARI VOWEL SIGN E -->
<key-style
latin:styleName="baseKeyDevanagariVowelSignE"
latin:parentStyle="moreKeysDevanagariVowelSignE"
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_i.xml b/java/res/xml/keystyle_devanagari_vowel_sign_i.xml
index a84fdb4a9..5817be1c6 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_i.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_i.xml
@@ -44,6 +44,14 @@
latin:styleName="moreKeysDevanagariVowelSignI"
latin:moreKeys="&#x25CC;&#x093F;|&#x093F;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0907: "इ" DEVANAGARI LETTER I -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignI"
+ latin:moreKeys="&#x0907;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignI" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml b/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml
index 6f6eb0f15..a7863c65f 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_ii.xml
@@ -44,6 +44,14 @@
latin:styleName="moreKeysDevanagariVowelSignIi"
latin:moreKeys="&#x25CC;&#x0940;|&#x0940;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0908: "ई" DEVANAGARI LETTER II -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignIi"
+ latin:moreKeys="&#x0908;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignIi" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_o.xml b/java/res/xml/keystyle_devanagari_vowel_sign_o.xml
index 68b176a43..3dc874e1a 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_o.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_o.xml
@@ -46,6 +46,14 @@
latin:styleName="moreKeysDevanagariVowelSignO"
latin:moreKeys="&#x25CC;&#x094B;|&#x094B;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0913: "ओ" DEVANAGARI LETTER O -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignO"
+ latin:moreKeys="&#x0913;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignO" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_u.xml b/java/res/xml/keystyle_devanagari_vowel_sign_u.xml
index 7c058b174..226c11a06 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_u.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_u.xml
@@ -45,6 +45,14 @@
latin:styleName="moreKeysDevanagariVowelSignU"
latin:moreKeys="&#x25CC;&#x0941;|&#x0941;" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0909: "उ" DEVANAGARI LETTER U -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignU"
+ latin:moreKeys="&#x0909;" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignU" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml b/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml
index 73ab63c89..7a9f47d77 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_uu.xml
@@ -45,6 +45,14 @@
latin:styleName="moreKeysDevanagariVowelSignUu"
latin:moreKeys="&#x25CC;&#x0942;|&#x0942;,%" />
</case>
+ <case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+090A: "ऊ" DEVANAGARI LETTER UU -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignUu"
+ latin:moreKeys="&#x090A;,%" />
+ </case>
<default>
<key-style
latin:styleName="moreKeysDevanagariVowelSignUu" />
diff --git a/java/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml b/java/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml
index 29b083eb3..56b739642 100644
--- a/java/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml
+++ b/java/res/xml/keystyle_devanagari_vowel_sign_vocalic_r.xml
@@ -46,6 +46,17 @@
latin:moreKeys="&#x090B;,&#x25CC;&#x0943;|&#x0943;" />
</case>
<case
+ latin:keyboardLayoutSet="marathi"
+ >
+ <!-- U+0931: "ऱ" DEVANAGARI LETTER RRA
+ U+090B: "ऋ" DEVANAGARI LETTER VOCALIC R
+ U+25CC: "◌" DOTTED CIRCLE
+ U+0943: "ृ" DEVANAGARI VOWEL SIGN VOCALIC R -->
+ <key-style
+ latin:styleName="moreKeysDevanagariVowelSignVocalicR"
+ latin:moreKeys="&#x0931;,&#x090B;,&#x25CC;&#x0943;|&#x0943;" />
+ </case>
+ <case
latin:keyboardLayoutSet="nepali_traditional"
>
<!-- U+0913: "ओ" DEVANAGARI LETTER O -->
diff --git a/java/res/xml/method.xml b/java/res/xml/method.xml
index 28eceb8db..777a13d42 100644
--- a/java/res/xml/method.xml
+++ b/java/res/xml/method.xml
@@ -68,6 +68,7 @@
lv: Latvian/qwerty
mk: Macedonian/south_slavic
mn_MN: Mongolian (Mongolia)/mongolian
+ (mr_IN: Marathi (India)/marathi) # This is a preliminary keyboard layout.
ms_MY: Malay (Malaysia)/qwerty
(my_MM: Myanmar (Myanmar)/myanmar) # This is a preliminary keyboard layout.
nb: Norwegian Bokmål/nordic
@@ -331,6 +332,7 @@
/>
<!-- TODO: This hindi_compact keyboard is a preliminary layout.
This isn't based on the final specification. -->
+ <!--
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic_compact"
android:subtypeId="0xe49c89a1"
@@ -339,6 +341,7 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=hindi_compact,EmojiCapable"
android:isAsciiCapable="false"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x35b7526a"
@@ -477,6 +480,18 @@
android:imeSubtypeExtraValue="KeyboardLayoutSet=mongolian,EmojiCapable"
android:isAsciiCapable="false"
/>
+ <!-- TODO: This marathi keyboard is a preliminary layout.
+ This isn't based on the final specification. -->
+ <!--
+ <subtype android:icon="@drawable/ic_ime_switcher_dark"
+ android:label="@string/subtype_generic"
+ android:subtypeId="0x747b9f03"
+ android:imeSubtypeLocale="mr_IN"
+ android:imeSubtypeMode="keyboard"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=marathi,EmojiCapable"
+ android:isAsciiCapable="false"
+ />
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x84c87c61"
@@ -487,14 +502,16 @@
/>
<!-- TODO: This Myanmar keyboard is a preliminary layout.
This isn't based on the final specification. -->
+ <!--
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0xea266ea4"
android:imeSubtypeLocale="my_MM"
android:imeSubtypeMode="keyboard"
- android:imeSubtypeExtraValue="KeyboardLayoutSet=myanmar,EmojiCapable"
+ android:imeSubtypeExtraValue="KeyboardLayoutSet=myanmar,EmojiCapable,CombiningRules=MyanmarReordering"
android:isAsciiCapable="false"
/>
+ -->
<subtype android:icon="@drawable/ic_ime_switcher_dark"
android:label="@string/subtype_generic"
android:subtypeId="0x3f12ee14"
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 7d86dbd5d..0e9c16190 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -95,6 +95,12 @@
android:summary="@string/use_personalized_dicts_summary"
android:persistent="true"
android:defaultValue="true" />
+ <!-- title will be set programmatically to embed application name -->
+ <CheckBoxPreference
+ android:key="pref_enable_metrics_logging"
+ android:summary="@string/enable_metrics_logging_summary"
+ android:persistent="true"
+ android:defaultValue="true" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/gesture_typing_category"
@@ -153,17 +159,17 @@
android:defaultValue="true" />
<CheckBoxPreference
android:key="pref_include_other_imes_in_language_switch_list"
+ android:dependency="pref_show_language_switch_key"
android:title="@string/include_other_imes_in_language_switch_list"
android:summary="@string/include_other_imes_in_language_switch_list_summary"
android:persistent="true"
android:defaultValue="false" />
<ListPreference
- android:key="pref_keyboard_layout_20110916"
+ android:key="pref_keyboard_theme"
android:title="@string/keyboard_color_scheme"
android:persistent="true"
android:entryValues="@array/keyboard_theme_ids"
- android:entries="@array/keyboard_theme_names"
- android:defaultValue="@string/config_default_keyboard_theme_id" />
+ android:entries="@array/keyboard_theme_names" />
<PreferenceScreen
android:fragment="com.android.inputmethod.latin.settings.AdditionalSubtypeSettings"
android:key="custom_input_styles"
diff --git a/java/res/xml/prefs_for_debug.xml b/java/res/xml/prefs_for_debug.xml
index c333b0751..0bcc5cbe4 100644
--- a/java/res/xml/prefs_for_debug.xml
+++ b/java/res/xml/prefs_for_debug.xml
@@ -21,12 +21,6 @@
android:key="english_ime_debug_settings"
>
<CheckBoxPreference
- android:key="enable_logging"
- android:title="@string/prefs_enable_log"
- android:summary="@string/prefs_description_log"
- android:persistent="true"
- android:defaultValue="false" />
- <CheckBoxPreference
android:key="debug_mode"
android:title="@string/prefs_debug_mode"
android:persistent="true"
@@ -37,11 +31,6 @@
android:persistent="true"
android:defaultValue="false" />
<CheckBoxPreference
- android:key="usability_study_mode"
- android:title="@string/prefs_usability_study_mode"
- android:persistent="true"
- android:defaultValue="false" />
- <CheckBoxPreference
android:key="pref_sliding_key_input_preview"
android:title="@string/sliding_key_input_preview"
android:summary="@string/sliding_key_input_preview_summary"
@@ -72,16 +61,8 @@
<PreferenceScreen
android:key="read_external_dictionary"
android:title="@string/prefs_read_external_dictionary" />
- <PreferenceScreen
- android:key="dump_contacts_dict"
- android:title="@string/prefs_dump_contacts_dict" />
- <PreferenceScreen
- android:key="dump_user_dict"
- android:title="@string/prefs_dump_user_dict" />
- <PreferenceScreen
- android:key="dump_user_history_dict"
- android:title="@string/prefs_dump_user_history_dict" />
- <PreferenceScreen
- android:key="dump_personalization_dict"
- android:title="@string/prefs_dump_personalization_dict" />
+ <PreferenceCategory
+ android:key="pref_key_dump_dictionaries"
+ android:title="@string/prefs_dump_dynamic_dicts">
+ </PreferenceCategory>
</PreferenceScreen>
diff --git a/java/res/xml/row_dvorak4.xml b/java/res/xml/row_dvorak4.xml
index 91462cb9c..e7a3ee736 100644
--- a/java/res/xml/row_dvorak4.xml
+++ b/java/res/xml/row_dvorak4.xml
@@ -30,8 +30,7 @@
<Key
latin:keySpec="q"
latin:backgroundType="normal"
- latin:additionalMoreKeys="!text/keyspec_shortcut"
- latin:keyStyle="f1MoreKeysStyle" />
+ latin:keyStyle="settingsMoreKeysStyle" />
<include
latin:keyXPos="25%p"
latin:keyboardLayout="@xml/key_space_5kw" />
diff --git a/java/res/xml/row_pcqwerty5.xml b/java/res/xml/row_pcqwerty5.xml
index 3782763a8..32c5389cc 100644
--- a/java/res/xml/row_pcqwerty5.xml
+++ b/java/res/xml/row_pcqwerty5.xml
@@ -26,13 +26,6 @@
>
<switch>
<case
- latin:hasShortcutKey="true"
- >
- <Key
- latin:keyStyle="shortcutKeyStyle"
- latin:keyWidth="11.538%p" />
- </case>
- <case
latin:clobberSettingsKey="false"
>
<Key
diff --git a/java/res/xml/row_symbols4.xml b/java/res/xml/row_symbols4.xml
index 09f6b628c..2be03bd6d 100644
--- a/java/res/xml/row_symbols4.xml
+++ b/java/res/xml/row_symbols4.xml
@@ -20,11 +20,15 @@
<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
<Key
- latin:keySpec="_" />
+ latin:keySpec="!text/keyspec_comma" />
<Key
- latin:keySpec="/" />
+ latin:keySpec="_" />
<include
latin:keyboardLayout="@xml/key_space_symbols" />
- <include
- latin:keyboardLayout="@xml/keys_comma_period_symbols" />
+ <Key
+ latin:keySpec="/" />
+ <!-- U+2026: "…" HORIZONTAL ELLIPSIS -->
+ <Key
+ latin:keySpec="."
+ latin:moreKeys="&#x2026;" />
</merge>
diff --git a/java/res/xml/row_symbols_shift4.xml b/java/res/xml/row_symbols_shift4.xml
index f75575bc6..4fc63c2c5 100644
--- a/java/res/xml/row_symbols_shift4.xml
+++ b/java/res/xml/row_symbols_shift4.xml
@@ -18,9 +18,18 @@
*/
-->
<merge xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" >
-
- <include latin:keyboardLayout="@xml/keys_less_greater" />
+ <include
+ latin:keyboardLayout="@xml/key_styles_less_greater" />
+ <Key
+ latin:keySpec="!text/keyspec_comma" />
+ <Key
+ latin:keyStyle="lessKeyStyle" />
<include
latin:keyboardLayout="@xml/key_space_symbols" />
- <include latin:keyboardLayout="@xml/keys_comma_period_symbols" />
+ <Key
+ latin:keyStyle="greaterKeyStyle" />
+ <!-- U+2026: "…" HORIZONTAL ELLIPSIS -->
+ <Key
+ latin:keySpec="."
+ latin:moreKeys="&#x2026;" />
</merge>
diff --git a/java/res/xml/rowkeys_marathi1.xml b/java/res/xml/rowkeys_marathi1.xml
new file mode 100644
index 000000000..810e71e3c
--- /dev/null
+++ b/java/res/xml/rowkeys_marathi1.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_au" />
+ <!-- U+0967: "१" DEVANAGARI DIGIT ONE -->
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAu"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="&#x0967;,1" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ai" />
+ <!-- U+0968: "२" DEVANAGARI DIGIT TWO -->
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAi"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="&#x0968;,2" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_aa" />
+ <!-- U+0969: "३" DEVANAGARI DIGIT THREE -->
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignAa"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="&#x0969;,3" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_ii" />
+ <!-- U+096A: "४" DEVANAGARI DIGIT FOUR -->
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignIi"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="&#x096A;,4" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_uu" />
+ <!-- U+096B: "५" DEVANAGARI DIGIT FIVE -->
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignUu"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="&#x096B;,5" />
+ <!-- U+092C: "ब" DEVANAGARI LETTER BA
+ U+092D: "भ" DEVANAGARI LETTER BHA
+ U+096C: "६" DEVANAGARI DIGIT SIX -->
+ <Key
+ latin:keySpec="&#x092C;"
+ latin:moreKeys="&#x092D;,%"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="&#x096C;,6"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0939: "ह" DEVANAGARI LETTER HA
+ U+096D: "७" DEVANAGARI DIGIT SEVEN -->
+ <Key
+ latin:keySpec="&#x0939;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="&#x096D;,7"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0917: "ग" DEVANAGARI LETTER GA
+ U+0918: "घ" DEVANAGARI LETTER GHA
+ U+096E: "८" DEVANAGARI DIGIT EIGHT -->
+ <Key
+ latin:keySpec="&#x0917;"
+ latin:moreKeys="&#x0918;,%"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="&#x096E;,8"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0926: "द" DEVANAGARI LETTER DA
+ U+0927: "ध" DEVANAGARI LETTER DHA
+ U+096F: "९" DEVANAGARI DIGIT NINE -->
+ <Key
+ latin:keySpec="&#x0926;"
+ latin:moreKeys="&#x0927;,%"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="&#x096F;,9"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091C: "ज" DEVANAGARI LETTER JA
+ U+091D: "झ" DEVANAGARI LETTER JHA
+ U+091C/U+094D/U+091E: "ज्ञ" DEVANAGARI LETTER JA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER JHA -->
+ <Key
+ latin:keySpec="&#x091C;"
+ latin:moreKeys="&#x091D;,&#x091C;&#x094D;&#x091E;,%"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="&#x0966;,0"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0921: "ड" DEVANAGARI LETTER DDA
+ U+0922: "ढ" DEVANAGARI LETTER DDHA -->
+ <Key
+ latin:keySpec="&#x0921;"
+ latin:moreKeys="&#x0922;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml/rowkeys_marathi2.xml b/java/res/xml/rowkeys_marathi2.xml
new file mode 100644
index 000000000..f95091529
--- /dev/null
+++ b/java/res/xml/rowkeys_marathi2.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_o" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignO" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_e" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignE" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_virama" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignVirama" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_i" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignI" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_u" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignU" />
+ <!-- U+092A: "प" DEVANAGARI LETTER PA
+ U+092B: "फ" DEVANAGARI LETTER PHA -->
+ <Key
+ latin:keySpec="&#x092A;"
+ latin:moreKeys="&#x092B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_vocalic_r" />
+ <!-- U+0930: "र" DEVANAGARI LETTER RA -->
+ <Key
+ latin:keySpec="&#x0930;"
+ latin:keyStyle="moreKeysDevanagariVowelSignVocalicR"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0915: "क" DEVANAGARI LETTER KA
+ U+0916: "ख" DEVANAGARI LETTER KHA -->
+ <Key
+ latin:keySpec="&#x0915;"
+ latin:moreKeys="&#x0916;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0924: "त" DEVANAGARI LETTER TA
+ U+0925: "थ" DEVANAGARI LETTER THA
+ U+0924/U+094D/U+0930: "त्र" DEVANAGARI LETTER TA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA -->
+ <Key
+ latin:keySpec="&#x0924;"
+ latin:moreKeys="&#x0925;,&#x0924;&#x094D;&#x0930;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091A: "च" DEVANAGARI LETTER CA
+ U+091B: "छ" DEVANAGARI LETTER CHA -->
+ <Key
+ latin:keySpec="&#x091A;"
+ latin:moreKeys="&#x091B;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+091F: "ट" DEVANAGARI LETTER TTA
+ U+0920: "ठ" DEVANAGARI LETTER TTHA -->
+ <Key
+ latin:keySpec="&#x091F;"
+ latin:moreKeys="&#x0920;"
+ latin:keyLabelFlags="fontNormal" />
+</merge>
diff --git a/java/res/xml/rowkeys_marathi3.xml b/java/res/xml/rowkeys_marathi3.xml
new file mode 100644
index 000000000..17fc5ac77
--- /dev/null
+++ b/java/res/xml/rowkeys_marathi3.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_candra_o" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignCandraO" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_vowel_sign_candra_e" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariVowelSignCandraE" />
+ <!-- Because the font rendering system prior to API version 16 can't automatically
+ render dotted circle for incomplete combining letter of some scripts, different
+ set of Key definitions are needed based on the API version. -->
+ <include
+ latin:keyboardLayout="@xml/keystyle_devanagari_sign_anusvara" />
+ <Key
+ latin:keyStyle="baseKeyDevanagariSignAnusvara" />
+ <!-- U+092E: "म" DEVANAGARI LETTER MA -->
+ <Key
+ latin:keySpec="&#x092E;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0928: "न" DEVANAGARI LETTER NA
+ U+0923: "ण" DEVANAGARI LETTER NNA
+ U+091E: "ञ" DEVANAGARI LETTER NYA
+ U+0919: "ङ" DEVANAGARI LETTER NGA -->
+ <Key
+ latin:keySpec="&#x0928;"
+ latin:moreKeys="&#x0923;,&#x091E;,&#x0919;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0935: "व" DEVANAGARI LETTER VA -->
+ <Key
+ latin:keySpec="&#x0935;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0932: "ल" DEVANAGARI LETTER LA
+ U+0933: "ळ" DEVANAGARI LETTER LLA -->
+ <Key
+ latin:keySpec="&#x0932;"
+ latin:moreKeys="&#x0933;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0938: "स" DEVANAGARI LETTER SA
+ U+0936: "श" DEVANAGARI LETTER SHA
+ U+0937: "ष" DEVANAGARI LETTER SSA
+ U+0936/U+094D/U+0930: "श्र" DEVANAGARI LETTER SHA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER RA -->
+ <Key
+ latin:keySpec="&#x0938;"
+ latin:moreKeys="&#x0936;,&#x0937;,&#x0936;&#x094D;&#x0930;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+092F: "य" DEVANAGARI LETTER YA -->
+ <Key
+ latin:keySpec="&#x092F;"
+ latin:keyLabelFlags="fontNormal" />
+ <!-- U+0915/U+094D/U+0937: "क्ष" DEVANAGARI LETTER KA/DEVANAGARI SIGN VIRAMA/DEVANAGARI LETTER SSA -->
+ <Key
+ latin:keySpec="&#x0915;&#x094D;&#x0937;"
+ latin:keyLabelFlags="fontNormal|followKeyLetterRatio" />
+</merge>
diff --git a/java/res/xml/rows_marathi.xml b/java/res/xml/rows_marathi.xml
new file mode 100644
index 000000000..42a036374
--- /dev/null
+++ b/java/res/xml/rows_marathi.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<merge
+ xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
+>
+ <include
+ latin:keyboardLayout="@xml/key_styles_common" />
+ <Row
+ latin:keyWidth="9.091%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_marathi1" />
+ </Row>
+ <Row
+ latin:keyWidth="9.091%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_marathi2" />
+ </Row>
+ <Row
+ latin:keyWidth="9.091%p"
+ >
+ <include
+ latin:keyboardLayout="@xml/rowkeys_marathi3" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
+ </Row>
+ <include
+ latin:keyboardLayout="@xml/row_qwerty4" />
+</merge>
diff --git a/java/res/xml/rows_number_normal.xml b/java/res/xml/rows_number_normal.xml
index 859a1624a..d8d15080e 100644
--- a/java/res/xml/rows_number_normal.xml
+++ b/java/res/xml/rows_number_normal.xml
@@ -90,11 +90,6 @@
latin:keyWidth="fillRight" />
</Row>
<Row>
- <Key
- latin:keyStyle="numSpaceKeyStyle" />
- <Key
- latin:keySpec="0"
- latin:keyStyle="numKeyStyle" />
<switch>
<case
latin:mode="date"
@@ -125,6 +120,11 @@
</default>
</switch>
<Key
+ latin:keySpec="0"
+ latin:keyStyle="numKeyStyle" />
+ <Key
+ latin:keyStyle="numSpaceKeyStyle" />
+ <Key
latin:keyStyle="enterKeyStyle"
latin:keyWidth="fillRight" />
</Row>
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
new file mode 100644
index 000000000..967cafad0
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityLongPressTimer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.accessibility;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.latin.R;
+
+// Handling long press timer to show a more keys keyboard.
+final class AccessibilityLongPressTimer extends Handler {
+ public interface LongPressTimerCallback {
+ public void onLongPressed(Key key);
+ }
+
+ private static final int MSG_LONG_PRESS = 1;
+
+ private final LongPressTimerCallback mCallback;
+ private final long mConfigAccessibilityLongPressTimeout;
+
+ public AccessibilityLongPressTimer(final LongPressTimerCallback callback,
+ final Context context) {
+ super();
+ mCallback = callback;
+ mConfigAccessibilityLongPressTimeout = context.getResources().getInteger(
+ R.integer.config_accessibility_long_press_key_timeout);
+ }
+
+ @Override
+ public void handleMessage(final Message msg) {
+ switch (msg.what) {
+ case MSG_LONG_PRESS:
+ cancelLongPress();
+ mCallback.onLongPressed((Key)msg.obj);
+ return;
+ default:
+ super.handleMessage(msg);
+ return;
+ }
+ }
+
+ public void startLongPress(final Key key) {
+ cancelLongPress();
+ final Message longPressMessage = obtainMessage(MSG_LONG_PRESS, key);
+ sendMessageDelayed(longPressMessage, mConfigAccessibilityLongPressTimeout);
+ }
+
+ public void cancelLongPress() {
+ removeMessages(MSG_LONG_PRESS);
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
index bc094b117..2762a9f25 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
+++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java
@@ -67,8 +67,6 @@ public final class AccessibilityUtils {
// These only need to be initialized if the kill switch is off.
sInstance.initInternal(context);
- KeyCodeDescriptionMapper.init();
- AccessibleKeyboardViewProxy.init(context);
}
public static AccessibilityUtils getInstance() {
@@ -115,7 +113,7 @@ public final class AccessibilityUtils {
* @param event The event to check.
* @return {@true} is the event is a touch exploration event
*/
- public boolean isTouchExplorationEvent(final MotionEvent event) {
+ public static boolean isTouchExplorationEvent(final MotionEvent event) {
final int action = event.getAction();
return action == MotionEvent.ACTION_HOVER_ENTER
|| action == MotionEvent.ACTION_HOVER_EXIT
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
deleted file mode 100644
index 322127a12..000000000
--- a/java/src/com/android/inputmethod/accessibility/AccessibleKeyboardViewProxy.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.accessibility;
-
-import android.content.Context;
-import android.os.SystemClock;
-import android.support.v4.view.AccessibilityDelegateCompat;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.view.accessibility.AccessibilityEventCompat;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
-import android.util.SparseIntArray;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewParent;
-import android.view.accessibility.AccessibilityEvent;
-
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.KeyDetector;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
-
-public final class AccessibleKeyboardViewProxy extends AccessibilityDelegateCompat {
- private static final AccessibleKeyboardViewProxy sInstance = new AccessibleKeyboardViewProxy();
-
- /** Map of keyboard modes to resource IDs. */
- private static final SparseIntArray KEYBOARD_MODE_RES_IDS = new SparseIntArray();
-
- static {
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATE, R.string.keyboard_mode_date);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATETIME, R.string.keyboard_mode_date_time);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_EMAIL, R.string.keyboard_mode_email);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_IM, R.string.keyboard_mode_im);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_NUMBER, R.string.keyboard_mode_number);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_PHONE, R.string.keyboard_mode_phone);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TEXT, R.string.keyboard_mode_text);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TIME, R.string.keyboard_mode_time);
- KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_URL, R.string.keyboard_mode_url);
- }
-
- private MainKeyboardView mView;
- private Keyboard mKeyboard;
- private AccessibilityEntityProvider mAccessibilityNodeProvider;
-
- private Key mLastHoverKey = null;
-
- /**
- * Inset in pixels to look for keys when the user's finger exits the keyboard area.
- */
- private int mEdgeSlop;
-
- /** The most recently set keyboard mode. */
- private int mLastKeyboardMode = KEYBOARD_IS_HIDDEN;
- private static final int KEYBOARD_IS_HIDDEN = -1;
-
- public static void init(final Context context) {
- sInstance.initInternal(context);
- }
-
- public static AccessibleKeyboardViewProxy getInstance() {
- return sInstance;
- }
-
- private AccessibleKeyboardViewProxy() {
- // Not publicly instantiable.
- }
-
- private void initInternal(final Context context) {
- mEdgeSlop = context.getResources().getDimensionPixelSize(
- R.dimen.config_accessibility_edge_slop);
- }
-
- /**
- * Sets the view wrapped by this proxy.
- *
- * @param view The view to wrap.
- */
- public void setView(final MainKeyboardView view) {
- if (view == null) {
- // Ignore null views.
- return;
- }
- mView = view;
-
- // Ensure that the view has an accessibility delegate.
- ViewCompat.setAccessibilityDelegate(view, this);
-
- if (mAccessibilityNodeProvider == null) {
- return;
- }
- mAccessibilityNodeProvider.setView(view);
-
- // Since this class is constructed lazily, we might not get a subsequent
- // call to setKeyboard() and therefore need to call it now.
- setKeyboard(view.getKeyboard());
- }
-
- /**
- * Called when the keyboard layout changes.
- * <p>
- * <b>Note:</b> This method will be called even if accessibility is not
- * enabled.
- * @param keyboard The keyboard that is being set to the wrapping view.
- */
- public void setKeyboard(final Keyboard keyboard) {
- if (keyboard == null) {
- return;
- }
- if (mAccessibilityNodeProvider != null) {
- mAccessibilityNodeProvider.setKeyboard(keyboard);
- }
- final Keyboard lastKeyboard = mKeyboard;
- final int lastKeyboardMode = mLastKeyboardMode;
- mKeyboard = keyboard;
- mLastKeyboardMode = keyboard.mId.mMode;
-
- // Since this method is called even when accessibility is off, make sure
- // to check the state before announcing anything.
- if (!AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
- return;
- }
- // Announce the language name only when the language is changed.
- if (lastKeyboard == null || !lastKeyboard.mId.mSubtype.equals(keyboard.mId.mSubtype)) {
- announceKeyboardLanguage(keyboard);
- }
- // Announce the mode only when the mode is changed.
- if (lastKeyboardMode != keyboard.mId.mMode) {
- announceKeyboardMode(keyboard);
- }
- }
-
- /**
- * Called when the keyboard is hidden and accessibility is enabled.
- */
- public void onHideWindow() {
- if (mView == null) {
- return;
- }
- announceKeyboardHidden();
- mLastKeyboardMode = KEYBOARD_IS_HIDDEN;
- }
-
- /**
- * Announces which language of keyboard is being displayed.
- *
- * @param keyboard The new keyboard.
- */
- private void announceKeyboardLanguage(final Keyboard keyboard) {
- final String languageText = SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(
- keyboard.mId.mSubtype);
- sendWindowStateChanged(languageText);
- }
-
- /**
- * Announces which type of keyboard is being displayed.
- * If the keyboard type is unknown, no announcement is made.
- *
- * @param keyboard The new keyboard.
- */
- private void announceKeyboardMode(final Keyboard keyboard) {
- final int mode = keyboard.mId.mMode;
- final Context context = mView.getContext();
- final int modeTextResId = KEYBOARD_MODE_RES_IDS.get(mode);
- if (modeTextResId == 0) {
- return;
- }
- final String modeText = context.getString(modeTextResId);
- final String text = context.getString(R.string.announce_keyboard_mode, modeText);
- sendWindowStateChanged(text);
- }
-
- /**
- * Announces that the keyboard has been hidden.
- */
- private void announceKeyboardHidden() {
- final Context context = mView.getContext();
- final String text = context.getString(R.string.announce_keyboard_hidden);
-
- sendWindowStateChanged(text);
- }
-
- /**
- * Sends a window state change event with the specified text.
- *
- * @param text The text to send with the event.
- */
- private void sendWindowStateChanged(final String text) {
- final AccessibilityEvent stateChange = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- mView.onInitializeAccessibilityEvent(stateChange);
- stateChange.getText().add(text);
- stateChange.setContentDescription(null);
-
- final ViewParent parent = mView.getParent();
- if (parent != null) {
- parent.requestSendAccessibilityEvent(mView, stateChange);
- }
- }
-
- /**
- * Proxy method for View.getAccessibilityNodeProvider(). This method is called in SDK
- * version 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) and higher to obtain the virtual
- * node hierarchy provider.
- *
- * @param host The host view for the provider.
- * @return The accessibility node provider for the current keyboard.
- */
- @Override
- public AccessibilityEntityProvider getAccessibilityNodeProvider(final View host) {
- if (mView == null) {
- return null;
- }
- return getAccessibilityNodeProvider();
- }
-
- /**
- * Receives hover events when touch exploration is turned on in SDK versions ICS and higher.
- *
- * @param event The hover event.
- * @param keyDetector The {@link KeyDetector} to determine on which key the <code>event</code>
- * is hovering.
- * @return {@code true} if the event is handled
- */
- public boolean dispatchHoverEvent(final MotionEvent event, final KeyDetector keyDetector) {
- if (mView == null) {
- return false;
- }
-
- final int x = (int) event.getX();
- final int y = (int) event.getY();
- final Key previousKey = mLastHoverKey;
- final Key key;
-
- if (pointInView(x, y)) {
- key = keyDetector.detectHitKey(x, y);
- } else {
- key = null;
- }
- mLastHoverKey = key;
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_HOVER_EXIT:
- // Make sure we're not getting an EXIT event because the user slid
- // off the keyboard area, then force a key press.
- if (key != null) {
- final long downTime = simulateKeyPress(key);
- simulateKeyRelease(key, downTime);
- }
- //$FALL-THROUGH$
- case MotionEvent.ACTION_HOVER_ENTER:
- return onHoverKey(key, event);
- case MotionEvent.ACTION_HOVER_MOVE:
- if (key != previousKey) {
- return onTransitionKey(key, previousKey, event);
- }
- return onHoverKey(key, event);
- }
- return false;
- }
-
- /**
- * @return A lazily-instantiated node provider for this view proxy.
- */
- private AccessibilityEntityProvider getAccessibilityNodeProvider() {
- // Instantiate the provide only when requested. Since the system
- // will call this method multiple times it is a good practice to
- // cache the provider instance.
- if (mAccessibilityNodeProvider == null) {
- mAccessibilityNodeProvider = new AccessibilityEntityProvider(mView);
- }
- return mAccessibilityNodeProvider;
- }
-
- /**
- * Utility method to determine whether the given point, in local coordinates, is inside the
- * view, where the area of the view is contracted by the edge slop factor.
- *
- * @param localX The local x-coordinate.
- * @param localY The local y-coordinate.
- */
- private boolean pointInView(final int localX, final int localY) {
- return (localX >= mEdgeSlop) && (localY >= mEdgeSlop)
- && (localX < (mView.getWidth() - mEdgeSlop))
- && (localY < (mView.getHeight() - mEdgeSlop));
- }
-
- /**
- * Simulates a key press by injecting touch event into the keyboard view.
- * This avoids the complexity of trackers and listeners within the keyboard.
- *
- * @param key The key to press.
- */
- private long simulateKeyPress(final Key key) {
- final int x = key.getHitBox().centerX();
- final int y = key.getHitBox().centerY();
- final long downTime = SystemClock.uptimeMillis();
- final MotionEvent downEvent = MotionEvent.obtain(
- downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0);
- mView.onTouchEvent(downEvent);
- downEvent.recycle();
- return downTime;
- }
-
- /**
- * Simulates a key release by injecting touch event into the keyboard view.
- * This avoids the complexity of trackers and listeners within the keyboard.
- *
- * @param key The key to release.
- */
- private void simulateKeyRelease(final Key key, final long downTime) {
- final int x = key.getHitBox().centerX();
- final int y = key.getHitBox().centerY();
- final MotionEvent upEvent = MotionEvent.obtain(
- downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0);
- mView.onTouchEvent(upEvent);
- upEvent.recycle();
- }
-
- /**
- * Simulates a transition between two {@link Key}s by sending a HOVER_EXIT on the previous key,
- * a HOVER_ENTER on the current key, and a HOVER_MOVE on the current key.
- *
- * @param currentKey The currently hovered key.
- * @param previousKey The previously hovered key.
- * @param event The event that triggered the transition.
- * @return {@code true} if the event was handled.
- */
- private boolean onTransitionKey(final Key currentKey, final Key previousKey,
- final MotionEvent event) {
- final int savedAction = event.getAction();
- event.setAction(MotionEvent.ACTION_HOVER_EXIT);
- onHoverKey(previousKey, event);
- event.setAction(MotionEvent.ACTION_HOVER_ENTER);
- onHoverKey(currentKey, event);
- event.setAction(MotionEvent.ACTION_HOVER_MOVE);
- final boolean handled = onHoverKey(currentKey, event);
- event.setAction(savedAction);
- return handled;
- }
-
- /**
- * Handles a hover event on a key. If {@link Key} extended View, this would be analogous to
- * calling View.onHoverEvent(MotionEvent).
- *
- * @param key The currently hovered key.
- * @param event The hover event.
- * @return {@code true} if the event was handled.
- */
- private boolean onHoverKey(final Key key, final MotionEvent event) {
- // Null keys can't receive events.
- if (key == null) {
- return false;
- }
- final AccessibilityEntityProvider provider = getAccessibilityNodeProvider();
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_HOVER_ENTER:
- provider.sendAccessibilityEventForKey(
- key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER);
- provider.performActionForKey(
- key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS, null);
- break;
- case MotionEvent.ACTION_HOVER_EXIT:
- provider.sendAccessibilityEventForKey(
- key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
- break;
- }
- return true;
- }
-
- /**
- * Notifies the user of changes in the keyboard shift state.
- */
- public void notifyShiftState() {
- if (mView == null || mKeyboard == null) {
- return;
- }
-
- final KeyboardId keyboardId = mKeyboard.mId;
- final int elementId = keyboardId.mElementId;
- final Context context = mView.getContext();
- final CharSequence text;
-
- switch (elementId) {
- case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
- case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
- text = context.getText(R.string.spoken_description_shiftmode_locked);
- break;
- case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
- case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
- case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
- text = context.getText(R.string.spoken_description_shiftmode_on);
- break;
- default:
- text = context.getText(R.string.spoken_description_shiftmode_off);
- }
- AccessibilityUtils.getInstance().announceForAccessibility(mView, text);
- }
-
- /**
- * Notifies the user of changes in the keyboard symbols state.
- */
- public void notifySymbolsState() {
- if (mView == null || mKeyboard == null) {
- return;
- }
-
- final KeyboardId keyboardId = mKeyboard.mId;
- final int elementId = keyboardId.mElementId;
- final Context context = mView.getContext();
- final int resId;
-
- switch (elementId) {
- case KeyboardId.ELEMENT_ALPHABET:
- case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
- case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
- case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
- case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
- resId = R.string.spoken_description_mode_alpha;
- break;
- case KeyboardId.ELEMENT_SYMBOLS:
- case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
- resId = R.string.spoken_description_mode_symbol;
- break;
- case KeyboardId.ELEMENT_PHONE:
- resId = R.string.spoken_description_mode_phone;
- break;
- case KeyboardId.ELEMENT_PHONE_SYMBOLS:
- resId = R.string.spoken_description_mode_phone_shift;
- break;
- default:
- return;
- }
-
- final String text = context.getString(resId);
- AccessibilityUtils.getInstance().announceForAccessibility(mView, text);
- }
-}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
index 2e6649bf2..7a3510ee1 100644
--- a/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyCodeDescriptionMapper.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.accessibility;
import android.content.Context;
+import android.content.res.Resources;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseIntArray;
@@ -27,37 +28,29 @@ import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.utils.StringUtils;
-import java.util.HashMap;
+import java.util.Locale;
-public final class KeyCodeDescriptionMapper {
+final class KeyCodeDescriptionMapper {
private static final String TAG = KeyCodeDescriptionMapper.class.getSimpleName();
+ private static final String SPOKEN_LETTER_RESOURCE_NAME_FORMAT = "spoken_accented_letter_%04X";
+ private static final String SPOKEN_SYMBOL_RESOURCE_NAME_FORMAT = "spoken_symbol_%04X";
+ private static final String SPOKEN_EMOJI_RESOURCE_NAME_FORMAT = "spoken_emoji_%04X";
// The resource ID of the string spoken for obscured keys
private static final int OBSCURED_KEY_RES_ID = R.string.spoken_description_dot;
- private static KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper();
-
- // Map of key labels to spoken description resource IDs
- private final HashMap<CharSequence, Integer> mKeyLabelMap = CollectionUtils.newHashMap();
-
- // Sparse array of spoken description resource IDs indexed by key codes
- private final SparseIntArray mKeyCodeMap;
-
- public static void init() {
- sInstance.initInternal();
- }
+ private static final KeyCodeDescriptionMapper sInstance = new KeyCodeDescriptionMapper();
public static KeyCodeDescriptionMapper getInstance() {
return sInstance;
}
- private KeyCodeDescriptionMapper() {
- mKeyCodeMap = new SparseIntArray();
- }
+ // Sparse array of spoken description resource IDs indexed by key codes
+ private final SparseIntArray mKeyCodeMap = new SparseIntArray();
- private void initInternal() {
+ private KeyCodeDescriptionMapper() {
// Special non-character codes defined in Keyboard
mKeyCodeMap.put(Constants.CODE_SPACE, R.string.spoken_description_space);
mKeyCodeMap.put(Constants.CODE_DELETE, R.string.spoken_description_delete);
@@ -73,19 +66,20 @@ public final class KeyCodeDescriptionMapper {
mKeyCodeMap.put(Constants.CODE_ACTION_PREVIOUS,
R.string.spoken_description_action_previous);
mKeyCodeMap.put(Constants.CODE_EMOJI, R.string.spoken_description_emoji);
+ // Because the upper-case and lower-case mappings of the following letters is depending on
+ // the locale, the upper case descriptions should be defined here. The lower case
+ // descriptions are handled in {@link #getSpokenLetterDescriptionId(Context,int)}.
+ // U+0049: "I" LATIN CAPITAL LETTER I
+ // U+0069: "i" LATIN SMALL LETTER I
+ // U+0130: "İ" LATIN CAPITAL LETTER I WITH DOT ABOVE
+ // U+0131: "ı" LATIN SMALL LETTER DOTLESS I
+ mKeyCodeMap.put(0x0049, R.string.spoken_letter_0049);
+ mKeyCodeMap.put(0x0130, R.string.spoken_letter_0130);
}
/**
* Returns the localized description of the action performed by a specified
* key based on the current keyboard state.
- * <p>
- * The order of precedence for key descriptions is:
- * <ol>
- * <li>Manually-defined based on the key label</li>
- * <li>Automatic or manually-defined based on the key code</li>
- * <li>Automatically based on the key label</li>
- * <li>{code null} for keys with no label or key code defined</li>
- * </p>
*
* @param context The package's context.
* @param keyboard The keyboard on which the key resides.
@@ -114,18 +108,26 @@ public final class KeyCodeDescriptionMapper {
return getDescriptionForActionKey(context, keyboard, key);
}
- if (!TextUtils.isEmpty(key.getLabel())) {
- final String label = key.getLabel().trim();
-
- // First, attempt to map the label to a pre-defined description.
- if (mKeyLabelMap.containsKey(label)) {
- return context.getString(mKeyLabelMap.get(label));
- }
+ if (code == Constants.CODE_OUTPUT_TEXT) {
+ return key.getOutputText();
}
// Just attempt to speak the description.
- if (key.getCode() != Constants.CODE_UNSPECIFIED) {
- return getDescriptionForKeyCode(context, keyboard, key, shouldObscure);
+ if (code != Constants.CODE_UNSPECIFIED) {
+ // If the key description should be obscured, now is the time to do it.
+ final boolean isDefinedNonCtrl = Character.isDefined(code)
+ && !Character.isISOControl(code);
+ if (shouldObscure && isDefinedNonCtrl) {
+ return context.getString(OBSCURED_KEY_RES_ID);
+ }
+ final String description = getDescriptionForCodePoint(context, code);
+ if (description != null) {
+ return description;
+ }
+ if (!TextUtils.isEmpty(key.getLabel())) {
+ return key.getLabel();
+ }
+ return context.getString(R.string.spoken_description_unknown);
}
return null;
}
@@ -139,7 +141,7 @@ public final class KeyCodeDescriptionMapper {
* @param keyboard The keyboard on which the key resides.
* @return a character sequence describing the action performed by pressing the key
*/
- private String getDescriptionForSwitchAlphaSymbol(final Context context,
+ private static String getDescriptionForSwitchAlphaSymbol(final Context context,
final Keyboard keyboard) {
final KeyboardId keyboardId = keyboard.mId;
final int elementId = keyboardId.mElementId;
@@ -177,7 +179,8 @@ public final class KeyCodeDescriptionMapper {
* @param keyboard The keyboard on which the key resides.
* @return A context-sensitive description of the "Shift" key.
*/
- private String getDescriptionForShiftKey(final Context context, final Keyboard keyboard) {
+ private static String getDescriptionForShiftKey(final Context context,
+ final Keyboard keyboard) {
final KeyboardId keyboardId = keyboard.mId;
final int elementId = keyboardId.mElementId;
final int resId;
@@ -189,9 +192,14 @@ public final class KeyCodeDescriptionMapper {
break;
case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
- case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
resId = R.string.spoken_description_shift_shifted;
break;
+ case KeyboardId.ELEMENT_SYMBOLS:
+ resId = R.string.spoken_description_symbols_shift;
+ break;
+ case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
+ resId = R.string.spoken_description_symbols_shift_shifted;
+ break;
default:
resId = R.string.spoken_description_shift;
}
@@ -206,7 +214,7 @@ public final class KeyCodeDescriptionMapper {
* @param key The key to describe.
* @return Returns a context-sensitive description of the "Enter" action key.
*/
- private String getDescriptionForActionKey(final Context context, final Keyboard keyboard,
+ private static String getDescriptionForActionKey(final Context context, final Keyboard keyboard,
final Key key) {
final KeyboardId keyboardId = keyboard.mId;
final int actionId = keyboardId.imeAction();
@@ -245,42 +253,91 @@ public final class KeyCodeDescriptionMapper {
/**
* Returns a localized character sequence describing what will happen when
- * the specified key is pressed based on its key code.
- * <p>
- * The order of precedence for key code descriptions is:
- * <ol>
- * <li>Manually-defined shift-locked description</li>
- * <li>Manually-defined shifted description</li>
- * <li>Manually-defined normal description</li>
- * <li>Automatic based on the character represented by the key code</li>
- * <li>Fall-back for undefined or control characters</li>
- * </ol>
- * </p>
+ * the specified key is pressed based on its key code point.
*
* @param context The package's context.
- * @param keyboard The keyboard on which the key resides.
- * @param key The key from which to obtain a description.
- * @param shouldObscure {@true} if text (e.g. non-control) characters should be obscured.
- * @return a character sequence describing the action performed by pressing the key
+ * @param codePoint The code point from which to obtain a description.
+ * @return a character sequence describing the code point.
*/
- private String getDescriptionForKeyCode(final Context context, final Keyboard keyboard,
- final Key key, final boolean shouldObscure) {
- final int code = key.getCode();
-
+ public String getDescriptionForCodePoint(final Context context, final int codePoint) {
// If the key description should be obscured, now is the time to do it.
- final boolean isDefinedNonCtrl = Character.isDefined(code) && !Character.isISOControl(code);
- if (shouldObscure && isDefinedNonCtrl) {
- return context.getString(OBSCURED_KEY_RES_ID);
+ final int index = mKeyCodeMap.indexOfKey(codePoint);
+ if (index >= 0) {
+ return context.getString(mKeyCodeMap.valueAt(index));
}
- if (mKeyCodeMap.indexOfKey(code) >= 0) {
- return context.getString(mKeyCodeMap.get(code));
+ final String accentedLetter = getSpokenAccentedLetterDescription(context, codePoint);
+ if (accentedLetter != null) {
+ return accentedLetter;
}
- if (isDefinedNonCtrl) {
- return Character.toString((char) code);
+ // Here, <code>code</code> may be a base (non-accented) letter.
+ final String unsupportedSymbol = getSpokenSymbolDescription(context, codePoint);
+ if (unsupportedSymbol != null) {
+ return unsupportedSymbol;
}
- if (!TextUtils.isEmpty(key.getLabel())) {
- return key.getLabel();
+ final String emojiDescription = getSpokenEmojiDescription(context, codePoint);
+ if (emojiDescription != null) {
+ return emojiDescription;
+ }
+ if (Character.isDefined(codePoint) && !Character.isISOControl(codePoint)) {
+ return StringUtils.newSingleCodePointString(codePoint);
+ }
+ return null;
+ }
+
+ // TODO: Remove this method once TTS supports those accented letters' verbalization.
+ private String getSpokenAccentedLetterDescription(final Context context, final int code) {
+ final boolean isUpperCase = Character.isUpperCase(code);
+ final int baseCode = isUpperCase ? Character.toLowerCase(code) : code;
+ final int baseIndex = mKeyCodeMap.indexOfKey(baseCode);
+ final int resId = (baseIndex >= 0) ? mKeyCodeMap.valueAt(baseIndex)
+ : getSpokenDescriptionId(context, baseCode, SPOKEN_LETTER_RESOURCE_NAME_FORMAT);
+ if (resId == 0) {
+ return null;
+ }
+ final String spokenText = context.getString(resId);
+ return isUpperCase ? context.getString(R.string.spoken_description_upper_case, spokenText)
+ : spokenText;
+ }
+
+ // TODO: Remove this method once TTS supports those symbols' verbalization.
+ private String getSpokenSymbolDescription(final Context context, final int code) {
+ final int resId = getSpokenDescriptionId(context, code, SPOKEN_SYMBOL_RESOURCE_NAME_FORMAT);
+ if (resId == 0) {
+ return null;
+ }
+ final String spokenText = context.getString(resId);
+ if (!TextUtils.isEmpty(spokenText)) {
+ return spokenText;
+ }
+ // If a translated description is empty, fall back to unknown symbol description.
+ return context.getString(R.string.spoken_symbol_unknown);
+ }
+
+ // TODO: Remove this method once TTS supports emoji verbalization.
+ private String getSpokenEmojiDescription(final Context context, final int code) {
+ final int resId = getSpokenDescriptionId(context, code, SPOKEN_EMOJI_RESOURCE_NAME_FORMAT);
+ if (resId == 0) {
+ return null;
+ }
+ final String spokenText = context.getString(resId);
+ if (!TextUtils.isEmpty(spokenText)) {
+ return spokenText;
+ }
+ // If a translated description is empty, fall back to unknown emoji description.
+ return context.getString(R.string.spoken_emoji_unknown);
+ }
+
+ private int getSpokenDescriptionId(final Context context, final int code,
+ final String resourceNameFormat) {
+ final String resourceName = String.format(Locale.ROOT, resourceNameFormat, code);
+ final Resources resources = context.getResources();
+ // Note that the resource package name may differ from the context package name.
+ final String resourcePackageName = resources.getResourcePackageName(
+ R.string.spoken_description_unknown);
+ final int resId = resources.getIdentifier(resourceName, "string", resourcePackageName);
+ if (resId != 0) {
+ mKeyCodeMap.append(code, resId);
}
- return context.getString(R.string.spoken_description_unknown, code);
+ return resId;
}
}
diff --git a/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
new file mode 100644
index 000000000..d67d9dc4b
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityDelegate.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.accessibility;
+
+import android.content.Context;
+import android.support.v4.view.AccessibilityDelegateCompat;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.accessibility.AccessibilityEventCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.keyboard.PointerTracker;
+
+/**
+ * This class represents a delegate that can be registered in a class that extends
+ * {@link KeyboardView} to enhance accessibility support via composition rather via inheritance.
+ *
+ * To implement accessibility mode, the target keyboard view has to:<p>
+ * - Call {@link #setKeyboard(Keyboard)} when a new keyboard is set to the keyboard view.
+ * - Dispatch a hover event by calling {@link #onHoverEnter(MotionEvent)}.
+ *
+ * @param <KV> The keyboard view class type.
+ */
+public class KeyboardAccessibilityDelegate<KV extends KeyboardView>
+ extends AccessibilityDelegateCompat {
+ private static final String TAG = KeyboardAccessibilityDelegate.class.getSimpleName();
+ protected static final boolean DEBUG_HOVER = false;
+
+ protected final KV mKeyboardView;
+ protected final KeyDetector mKeyDetector;
+ private Keyboard mKeyboard;
+ private KeyboardAccessibilityNodeProvider mAccessibilityNodeProvider;
+ private Key mLastHoverKey;
+
+ public static final int HOVER_EVENT_POINTER_ID = 0;
+
+ public KeyboardAccessibilityDelegate(final KV keyboardView, final KeyDetector keyDetector) {
+ super();
+ mKeyboardView = keyboardView;
+ mKeyDetector = keyDetector;
+
+ // Ensure that the view has an accessibility delegate.
+ ViewCompat.setAccessibilityDelegate(keyboardView, this);
+ }
+
+ /**
+ * Called when the keyboard layout changes.
+ * <p>
+ * <b>Note:</b> This method will be called even if accessibility is not
+ * enabled.
+ * @param keyboard The keyboard that is being set to the wrapping view.
+ */
+ public void setKeyboard(final Keyboard keyboard) {
+ if (keyboard == null) {
+ return;
+ }
+ if (mAccessibilityNodeProvider != null) {
+ mAccessibilityNodeProvider.setKeyboard(keyboard);
+ }
+ mKeyboard = keyboard;
+ }
+
+ protected final Keyboard getKeyboard() {
+ return mKeyboard;
+ }
+
+ protected final void setLastHoverKey(final Key key) {
+ mLastHoverKey = key;
+ }
+
+ protected final Key getLastHoverKey() {
+ return mLastHoverKey;
+ }
+
+ /**
+ * Sends a window state change event with the specified string resource id.
+ *
+ * @param resId The string resource id of the text to send with the event.
+ */
+ protected void sendWindowStateChanged(final int resId) {
+ if (resId == 0) {
+ return;
+ }
+ final Context context = mKeyboardView.getContext();
+ sendWindowStateChanged(context.getString(resId));
+ }
+
+ /**
+ * Sends a window state change event with the specified text.
+ *
+ * @param text The text to send with the event.
+ */
+ protected void sendWindowStateChanged(final String text) {
+ final AccessibilityEvent stateChange = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ mKeyboardView.onInitializeAccessibilityEvent(stateChange);
+ stateChange.getText().add(text);
+ stateChange.setContentDescription(null);
+
+ final ViewParent parent = mKeyboardView.getParent();
+ if (parent != null) {
+ parent.requestSendAccessibilityEvent(mKeyboardView, stateChange);
+ }
+ }
+
+ /**
+ * Delegate method for View.getAccessibilityNodeProvider(). This method is called in SDK
+ * version 15 (Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) and higher to obtain the virtual
+ * node hierarchy provider.
+ *
+ * @param host The host view for the provider.
+ * @return The accessibility node provider for the current keyboard.
+ */
+ @Override
+ public KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider(final View host) {
+ return getAccessibilityNodeProvider();
+ }
+
+ /**
+ * @return A lazily-instantiated node provider for this view delegate.
+ */
+ protected KeyboardAccessibilityNodeProvider getAccessibilityNodeProvider() {
+ // Instantiate the provide only when requested. Since the system
+ // will call this method multiple times it is a good practice to
+ // cache the provider instance.
+ if (mAccessibilityNodeProvider == null) {
+ mAccessibilityNodeProvider = new KeyboardAccessibilityNodeProvider(mKeyboardView);
+ }
+ return mAccessibilityNodeProvider;
+ }
+
+ /**
+ * Get a key that a hover event is on.
+ *
+ * @param event The hover event.
+ * @return key The key that the <code>event</code> is on.
+ */
+ protected final Key getHoverKeyOf(final MotionEvent event) {
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ return mKeyDetector.detectHitKey(x, y);
+ }
+
+ /**
+ * Receives hover events when touch exploration is turned on in SDK versions ICS and higher.
+ *
+ * @param event The hover event.
+ * @return {@code true} if the event is handled.
+ */
+ public boolean onHoverEvent(final MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_HOVER_ENTER:
+ onHoverEnter(event);
+ break;
+ case MotionEvent.ACTION_HOVER_MOVE:
+ onHoverMove(event);
+ break;
+ case MotionEvent.ACTION_HOVER_EXIT:
+ onHoverExit(event);
+ break;
+ default:
+ Log.w(getClass().getSimpleName(), "Unknown hover event: " + event);
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Process {@link MotionEvent#ACTION_HOVER_ENTER} event.
+ *
+ * @param event A hover enter event.
+ */
+ protected void onHoverEnter(final MotionEvent event) {
+ final Key key = getHoverKeyOf(event);
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnter: key=" + key);
+ }
+ if (key != null) {
+ onHoverEnterTo(key);
+ }
+ setLastHoverKey(key);
+ }
+
+ /**
+ * Process {@link MotionEvent#ACTION_HOVER_MOVE} event.
+ *
+ * @param event A hover move event.
+ */
+ protected void onHoverMove(final MotionEvent event) {
+ final Key lastKey = getLastHoverKey();
+ final Key key = getHoverKeyOf(event);
+ if (key != lastKey) {
+ if (lastKey != null) {
+ onHoverExitFrom(lastKey);
+ }
+ if (key != null) {
+ onHoverEnterTo(key);
+ }
+ }
+ if (key != null) {
+ onHoverMoveWithin(key);
+ }
+ setLastHoverKey(key);
+ }
+
+ /**
+ * Process {@link MotionEvent#ACTION_HOVER_EXIT} event.
+ *
+ * @param event A hover exit event.
+ */
+ protected void onHoverExit(final MotionEvent event) {
+ final Key lastKey = getLastHoverKey();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExit: key=" + getHoverKeyOf(event) + " last=" + lastKey);
+ }
+ if (lastKey != null) {
+ onHoverExitFrom(lastKey);
+ }
+ final Key key = getHoverKeyOf(event);
+ // Make sure we're not getting an EXIT event because the user slid
+ // off the keyboard area, then force a key press.
+ if (key != null) {
+ onRegisterHoverKey(key, event);
+ onHoverExitFrom(key);
+ }
+ setLastHoverKey(null);
+ }
+
+ /**
+ * Register a key that is selected by a hover event
+ *
+ * @param key A key to be registered.
+ * @param event A hover exit event that triggers key registering.
+ */
+ protected void onRegisterHoverKey(final Key key, final MotionEvent event) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onRegisterHoverKey: key=" + key);
+ }
+ simulateTouchEvent(MotionEvent.ACTION_DOWN, event);
+ simulateTouchEvent(MotionEvent.ACTION_UP, event);
+ }
+
+ /**
+ * Simulating a touch event by injecting a synthesized touch event into {@link PointerTracker}.
+ *
+ * @param touchAction The action of the synthesizing touch event.
+ * @param hoverEvent The base hover event from that the touch event is synthesized.
+ */
+ protected void simulateTouchEvent(final int touchAction, final MotionEvent hoverEvent) {
+ final MotionEvent touchEvent = synthesizeTouchEvent(touchAction, hoverEvent);
+ final int actionIndex = touchEvent.getActionIndex();
+ final int pointerId = touchEvent.getPointerId(actionIndex);
+ final PointerTracker tracker = PointerTracker.getPointerTracker(pointerId);
+ tracker.processMotionEvent(touchEvent, mKeyDetector);
+ touchEvent.recycle();
+ }
+
+ /**
+ * Synthesize a touch event from a hover event.
+ *
+ * @param touchAction The action of the synthesizing touch event.
+ * @param hoverEvent The base hover event from that the touch event is synthesized.
+ * @return The synthesized touch event of <code>touchAction</code> that has pointer information
+ * of <code>event</code>.
+ */
+ protected static MotionEvent synthesizeTouchEvent(final int touchAction,
+ final MotionEvent hoverEvent) {
+ final MotionEvent touchEvent = MotionEvent.obtain(hoverEvent);
+ touchEvent.setAction(touchAction);
+ return touchEvent;
+ }
+
+ /**
+ * Handles a hover enter event on a key.
+ *
+ * @param key The currently hovered key.
+ */
+ protected void onHoverEnterTo(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnterTo: key=" + key);
+ }
+ key.onPressed();
+ mKeyboardView.invalidateKey(key);
+ final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+ provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_ENTER);
+ provider.performActionForKey(key, AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS);
+ }
+
+ /**
+ * Handles a hover move event on a key.
+ *
+ * @param key The currently hovered key.
+ */
+ protected void onHoverMoveWithin(final Key key) { }
+
+ /**
+ * Handles a hover exit event on a key.
+ *
+ * @param key The currently hovered key.
+ */
+ protected void onHoverExitFrom(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExitFrom: key=" + key);
+ }
+ key.onReleased();
+ mKeyboardView.invalidateKey(key);
+ final KeyboardAccessibilityNodeProvider provider = getAccessibilityNodeProvider();
+ provider.sendAccessibilityEventForKey(key, AccessibilityEventCompat.TYPE_VIEW_HOVER_EXIT);
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
index ec1ab3565..18673a366 100644
--- a/java/src/com/android/inputmethod/accessibility/AccessibilityEntityProvider.java
+++ b/java/src/com/android/inputmethod/accessibility/KeyboardAccessibilityNodeProvider.java
@@ -47,8 +47,8 @@ import java.util.List;
* virtual views, thus conveying their logical structure.
* </p>
*/
-public final class AccessibilityEntityProvider extends AccessibilityNodeProviderCompat {
- private static final String TAG = AccessibilityEntityProvider.class.getSimpleName();
+final class KeyboardAccessibilityNodeProvider extends AccessibilityNodeProviderCompat {
+ private static final String TAG = KeyboardAccessibilityNodeProvider.class.getSimpleName();
private static final int UNDEFINED = Integer.MIN_VALUE;
private final KeyCodeDescriptionMapper mKeyCodeDescriptionMapper;
@@ -64,23 +64,15 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
private int mAccessibilityFocusedView = UNDEFINED;
/** The current keyboard view. */
- private KeyboardView mKeyboardView;
+ private final KeyboardView mKeyboardView;
/** The current keyboard. */
private Keyboard mKeyboard;
- public AccessibilityEntityProvider(final KeyboardView keyboardView) {
+ public KeyboardAccessibilityNodeProvider(final KeyboardView keyboardView) {
+ super();
mKeyCodeDescriptionMapper = KeyCodeDescriptionMapper.getInstance();
mAccessibilityUtils = AccessibilityUtils.getInstance();
- setView(keyboardView);
- }
-
- /**
- * Sets the keyboard view represented by this node provider.
- *
- * @param keyboardView The keyboard view to represent.
- */
- public void setView(final KeyboardView keyboardView) {
mKeyboardView = keyboardView;
updateParentLocation();
@@ -142,7 +134,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
event.setClassName(key.getClass().getName());
event.setContentDescription(keyDescription);
event.setEnabled(true);
- final AccessibilityRecordCompat record = new AccessibilityRecordCompat(event);
+ final AccessibilityRecordCompat record = AccessibilityEventCompat.asRecord(event);
record.setSource(mKeyboardView, virtualViewId);
return event;
}
@@ -237,7 +229,7 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
if (key == null) {
return false;
}
- return performActionForKey(key, action, arguments);
+ return performActionForKey(key, action);
}
/**
@@ -245,25 +237,16 @@ public final class AccessibilityEntityProvider extends AccessibilityNodeProvider
*
* @param key The on which to perform the action.
* @param action The action to perform.
- * @param arguments The action's arguments.
* @return The result of performing the action, or false if the action is not supported.
*/
- boolean performActionForKey(final Key key, final int action, final Bundle arguments) {
- final int virtualViewId = getVirtualViewIdOf(key);
-
+ boolean performActionForKey(final Key key, final int action) {
switch (action) {
case AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS:
- if (mAccessibilityFocusedView == virtualViewId) {
- return false;
- }
- mAccessibilityFocusedView = virtualViewId;
+ mAccessibilityFocusedView = getVirtualViewIdOf(key);
sendAccessibilityEventForKey(
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
return true;
case AccessibilityNodeInfoCompat.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
- if (mAccessibilityFocusedView != virtualViewId) {
- return false;
- }
mAccessibilityFocusedView = UNDEFINED;
sendAccessibilityEventForKey(
key, AccessibilityEventCompat.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
new file mode 100644
index 000000000..96f84dde9
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.accessibility;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.MotionEvent;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.MainKeyboardView;
+import com.android.inputmethod.keyboard.PointerTracker;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+
+/**
+ * This class represents a delegate that can be registered in {@link MainKeyboardView} to enhance
+ * accessibility support via composition rather via inheritance.
+ */
+public final class MainKeyboardAccessibilityDelegate
+ extends KeyboardAccessibilityDelegate<MainKeyboardView>
+ implements AccessibilityLongPressTimer.LongPressTimerCallback {
+ private static final String TAG = MainKeyboardAccessibilityDelegate.class.getSimpleName();
+
+ /** Map of keyboard modes to resource IDs. */
+ private static final SparseIntArray KEYBOARD_MODE_RES_IDS = new SparseIntArray();
+
+ static {
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATE, R.string.keyboard_mode_date);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_DATETIME, R.string.keyboard_mode_date_time);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_EMAIL, R.string.keyboard_mode_email);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_IM, R.string.keyboard_mode_im);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_NUMBER, R.string.keyboard_mode_number);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_PHONE, R.string.keyboard_mode_phone);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TEXT, R.string.keyboard_mode_text);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_TIME, R.string.keyboard_mode_time);
+ KEYBOARD_MODE_RES_IDS.put(KeyboardId.MODE_URL, R.string.keyboard_mode_url);
+ }
+
+ /** The most recently set keyboard mode. */
+ private int mLastKeyboardMode = KEYBOARD_IS_HIDDEN;
+ private static final int KEYBOARD_IS_HIDDEN = -1;
+ // The rectangle region to ignore hover events.
+ private final Rect mBoundsToIgnoreHoverEvent = new Rect();
+
+ private final AccessibilityLongPressTimer mAccessibilityLongPressTimer;
+
+ public MainKeyboardAccessibilityDelegate(final MainKeyboardView mainKeyboardView,
+ final KeyDetector keyDetector) {
+ super(mainKeyboardView, keyDetector);
+ mAccessibilityLongPressTimer = new AccessibilityLongPressTimer(
+ this /* callback */, mainKeyboardView.getContext());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setKeyboard(final Keyboard keyboard) {
+ if (keyboard == null) {
+ return;
+ }
+ final Keyboard lastKeyboard = getKeyboard();
+ super.setKeyboard(keyboard);
+ final int lastKeyboardMode = mLastKeyboardMode;
+ mLastKeyboardMode = keyboard.mId.mMode;
+
+ // Since this method is called even when accessibility is off, make sure
+ // to check the state before announcing anything.
+ if (!AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
+ return;
+ }
+ // Announce the language name only when the language is changed.
+ if (lastKeyboard == null || !keyboard.mId.mSubtype.equals(lastKeyboard.mId.mSubtype)) {
+ announceKeyboardLanguage(keyboard);
+ return;
+ }
+ // Announce the mode only when the mode is changed.
+ if (keyboard.mId.mMode != lastKeyboardMode) {
+ announceKeyboardMode(keyboard);
+ return;
+ }
+ // Announce the keyboard type only when the type is changed.
+ if (keyboard.mId.mElementId != lastKeyboard.mId.mElementId) {
+ announceKeyboardType(keyboard, lastKeyboard);
+ return;
+ }
+ }
+
+ /**
+ * Called when the keyboard is hidden and accessibility is enabled.
+ */
+ public void onHideWindow() {
+ announceKeyboardHidden();
+ mLastKeyboardMode = KEYBOARD_IS_HIDDEN;
+ }
+
+ /**
+ * Announces which language of keyboard is being displayed.
+ *
+ * @param keyboard The new keyboard.
+ */
+ private void announceKeyboardLanguage(final Keyboard keyboard) {
+ final String languageText = SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(
+ keyboard.mId.mSubtype);
+ sendWindowStateChanged(languageText);
+ }
+
+ /**
+ * Announces which type of keyboard is being displayed.
+ * If the keyboard type is unknown, no announcement is made.
+ *
+ * @param keyboard The new keyboard.
+ */
+ private void announceKeyboardMode(final Keyboard keyboard) {
+ final Context context = mKeyboardView.getContext();
+ final int modeTextResId = KEYBOARD_MODE_RES_IDS.get(keyboard.mId.mMode);
+ if (modeTextResId == 0) {
+ return;
+ }
+ final String modeText = context.getString(modeTextResId);
+ final String text = context.getString(R.string.announce_keyboard_mode, modeText);
+ sendWindowStateChanged(text);
+ }
+
+ /**
+ * Announces which type of keyboard is being displayed.
+ *
+ * @param keyboard The new keyboard.
+ * @param lastKeyboard The last keyboard.
+ */
+ private void announceKeyboardType(final Keyboard keyboard, final Keyboard lastKeyboard) {
+ final int lastElementId = lastKeyboard.mId.mElementId;
+ final int resId;
+ switch (keyboard.mId.mElementId) {
+ case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
+ case KeyboardId.ELEMENT_ALPHABET:
+ if (lastElementId == KeyboardId.ELEMENT_ALPHABET
+ || lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
+ // Transition between alphabet mode and automatic shifted mode should be silently
+ // ignored because it can be determined by each key's talk back announce.
+ return;
+ }
+ resId = R.string.spoken_description_mode_alpha;
+ break;
+ case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
+ if (lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
+ // Resetting automatic shifted mode by pressing the shift key causes the transition
+ // from automatic shifted to manual shifted that should be silently ignored.
+ return;
+ }
+ resId = R.string.spoken_description_shiftmode_on;
+ break;
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
+ if (lastElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) {
+ // Resetting caps locked mode by pressing the shift key causes the transition
+ // from shift locked to shift lock shifted that should be silently ignored.
+ return;
+ }
+ resId = R.string.spoken_description_shiftmode_locked;
+ break;
+ case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
+ resId = R.string.spoken_description_shiftmode_locked;
+ break;
+ case KeyboardId.ELEMENT_SYMBOLS:
+ resId = R.string.spoken_description_mode_symbol;
+ break;
+ case KeyboardId.ELEMENT_SYMBOLS_SHIFTED:
+ resId = R.string.spoken_description_mode_symbol_shift;
+ break;
+ case KeyboardId.ELEMENT_PHONE:
+ resId = R.string.spoken_description_mode_phone;
+ break;
+ case KeyboardId.ELEMENT_PHONE_SYMBOLS:
+ resId = R.string.spoken_description_mode_phone_shift;
+ break;
+ default:
+ return;
+ }
+ sendWindowStateChanged(resId);
+ }
+
+ /**
+ * Announces that the keyboard has been hidden.
+ */
+ private void announceKeyboardHidden() {
+ sendWindowStateChanged(R.string.announce_keyboard_hidden);
+ }
+
+ @Override
+ protected void onRegisterHoverKey(final Key key, final MotionEvent event) {
+ final int x = key.getHitBox().centerX();
+ final int y = key.getHitBox().centerY();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onRegisterHoverKey: key=" + key
+ + " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y));
+ }
+ if (mBoundsToIgnoreHoverEvent.contains(x, y)) {
+ // This hover exit event points to the key that should be ignored.
+ // Clear the ignoring region to handle further hover events.
+ mBoundsToIgnoreHoverEvent.setEmpty();
+ return;
+ }
+ super.onRegisterHoverKey(key, event);
+ }
+
+ @Override
+ protected void onHoverEnterTo(final Key key) {
+ final int x = key.getHitBox().centerX();
+ final int y = key.getHitBox().centerY();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnterTo: key=" + key
+ + " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y));
+ }
+ mAccessibilityLongPressTimer.cancelLongPress();
+ if (mBoundsToIgnoreHoverEvent.contains(x, y)) {
+ return;
+ }
+ // This hover enter event points to the key that isn't in the ignoring region.
+ // Further hover events should be handled.
+ mBoundsToIgnoreHoverEvent.setEmpty();
+ super.onHoverEnterTo(key);
+ if (key.isLongPressEnabled()) {
+ mAccessibilityLongPressTimer.startLongPress(key);
+ }
+ }
+
+ @Override
+ protected void onHoverExitFrom(final Key key) {
+ final int x = key.getHitBox().centerX();
+ final int y = key.getHitBox().centerY();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExitFrom: key=" + key
+ + " inIgnoreBounds=" + mBoundsToIgnoreHoverEvent.contains(x, y));
+ }
+ mAccessibilityLongPressTimer.cancelLongPress();
+ super.onHoverExitFrom(key);
+ }
+
+ @Override
+ public void onLongPressed(final Key key) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onLongPressed: key=" + key);
+ }
+ final PointerTracker tracker = PointerTracker.getPointerTracker(HOVER_EVENT_POINTER_ID);
+ final long eventTime = SystemClock.uptimeMillis();
+ final int x = key.getHitBox().centerX();
+ final int y = key.getHitBox().centerY();
+ final MotionEvent downEvent = MotionEvent.obtain(
+ eventTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0 /* metaState */);
+ // Inject a fake down event to {@link PointerTracker} to handle a long press correctly.
+ tracker.processMotionEvent(downEvent, mKeyDetector);
+ // The above fake down event triggers an unnecessary long press timer that should be
+ // canceled.
+ tracker.cancelLongPressTimer();
+ downEvent.recycle();
+ // Invoke {@link MainKeyboardView#onLongPress(PointerTracker)} as if a long press timeout
+ // has passed.
+ mKeyboardView.onLongPress(tracker);
+ // If {@link Key#hasNoPanelAutoMoreKeys()} is true (such as "0 +" key on the phone layout)
+ // or a key invokes IME switcher dialog, we should just ignore the next
+ // {@link #onRegisterHoverKey(Key,MotionEvent)}. It can be determined by whether
+ // {@link PointerTracker} is in operation or not.
+ if (tracker.isInOperation()) {
+ // This long press shows a more keys keyboard and further hover events should be
+ // handled.
+ mBoundsToIgnoreHoverEvent.setEmpty();
+ return;
+ }
+ // This long press has handled at {@link MainKeyboardView#onLongPress(PointerTracker)}.
+ // We should ignore further hover events on this key.
+ mBoundsToIgnoreHoverEvent.set(key.getHitBox());
+ if (key.hasNoPanelAutoMoreKey()) {
+ // This long press has registered a code point without showing a more keys keyboard.
+ // We should talk back the code point if possible.
+ final int codePointOfNoPanelAutoMoreKey = key.getMoreKeys()[0].mCode;
+ final String text = KeyCodeDescriptionMapper.getInstance().getDescriptionForCodePoint(
+ mKeyboardView.getContext(), codePointOfNoPanelAutoMoreKey);
+ if (text != null) {
+ sendWindowStateChanged(text);
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java
new file mode 100644
index 000000000..3a56c5d2a
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/MoreKeysKeyboardAccessibilityDelegate.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.accessibility;
+
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
+import com.android.inputmethod.latin.Constants;
+
+/**
+ * This class represents a delegate that can be registered in {@link MoreKeysKeyboardView} to
+ * enhance accessibility support via composition rather via inheritance.
+ */
+public class MoreKeysKeyboardAccessibilityDelegate
+ extends KeyboardAccessibilityDelegate<MoreKeysKeyboardView> {
+ private static final String TAG = MoreKeysKeyboardAccessibilityDelegate.class.getSimpleName();
+
+ private final Rect mMoreKeysKeyboardValidBounds = new Rect();
+ private static final int CLOSING_INSET_IN_PIXEL = 1;
+ private int mOpenAnnounceResId;
+ private int mCloseAnnounceResId;
+
+ public MoreKeysKeyboardAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView,
+ final KeyDetector keyDetector) {
+ super(moreKeysKeyboardView, keyDetector);
+ }
+
+ public void setOpenAnnounce(final int resId) {
+ mOpenAnnounceResId = resId;
+ }
+
+ public void setCloseAnnounce(final int resId) {
+ mCloseAnnounceResId = resId;
+ }
+
+ public void onShowMoreKeysKeyboard() {
+ sendWindowStateChanged(mOpenAnnounceResId);
+ }
+
+ @Override
+ protected void onHoverEnter(final MotionEvent event) {
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverEnter: key=" + getHoverKeyOf(event));
+ }
+ super.onHoverEnter(event);
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ final int pointerId = event.getPointerId(actionIndex);
+ final long eventTime = event.getEventTime();
+ mKeyboardView.onDownEvent(x, y, pointerId, eventTime);
+ }
+
+ @Override
+ protected void onHoverMove(final MotionEvent event) {
+ super.onHoverMove(event);
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ final int pointerId = event.getPointerId(actionIndex);
+ final long eventTime = event.getEventTime();
+ mKeyboardView.onMoveEvent(x, y, pointerId, eventTime);
+ }
+
+ @Override
+ protected void onHoverExit(final MotionEvent event) {
+ final Key lastKey = getLastHoverKey();
+ if (DEBUG_HOVER) {
+ Log.d(TAG, "onHoverExit: key=" + getHoverKeyOf(event) + " last=" + lastKey);
+ }
+ if (lastKey != null) {
+ super.onHoverExitFrom(lastKey);
+ }
+ setLastHoverKey(null);
+ final int actionIndex = event.getActionIndex();
+ final int x = (int)event.getX(actionIndex);
+ final int y = (int)event.getY(actionIndex);
+ final int pointerId = event.getPointerId(actionIndex);
+ final long eventTime = event.getEventTime();
+ // A hover exit event at one pixel width or height area on the edges of more keys keyboard
+ // are treated as closing.
+ mMoreKeysKeyboardValidBounds.set(0, 0, mKeyboardView.getWidth(), mKeyboardView.getHeight());
+ mMoreKeysKeyboardValidBounds.inset(CLOSING_INSET_IN_PIXEL, CLOSING_INSET_IN_PIXEL);
+ if (mMoreKeysKeyboardValidBounds.contains(x, y)) {
+ // Invoke {@link MoreKeysKeyboardView#onUpEvent(int,int,int,long)} as if this hover
+ // exit event selects a key.
+ mKeyboardView.onUpEvent(x, y, pointerId, eventTime);
+ mKeyboardView.dismissMoreKeysPanel();
+ return;
+ }
+ // Close the more keys keyboard.
+ mKeyboardView.onMoveEvent(
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, pointerId, eventTime);
+ sendWindowStateChanged(mCloseAnnounceResId);
+ }
+}
diff --git a/java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java
new file mode 100644
index 000000000..dfc866113
--- /dev/null
+++ b/java/src/com/android/inputmethod/accessibility/MoreSuggestionsAccessibilityDelegate.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.accessibility;
+
+import android.view.MotionEvent;
+
+import com.android.inputmethod.keyboard.KeyDetector;
+import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
+
+public final class MoreSuggestionsAccessibilityDelegate
+ extends MoreKeysKeyboardAccessibilityDelegate {
+ public MoreSuggestionsAccessibilityDelegate(final MoreKeysKeyboardView moreKeysKeyboardView,
+ final KeyDetector keyDetector) {
+ super(moreKeysKeyboardView, keyDetector);
+ }
+
+ @Override
+ protected void simulateTouchEvent(final int touchAction, final MotionEvent hoverEvent) {
+ final MotionEvent touchEvent = synthesizeTouchEvent(touchAction, hoverEvent);
+ mKeyboardView.onTouchEvent(touchEvent);
+ touchEvent.recycle();
+ }
+}
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index 60f7e2def..4d51821f2 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -27,7 +27,6 @@ import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -73,13 +72,13 @@ public final class SuggestionSpanUtils {
return pickedWord;
}
- final ArrayList<String> suggestionsList = CollectionUtils.newArrayList();
+ final ArrayList<String> suggestionsList = new ArrayList<>();
for (int i = 0; i < suggestedWords.size(); ++i) {
if (suggestionsList.size() >= SuggestionSpan.SUGGESTIONS_MAX_SIZE) {
break;
}
final SuggestedWordInfo info = suggestedWords.getInfo(i);
- if (info.mKind == SuggestedWordInfo.KIND_PREDICTION) {
+ if (info.isKindOf(SuggestedWordInfo.KIND_PREDICTION)) {
continue;
}
final String word = suggestedWords.getWord(i);
diff --git a/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java b/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java
index a0d76415c..6e32e74ab 100644
--- a/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/UserDictionaryCompatUtils.java
@@ -29,8 +29,8 @@ public final class UserDictionaryCompatUtils {
Context.class, String.class, Integer.TYPE, String.class, Locale.class);
@SuppressWarnings("deprecation")
- public static void addWord(final Context context, final String word, final int freq,
- final String shortcut, final Locale locale) {
+ public static void addWord(final Context context, final String word,
+ final int freq, final String shortcut, final Locale locale) {
if (hasNewerAddWord()) {
CompatUtils.invoke(Words.class, null, METHOD_addWord, context, word, freq, shortcut,
locale);
diff --git a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
index dec739d39..767cc423d 100644
--- a/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
+++ b/java/src/com/android/inputmethod/compat/ViewCompatUtils.java
@@ -24,23 +24,13 @@ import java.lang.reflect.Method;
// Currently {@link #getPaddingEnd(View)} and {@link #setPaddingRelative(View,int,int,int,int)}
// are missing from android-support-v4 static library in KitKat SDK.
public final class ViewCompatUtils {
- // Note that View.LAYOUT_DIRECTION_LTR and View.LAYOUT_DIRECTION_RTL have been introduced in
- // API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1).
- public static final int LAYOUT_DIRECTION_LTR = (Integer)CompatUtils.getFieldValue(null, 0x0,
- CompatUtils.getField(View.class, "LAYOUT_DIRECTION_LTR"));
- public static final int LAYOUT_DIRECTION_RTL = (Integer)CompatUtils.getFieldValue(null, 0x1,
- CompatUtils.getField(View.class, "LAYOUT_DIRECTION_RTL"));
-
- // Note that View.getPaddingEnd(), View.setPaddingRelative(int,int,int,int), and
- // View.getLayoutDirection() have been introduced in API level 17
- // (Build.VERSION_CODE.JELLY_BEAN_MR1).
+ // Note that View.getPaddingEnd(), View.setPaddingRelative(int,int,int,int) have been
+ // introduced in API level 17 (Build.VERSION_CODE.JELLY_BEAN_MR1).
private static final Method METHOD_getPaddingEnd = CompatUtils.getMethod(
View.class, "getPaddingEnd");
private static final Method METHOD_setPaddingRelative = CompatUtils.getMethod(
View.class, "setPaddingRelative",
Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE);
- private static final Method METHOD_getLayoutDirection = CompatUtils.getMethod(
- View.class, "getLayoutDirection");
private ViewCompatUtils() {
// This utility class is not publicly instantiable.
@@ -61,11 +51,4 @@ public final class ViewCompatUtils {
}
CompatUtils.invoke(view, null, METHOD_setPaddingRelative, start, top, end, bottom);
}
-
- public static int getLayoutDirection(final View view) {
- if (METHOD_getLayoutDirection == null) {
- return LAYOUT_DIRECTION_LTR;
- }
- return (Integer)CompatUtils.invoke(view, 0, METHOD_getLayoutDirection);
- }
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
index 706bdea8e..3d294acd7 100644
--- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
+++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.dictionarypack;
-import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.ContentValues;
import android.content.Context;
@@ -325,8 +324,9 @@ public final class ActionBatch {
MetadataDbHelper.TYPE_BULK, MetadataDbHelper.STATUS_AVAILABLE,
mWordList.mId, mWordList.mLocale, mWordList.mDescription,
null == mWordList.mLocalFilename ? "" : mWordList.mLocalFilename,
- mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mChecksum,
- mWordList.mFileSize, mWordList.mVersion, mWordList.mFormatVersion);
+ mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mRawChecksum,
+ mWordList.mChecksum, mWordList.mFileSize, mWordList.mVersion,
+ mWordList.mFormatVersion);
PrivateLog.log("Insert 'available' record for " + mWordList.mDescription
+ " and locale " + mWordList.mLocale);
db.insert(MetadataDbHelper.METADATA_TABLE_NAME, null, values);
@@ -374,7 +374,7 @@ public final class ActionBatch {
final ContentValues values = MetadataDbHelper.makeContentValues(0,
MetadataDbHelper.TYPE_BULK, MetadataDbHelper.STATUS_INSTALLED,
mWordList.mId, mWordList.mLocale, mWordList.mDescription,
- "", mWordList.mRemoteFilename, mWordList.mLastUpdate,
+ "", mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mRawChecksum,
mWordList.mChecksum, mWordList.mFileSize, mWordList.mVersion,
mWordList.mFormatVersion);
PrivateLog.log("Insert 'preinstalled' record for " + mWordList.mDescription
@@ -416,8 +416,9 @@ public final class ActionBatch {
oldValues.getAsInteger(MetadataDbHelper.STATUS_COLUMN),
mWordList.mId, mWordList.mLocale, mWordList.mDescription,
oldValues.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN),
- mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mChecksum,
- mWordList.mFileSize, mWordList.mVersion, mWordList.mFormatVersion);
+ mWordList.mRemoteFilename, mWordList.mLastUpdate, mWordList.mRawChecksum,
+ mWordList.mChecksum, mWordList.mFileSize, mWordList.mVersion,
+ mWordList.mFormatVersion);
PrivateLog.log("Updating record for " + mWordList.mDescription
+ " and locale " + mWordList.mLocale);
db.update(MetadataDbHelper.METADATA_TABLE_NAME, values,
@@ -598,7 +599,7 @@ public final class ActionBatch {
private final Queue<Action> mActions;
public ActionBatch() {
- mActions = new LinkedList<Action>();
+ mActions = new LinkedList<>();
}
public void add(final Action a) {
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java
index 2623eff56..1d84e5888 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryDownloadProgressBar.java
@@ -29,7 +29,6 @@ import android.view.View;
import android.widget.ProgressBar;
public class DictionaryDownloadProgressBar extends ProgressBar {
- @SuppressWarnings("unused")
private static final String TAG = DictionaryDownloadProgressBar.class.getSimpleName();
private static final int NOT_A_DOWNLOADMANAGER_PENDING_ID = 0;
@@ -119,7 +118,6 @@ public class DictionaryDownloadProgressBar extends ProgressBar {
try {
final UpdateHelper updateHelper = new UpdateHelper();
final Query query = new Query().setFilterById(mId);
- int lastProgress = 0;
setIndeterminate(true);
while (!isInterrupted()) {
final Cursor cursor = mDownloadManagerWrapper.query(query);
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
index 13c07de35..8e026171d 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
@@ -18,8 +18,6 @@ package com.android.inputmethod.dictionarypack;
import android.view.View;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
import java.util.ArrayList;
import java.util.HashMap;
@@ -39,8 +37,8 @@ public class DictionaryListInterfaceState {
public int mStatus = MetadataDbHelper.STATUS_UNKNOWN;
}
- private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap();
- private ArrayList<View> mViewCache = CollectionUtils.newArrayList();
+ private HashMap<String, State> mWordlistToState = new HashMap<>();
+ private ArrayList<View> mViewCache = new ArrayList<>();
public boolean isOpen(final String wordlistId) {
final State state = mWordlistToState.get(wordlistId);
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
index 80def701d..f5bd84c8c 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryProvider.java
@@ -89,10 +89,13 @@ public final class DictionaryProvider extends ContentProvider {
private static final class WordListInfo {
public final String mId;
public final String mLocale;
+ public final String mRawChecksum;
public final int mMatchLevel;
- public WordListInfo(final String id, final String locale, final int matchLevel) {
+ public WordListInfo(final String id, final String locale, final String rawChecksum,
+ final int matchLevel) {
mId = id;
mLocale = locale;
+ mRawChecksum = rawChecksum;
mMatchLevel = matchLevel;
}
}
@@ -106,7 +109,8 @@ public final class DictionaryProvider extends ContentProvider {
private static final class ResourcePathCursor extends AbstractCursor {
// Column names for the cursor returned by this content provider.
- static private final String[] columnNames = { "id", "locale" };
+ static private final String[] columnNames = { MetadataDbHelper.WORDLISTID_COLUMN,
+ MetadataDbHelper.LOCALE_COLUMN, MetadataDbHelper.RAW_CHECKSUM_COLUMN };
// The list of word lists served by this provider that match the client request.
final WordListInfo[] mWordLists;
@@ -141,6 +145,7 @@ public final class DictionaryProvider extends ContentProvider {
switch (column) {
case 0: return mWordLists[mPos].mId;
case 1: return mWordLists[mPos].mLocale;
+ case 2: return mWordLists[mPos].mRawChecksum;
default : return null;
}
}
@@ -352,11 +357,13 @@ public final class DictionaryProvider extends ContentProvider {
return Collections.<WordListInfo>emptyList();
}
try {
- final HashMap<String, WordListInfo> dicts = new HashMap<String, WordListInfo>();
+ final HashMap<String, WordListInfo> dicts = new HashMap<>();
final int idIndex = results.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN);
final int localeIndex = results.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN);
final int localFileNameIndex =
results.getColumnIndex(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
+ final int rawChecksumIndex =
+ results.getColumnIndex(MetadataDbHelper.RAW_CHECKSUM_COLUMN);
final int statusIndex = results.getColumnIndex(MetadataDbHelper.STATUS_COLUMN);
if (results.moveToFirst()) {
do {
@@ -379,6 +386,7 @@ public final class DictionaryProvider extends ContentProvider {
}
final String wordListLocale = results.getString(localeIndex);
final String wordListLocalFilename = results.getString(localFileNameIndex);
+ final String wordListRawChecksum = results.getString(rawChecksumIndex);
final int wordListStatus = results.getInt(statusIndex);
// Test the requested locale against this wordlist locale. The requested locale
// has to either match exactly or be more specific than the dictionary - a
@@ -412,8 +420,8 @@ public final class DictionaryProvider extends ContentProvider {
final WordListInfo currentBestMatch = dicts.get(wordListCategory);
if (null == currentBestMatch
|| currentBestMatch.mMatchLevel < matchLevel) {
- dicts.put(wordListCategory,
- new WordListInfo(wordListId, wordListLocale, matchLevel));
+ dicts.put(wordListCategory, new WordListInfo(wordListId, wordListLocale,
+ wordListRawChecksum, matchLevel));
}
} while (results.moveToNext());
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
index dae2f22a4..11982fa65 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java
@@ -33,13 +33,13 @@ import android.preference.PreferenceGroup;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
-import android.view.animation.AnimationUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import com.android.inputmethod.latin.R;
@@ -67,8 +67,8 @@ public final class DictionarySettingsFragment extends PreferenceFragment
private boolean mChangedSettings;
private DictionaryListInterfaceState mDictionaryListInterfaceState =
new DictionaryListInterfaceState();
- private TreeMap<String, WordListPreference> mCurrentPreferenceMap =
- new TreeMap<String, WordListPreference>(); // never null
+ // never null
+ private TreeMap<String, WordListPreference> mCurrentPreferenceMap = new TreeMap<>();
private final BroadcastReceiver mConnectivityChangedReceiver = new BroadcastReceiver() {
@Override
@@ -280,19 +280,18 @@ public final class DictionarySettingsFragment extends PreferenceFragment
: activity.getContentResolver().query(contentUri, null, null, null, null);
if (null == cursor) {
- final ArrayList<Preference> result = new ArrayList<Preference>();
+ final ArrayList<Preference> result = new ArrayList<>();
result.add(createErrorMessage(activity, R.string.cannot_connect_to_dict_service));
return result;
}
try {
if (!cursor.moveToFirst()) {
- final ArrayList<Preference> result = new ArrayList<Preference>();
+ final ArrayList<Preference> result = new ArrayList<>();
result.add(createErrorMessage(activity, R.string.no_dictionaries_available));
return result;
} else {
final String systemLocaleString = Locale.getDefault().toString();
- final TreeMap<String, WordListPreference> prefMap =
- new TreeMap<String, WordListPreference>();
+ final TreeMap<String, WordListPreference> prefMap = new TreeMap<>();
final int idIndex = cursor.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN);
final int versionIndex = cursor.getColumnIndex(MetadataDbHelper.VERSION_COLUMN);
final int localeIndex = cursor.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN);
diff --git a/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java b/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java
index 77f67b8a3..4f0805c5c 100644
--- a/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java
+++ b/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java
@@ -175,7 +175,7 @@ public final class LocaleUtils {
return saveLocale;
}
- private static final HashMap<String, Locale> sLocaleCache = new HashMap<String, Locale>();
+ private static final HashMap<String, Locale> sLocaleCache = new HashMap<>();
/**
* Creates a locale from a string specification.
diff --git a/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java b/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java
index e47e86e4b..ccd054c84 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MD5Calculator.java
@@ -20,7 +20,7 @@ import java.io.InputStream;
import java.io.IOException;
import java.security.MessageDigest;
-final class MD5Calculator {
+public final class MD5Calculator {
private MD5Calculator() {} // This helper class is not instantiable
public static String checksum(final InputStream in) throws IOException {
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index 4a8fa51ee..17dd781d5 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -20,6 +20,7 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import android.util.Log;
@@ -46,7 +47,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
// used to identify the versions for upgrades. This should never change going forward.
private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 6;
// The current database version.
- private static final int CURRENT_METADATA_DATABASE_VERSION = 7;
+ private static final int CURRENT_METADATA_DATABASE_VERSION = 9;
private final static long NOT_A_DOWNLOAD_ID = -1;
@@ -66,7 +67,8 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
public static final String VERSION_COLUMN = "version";
public static final String FORMATVERSION_COLUMN = "formatversion";
public static final String FLAGS_COLUMN = "flags";
- public static final int COLUMN_COUNT = 13;
+ public static final String RAW_CHECKSUM_COLUMN = "rawChecksum";
+ public static final int COLUMN_COUNT = 14;
private static final String CLIENT_CLIENT_ID_COLUMN = "clientid";
private static final String CLIENT_METADATA_URI_COLUMN = "uri";
@@ -119,8 +121,9 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
+ CHECKSUM_COLUMN + " TEXT, "
+ FILESIZE_COLUMN + " INTEGER, "
+ VERSION_COLUMN + " INTEGER,"
- + FORMATVERSION_COLUMN + " INTEGER,"
- + FLAGS_COLUMN + " INTEGER,"
+ + FORMATVERSION_COLUMN + " INTEGER, "
+ + FLAGS_COLUMN + " INTEGER, "
+ + RAW_CHECKSUM_COLUMN + " TEXT,"
+ "PRIMARY KEY (" + WORDLISTID_COLUMN + "," + VERSION_COLUMN + "));";
private static final String METADATA_CREATE_CLIENT_TABLE =
"CREATE TABLE IF NOT EXISTS " + CLIENT_TABLE_NAME + " ("
@@ -136,7 +139,8 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
static final String[] METADATA_TABLE_COLUMNS = { PENDINGID_COLUMN, TYPE_COLUMN,
STATUS_COLUMN, WORDLISTID_COLUMN, LOCALE_COLUMN, DESCRIPTION_COLUMN,
LOCAL_FILENAME_COLUMN, REMOTE_FILENAME_COLUMN, DATE_COLUMN, CHECKSUM_COLUMN,
- FILESIZE_COLUMN, VERSION_COLUMN, FORMATVERSION_COLUMN, FLAGS_COLUMN };
+ FILESIZE_COLUMN, VERSION_COLUMN, FORMATVERSION_COLUMN, FLAGS_COLUMN,
+ RAW_CHECKSUM_COLUMN };
// List of all client table columns.
static final String[] CLIENT_TABLE_COLUMNS = { CLIENT_CLIENT_ID_COLUMN,
CLIENT_METADATA_URI_COLUMN, CLIENT_PENDINGID_COLUMN, FLAGS_COLUMN };
@@ -156,7 +160,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
// this legacy database. New clients should make sure to always pass a client ID so as
// to avoid conflicts.
final String clientId = null != clientIdOrNull ? clientIdOrNull : "";
- if (null == sInstanceMap) sInstanceMap = new TreeMap<String, MetadataDbHelper>();
+ if (null == sInstanceMap) sInstanceMap = new TreeMap<>();
MetadataDbHelper helper = sInstanceMap.get(clientId);
if (null == helper) {
helper = new MetadataDbHelper(context, clientId);
@@ -215,6 +219,17 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
createClientTable(db);
}
+ private void addRawChecksumColumnUnlessPresent(final SQLiteDatabase db, final String clientId) {
+ try {
+ db.execSQL("SELECT " + RAW_CHECKSUM_COLUMN + " FROM "
+ + METADATA_TABLE_NAME + " LIMIT 0;");
+ } catch (SQLiteException e) {
+ Log.i(TAG, "No " + RAW_CHECKSUM_COLUMN + " column : creating it");
+ db.execSQL("ALTER TABLE " + METADATA_TABLE_NAME + " ADD COLUMN "
+ + RAW_CHECKSUM_COLUMN + " TEXT;");
+ }
+ }
+
/**
* Upgrade the database. Upgrade from version 3 is supported.
* Version 3 has a DB named METADATA_DATABASE_NAME_STEM containing a table METADATA_TABLE_NAME.
@@ -260,6 +275,12 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
db.execSQL("DROP TABLE IF EXISTS " + CLIENT_TABLE_NAME);
onCreate(db);
}
+ // A rawChecksum column that did not exist in the previous versions was added that
+ // corresponds to the md5 checksum of the file after decompression/decryption. This is to
+ // strengthen the system against corrupted dictionary files.
+ // The most secure way to upgrade a database is to just test for the column presence, and
+ // add it if it's not there.
+ addRawChecksumColumnUnlessPresent(db, mClientId);
}
/**
@@ -431,7 +452,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
public static ContentValues makeContentValues(final int pendingId, final int type,
final int status, final String wordlistId, final String locale,
final String description, final String filename, final String url, final long date,
- final String checksum, final long filesize, final int version,
+ final String rawChecksum, final String checksum, final long filesize, final int version,
final int formatVersion) {
final ContentValues result = new ContentValues(COLUMN_COUNT);
result.put(PENDINGID_COLUMN, pendingId);
@@ -443,6 +464,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
result.put(LOCAL_FILENAME_COLUMN, filename);
result.put(REMOTE_FILENAME_COLUMN, url);
result.put(DATE_COLUMN, date);
+ result.put(RAW_CHECKSUM_COLUMN, rawChecksum);
result.put(CHECKSUM_COLUMN, checksum);
result.put(FILESIZE_COLUMN, filesize);
result.put(VERSION_COLUMN, version);
@@ -478,6 +500,8 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
if (null == result.get(REMOTE_FILENAME_COLUMN)) result.put(REMOTE_FILENAME_COLUMN, "");
// 0 for the update date : 1970/1/1. Unless specified.
if (null == result.get(DATE_COLUMN)) result.put(DATE_COLUMN, 0);
+ // Raw checksum unknown unless specified
+ if (null == result.get(RAW_CHECKSUM_COLUMN)) result.put(RAW_CHECKSUM_COLUMN, "");
// Checksum unknown unless specified
if (null == result.get(CHECKSUM_COLUMN)) result.put(CHECKSUM_COLUMN, "");
// No filesize unless specified
@@ -525,6 +549,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
putStringResult(result, cursor, LOCAL_FILENAME_COLUMN);
putStringResult(result, cursor, REMOTE_FILENAME_COLUMN);
putIntResult(result, cursor, DATE_COLUMN);
+ putStringResult(result, cursor, RAW_CHECKSUM_COLUMN);
putStringResult(result, cursor, CHECKSUM_COLUMN);
putIntResult(result, cursor, FILESIZE_COLUMN);
putIntResult(result, cursor, VERSION_COLUMN);
@@ -614,7 +639,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
public static ArrayList<DownloadRecord> getDownloadRecordsForDownloadId(final Context context,
final long downloadId) {
final SQLiteDatabase defaultDb = getDb(context, "");
- final ArrayList<DownloadRecord> results = new ArrayList<DownloadRecord>();
+ final ArrayList<DownloadRecord> results = new ArrayList<>();
final Cursor cursor = defaultDb.query(CLIENT_TABLE_NAME, CLIENT_TABLE_COLUMNS,
null, null, null, null, null);
try {
@@ -898,7 +923,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
// - Remove the old entry from the table
// - Erase the old file
// We start by gathering the names of the files we should delete.
- final List<String> filenames = new LinkedList<String>();
+ final List<String> filenames = new LinkedList<>();
final Cursor c = db.query(METADATA_TABLE_NAME,
new String[] { LOCAL_FILENAME_COLUMN },
LOCALE_COLUMN + " = ? AND " +
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java b/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java
index 5c2289911..d66b69050 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataHandler.java
@@ -43,7 +43,7 @@ public class MetadataHandler {
* @return the constructed list of wordlist metadata.
*/
private static List<WordListMetadata> makeMetadataObject(final Cursor results) {
- final ArrayList<WordListMetadata> buildingMetadata = new ArrayList<WordListMetadata>();
+ final ArrayList<WordListMetadata> buildingMetadata = new ArrayList<>();
if (null != results && results.moveToFirst()) {
final int localeColumn = results.getColumnIndex(MetadataDbHelper.LOCALE_COLUMN);
final int typeColumn = results.getColumnIndex(MetadataDbHelper.TYPE_COLUMN);
@@ -52,6 +52,8 @@ public class MetadataHandler {
final int idIndex = results.getColumnIndex(MetadataDbHelper.WORDLISTID_COLUMN);
final int updateIndex = results.getColumnIndex(MetadataDbHelper.DATE_COLUMN);
final int fileSizeIndex = results.getColumnIndex(MetadataDbHelper.FILESIZE_COLUMN);
+ final int rawChecksumIndex =
+ results.getColumnIndex(MetadataDbHelper.RAW_CHECKSUM_COLUMN);
final int checksumIndex = results.getColumnIndex(MetadataDbHelper.CHECKSUM_COLUMN);
final int localFilenameIndex =
results.getColumnIndex(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
@@ -66,6 +68,7 @@ public class MetadataHandler {
results.getString(descriptionColumn),
results.getLong(updateIndex),
results.getLong(fileSizeIndex),
+ results.getString(rawChecksumIndex),
results.getString(checksumIndex),
results.getString(localFilenameIndex),
results.getString(remoteFilenameIndex),
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java b/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java
index 27670fddf..52290cadc 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataParser.java
@@ -37,6 +37,7 @@ public class MetadataParser {
private static final String DESCRIPTION_FIELD_NAME = MetadataDbHelper.DESCRIPTION_COLUMN;
private static final String UPDATE_FIELD_NAME = "update";
private static final String FILESIZE_FIELD_NAME = MetadataDbHelper.FILESIZE_COLUMN;
+ private static final String RAW_CHECKSUM_FIELD_NAME = MetadataDbHelper.RAW_CHECKSUM_COLUMN;
private static final String CHECKSUM_FIELD_NAME = MetadataDbHelper.CHECKSUM_COLUMN;
private static final String REMOTE_FILENAME_FIELD_NAME =
MetadataDbHelper.REMOTE_FILENAME_COLUMN;
@@ -51,7 +52,7 @@ public class MetadataParser {
*/
private static WordListMetadata parseOneWordList(final JsonReader reader)
throws IOException, BadFormatException {
- final TreeMap<String, String> arguments = new TreeMap<String, String>();
+ final TreeMap<String, String> arguments = new TreeMap<>();
reader.beginObject();
while (reader.hasNext()) {
final String name = reader.nextName();
@@ -80,6 +81,7 @@ public class MetadataParser {
arguments.get(DESCRIPTION_FIELD_NAME),
Long.parseLong(arguments.get(UPDATE_FIELD_NAME)),
Long.parseLong(arguments.get(FILESIZE_FIELD_NAME)),
+ arguments.get(RAW_CHECKSUM_FIELD_NAME),
arguments.get(CHECKSUM_FIELD_NAME),
null,
arguments.get(REMOTE_FILENAME_FIELD_NAME),
@@ -98,7 +100,7 @@ public class MetadataParser {
public static List<WordListMetadata> parseMetadata(final InputStreamReader input)
throws IOException, BadFormatException {
JsonReader reader = new JsonReader(input);
- final ArrayList<WordListMetadata> readInfo = new ArrayList<WordListMetadata>();
+ final ArrayList<WordListMetadata> readInfo = new ArrayList<>();
reader.beginArray();
while (reader.hasNext()) {
final WordListMetadata thisMetadata = parseOneWordList(reader);
diff --git a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
index dcff490db..95a094232 100644
--- a/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
+++ b/java/src/com/android/inputmethod/dictionarypack/UpdateHandler.java
@@ -177,7 +177,7 @@ public final class UpdateHandler {
*/
public static boolean tryUpdate(final Context context, final boolean updateNow) {
// TODO: loop through all clients instead of only doing the default one.
- final TreeSet<String> uris = new TreeSet<String>();
+ final TreeSet<String> uris = new TreeSet<>();
final Cursor cursor = MetadataDbHelper.queryClientIds(context);
if (null == cursor) return false;
try {
@@ -557,7 +557,7 @@ public final class UpdateHandler {
// Instantiation of a parameterized type is not possible in Java, so it's not possible to
// return the same type of list that was passed - probably the same reason why Collections
// does not do it. So we need to decide statically which concrete type to return.
- return new LinkedList<T>(src);
+ return new LinkedList<>(src);
}
/**
@@ -740,10 +740,10 @@ public final class UpdateHandler {
final ActionBatch actions = new ActionBatch();
// Upgrade existing word lists
DebugLogUtils.l("Comparing dictionaries");
- final Set<String> wordListIds = new TreeSet<String>();
+ final Set<String> wordListIds = new TreeSet<>();
// TODO: Can these be null?
- if (null == from) from = new ArrayList<WordListMetadata>();
- if (null == to) to = new ArrayList<WordListMetadata>();
+ if (null == from) from = new ArrayList<>();
+ if (null == to) to = new ArrayList<>();
for (WordListMetadata wlData : from) wordListIds.add(wlData.mId);
for (WordListMetadata wlData : to) wordListIds.add(wlData.mId);
for (String id : wordListIds) {
diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListMetadata.java b/java/src/com/android/inputmethod/dictionarypack/WordListMetadata.java
index 69bff9597..9e510a68b 100644
--- a/java/src/com/android/inputmethod/dictionarypack/WordListMetadata.java
+++ b/java/src/com/android/inputmethod/dictionarypack/WordListMetadata.java
@@ -30,6 +30,7 @@ public class WordListMetadata {
public final String mDescription;
public final long mLastUpdate;
public final long mFileSize;
+ public final String mRawChecksum;
public final String mChecksum;
public final String mLocalFilename;
public final String mRemoteFilename;
@@ -50,13 +51,15 @@ public class WordListMetadata {
public WordListMetadata(final String id, final int type,
final String description, final long lastUpdate, final long fileSize,
- final String checksum, final String localFilename, final String remoteFilename,
- final int version, final int formatVersion, final int flags, final String locale) {
+ final String rawChecksum, final String checksum, final String localFilename,
+ final String remoteFilename, final int version, final int formatVersion,
+ final int flags, final String locale) {
mId = id;
mType = type;
mDescription = description;
mLastUpdate = lastUpdate; // In milliseconds
mFileSize = fileSize;
+ mRawChecksum = rawChecksum;
mChecksum = checksum;
mLocalFilename = localFilename;
mRemoteFilename = remoteFilename;
@@ -77,6 +80,7 @@ public class WordListMetadata {
final String description = values.getAsString(MetadataDbHelper.DESCRIPTION_COLUMN);
final Long lastUpdate = values.getAsLong(MetadataDbHelper.DATE_COLUMN);
final Long fileSize = values.getAsLong(MetadataDbHelper.FILESIZE_COLUMN);
+ final String rawChecksum = values.getAsString(MetadataDbHelper.RAW_CHECKSUM_COLUMN);
final String checksum = values.getAsString(MetadataDbHelper.CHECKSUM_COLUMN);
final String localFilename = values.getAsString(MetadataDbHelper.LOCAL_FILENAME_COLUMN);
final String remoteFilename = values.getAsString(MetadataDbHelper.REMOTE_FILENAME_COLUMN);
@@ -98,8 +102,8 @@ public class WordListMetadata {
|| null == locale) {
throw new IllegalArgumentException();
}
- return new WordListMetadata(id, type, description, lastUpdate, fileSize, checksum,
- localFilename, remoteFilename, version, formatVersion, flags, locale);
+ return new WordListMetadata(id, type, description, lastUpdate, fileSize, rawChecksum,
+ checksum, localFilename, remoteFilename, version, formatVersion, flags, locale);
}
@Override
@@ -110,6 +114,7 @@ public class WordListMetadata {
sb.append("\nDescription : ").append(mDescription);
sb.append("\nLastUpdate : ").append(mLastUpdate);
sb.append("\nFileSize : ").append(mFileSize);
+ sb.append("\nRawChecksum : ").append(mRawChecksum);
sb.append("\nChecksum : ").append(mChecksum);
sb.append("\nLocalFilename : ").append(mLocalFilename);
sb.append("\nRemoteFilename : ").append(mRemoteFilename);
diff --git a/java/src/com/android/inputmethod/event/CombinerChain.java b/java/src/com/android/inputmethod/event/CombinerChain.java
index 8b59dc52a..61bc11b39 100644
--- a/java/src/com/android/inputmethod/event/CombinerChain.java
+++ b/java/src/com/android/inputmethod/event/CombinerChain.java
@@ -20,9 +20,9 @@ import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* This class implements the logic chain between receiving events and generating code points.
@@ -43,20 +43,32 @@ public class CombinerChain {
private SpannableStringBuilder mStateFeedback;
private final ArrayList<Combiner> mCombiners;
+ private static final HashMap<String, Class<? extends Combiner>> IMPLEMENTED_COMBINERS =
+ new HashMap<>();
+ static {
+ IMPLEMENTED_COMBINERS.put("MyanmarReordering", MyanmarReordering.class);
+ }
+ private static final String COMBINER_SPEC_SEPARATOR = ";";
+
/**
* Create an combiner chain.
*
* The combiner chain takes events as inputs and outputs code points and combining state.
* For example, if the input language is Japanese, the combining chain will typically perform
- * kana conversion.
+ * kana conversion. This takes a string for initial text, taken to be present before the
+ * cursor: we'll start after this.
*
+ * @param initialText The text that has already been combined so far.
* @param combinerList A list of combiners to be applied in order.
*/
- public CombinerChain(final Combiner... combinerList) {
- mCombiners = CollectionUtils.newArrayList();
+ public CombinerChain(final String initialText, final Combiner... combinerList) {
+ mCombiners = new ArrayList<>();
// The dead key combiner is always active, and always first
mCombiners.add(new DeadKeyCombiner());
- mCombinedText = new StringBuilder();
+ for (final Combiner combiner : combinerList) {
+ mCombiners.add(combiner);
+ }
+ mCombinedText = new StringBuilder(initialText);
mStateFeedback = new SpannableStringBuilder();
}
@@ -74,7 +86,7 @@ public class CombinerChain {
* @param newEvent the new event to process
*/
public void processEvent(final ArrayList<Event> previousEvents, final Event newEvent) {
- final ArrayList<Event> modifiablePreviousEvents = new ArrayList<Event>(previousEvents);
+ final ArrayList<Event> modifiablePreviousEvents = new ArrayList<>(previousEvents);
Event event = newEvent;
for (final Combiner combiner : mCombiners) {
// A combiner can never return more than one event; it can return several
@@ -114,4 +126,30 @@ public class CombinerChain {
final SpannableStringBuilder s = new SpannableStringBuilder(mCombinedText);
return s.append(mStateFeedback);
}
+
+ public static Combiner[] createCombiners(final String spec) {
+ if (TextUtils.isEmpty(spec)) {
+ return new Combiner[0];
+ }
+ final String[] combinerDescriptors = spec.split(COMBINER_SPEC_SEPARATOR);
+ final Combiner[] combiners = new Combiner[combinerDescriptors.length];
+ int i = 0;
+ for (final String combinerDescriptor : combinerDescriptors) {
+ final Class<? extends Combiner> combinerClass =
+ IMPLEMENTED_COMBINERS.get(combinerDescriptor);
+ if (null == combinerClass) {
+ throw new RuntimeException("Unknown combiner descriptor: " + combinerDescriptor);
+ }
+ try {
+ combiners[i++] = combinerClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new RuntimeException("Unable to instantiate combiner: " + combinerDescriptor,
+ e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Unable to instantiate combiner: " + combinerDescriptor,
+ e);
+ }
+ }
+ return combiners;
+ }
}
diff --git a/java/src/com/android/inputmethod/event/MyanmarReordering.java b/java/src/com/android/inputmethod/event/MyanmarReordering.java
new file mode 100644
index 000000000..32919932d
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/MyanmarReordering.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.event;
+
+import com.android.inputmethod.latin.Constants;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * A combiner that reorders input for Myanmar.
+ */
+public class MyanmarReordering implements Combiner {
+ // U+1031 MYANMAR VOWEL SIGN E
+ private final static int VOWEL_E = 0x1031; // Code point for vowel E that we need to reorder
+ // U+200C ZERO WIDTH NON-JOINER
+ // U+200B ZERO WIDTH SPACE
+ private final static int ZERO_WIDTH_NON_JOINER = 0x200B; // should be 0x200C
+
+ private final ArrayList<Event> mCurrentEvents = new ArrayList<>();
+
+ // List of consonants :
+ // U+1000 MYANMAR LETTER KA
+ // U+1001 MYANMAR LETTER KHA
+ // U+1002 MYANMAR LETTER GA
+ // U+1003 MYANMAR LETTER GHA
+ // U+1004 MYANMAR LETTER NGA
+ // U+1005 MYANMAR LETTER CA
+ // U+1006 MYANMAR LETTER CHA
+ // U+1007 MYANMAR LETTER JA
+ // U+1008 MYANMAR LETTER JHA
+ // U+1009 MYANMAR LETTER NYA
+ // U+100A MYANMAR LETTER NNYA
+ // U+100B MYANMAR LETTER TTA
+ // U+100C MYANMAR LETTER TTHA
+ // U+100D MYANMAR LETTER DDA
+ // U+100E MYANMAR LETTER DDHA
+ // U+100F MYANMAR LETTER NNA
+ // U+1010 MYANMAR LETTER TA
+ // U+1011 MYANMAR LETTER THA
+ // U+1012 MYANMAR LETTER DA
+ // U+1013 MYANMAR LETTER DHA
+ // U+1014 MYANMAR LETTER NA
+ // U+1015 MYANMAR LETTER PA
+ // U+1016 MYANMAR LETTER PHA
+ // U+1017 MYANMAR LETTER BA
+ // U+1018 MYANMAR LETTER BHA
+ // U+1019 MYANMAR LETTER MA
+ // U+101A MYANMAR LETTER YA
+ // U+101B MYANMAR LETTER RA
+ // U+101C MYANMAR LETTER LA
+ // U+101D MYANMAR LETTER WA
+ // U+101E MYANMAR LETTER SA
+ // U+101F MYANMAR LETTER HA
+ // U+1020 MYANMAR LETTER LLA
+ // U+103F MYANMAR LETTER GREAT SA
+ private static boolean isConsonant(final int codePoint) {
+ return (codePoint >= 0x1000 && codePoint <= 0x1020) || 0x103F == codePoint;
+ }
+
+ // List of medials :
+ // U+103B MYANMAR CONSONANT SIGN MEDIAL YA
+ // U+103C MYANMAR CONSONANT SIGN MEDIAL RA
+ // U+103D MYANMAR CONSONANT SIGN MEDIAL WA
+ // U+103E MYANMAR CONSONANT SIGN MEDIAL HA
+ // U+105E MYANMAR CONSONANT SIGN MON MEDIAL NA
+ // U+105F MYANMAR CONSONANT SIGN MON MEDIAL MA
+ // U+1060 MYANMAR CONSONANT SIGN MON MEDIAL LA
+ // U+1082 MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+ private static int[] MEDIAL_LIST = { 0x103B, 0x103C, 0x103D, 0x103E,
+ 0x105E, 0x105F, 0x1060, 0x1082};
+ private static boolean isMedial(final int codePoint) {
+ return Arrays.binarySearch(MEDIAL_LIST, codePoint) >= 0;
+ }
+
+ private static boolean isConsonantOrMedial(final int codePoint) {
+ return isConsonant(codePoint) || isMedial(codePoint);
+ }
+
+ private Event getLastEvent() {
+ final int size = mCurrentEvents.size();
+ if (size <= 0) {
+ return null;
+ }
+ return mCurrentEvents.get(size - 1);
+ }
+
+ private CharSequence getCharSequence() {
+ final StringBuilder s = new StringBuilder();
+ for (final Event e : mCurrentEvents) {
+ s.appendCodePoint(e.mCodePoint);
+ }
+ return s;
+ }
+
+ /**
+ * Clears the currently combining stream of events and returns the resulting software text
+ * event corresponding to the stream. Optionally adds a new event to the cleared stream.
+ * @param newEvent the new event to add to the stream. null if none.
+ * @return the resulting software text event. Null if none.
+ */
+ private Event clearAndGetResultingEvent(final Event newEvent) {
+ final CharSequence combinedText;
+ if (mCurrentEvents.size() > 0) {
+ combinedText = getCharSequence();
+ mCurrentEvents.clear();
+ } else {
+ combinedText = null;
+ }
+ if (null != newEvent) {
+ mCurrentEvents.add(newEvent);
+ }
+ return null == combinedText ? null
+ : Event.createSoftwareTextEvent(combinedText, Event.NOT_A_KEY_CODE);
+ }
+
+ @Override
+ public Event processEvent(ArrayList<Event> previousEvents, Event newEvent) {
+ final int codePoint = newEvent.mCodePoint;
+ if (VOWEL_E == codePoint) {
+ final Event lastEvent = getLastEvent();
+ if (null == lastEvent) {
+ mCurrentEvents.add(newEvent);
+ return null;
+ } else if (isConsonantOrMedial(lastEvent.mCodePoint)) {
+ final Event resultingEvent = clearAndGetResultingEvent(null);
+ mCurrentEvents.add(Event.createSoftwareKeypressEvent(ZERO_WIDTH_NON_JOINER,
+ Event.NOT_A_KEY_CODE,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE,
+ false /* isKeyRepeat */));
+ mCurrentEvents.add(newEvent);
+ return resultingEvent;
+ } else { // VOWEL_E == lastCodePoint. But if that was anything else this is correct too.
+ return clearAndGetResultingEvent(newEvent);
+ }
+ } if (isConsonant(codePoint)) {
+ final Event lastEvent = getLastEvent();
+ if (null == lastEvent) {
+ mCurrentEvents.add(newEvent);
+ return null;
+ } else if (VOWEL_E == lastEvent.mCodePoint) {
+ final int eventSize = mCurrentEvents.size();
+ if (eventSize >= 2
+ && mCurrentEvents.get(eventSize - 2).mCodePoint == ZERO_WIDTH_NON_JOINER) {
+ // We have a ZWJN before a vowel E. We need to remove the ZWNJ and then
+ // reorder the vowel with respect to the consonant.
+ mCurrentEvents.remove(eventSize - 1);
+ mCurrentEvents.remove(eventSize - 2);
+ mCurrentEvents.add(newEvent);
+ mCurrentEvents.add(lastEvent);
+ return null;
+ }
+ // If there is already a consonant, then we are starting a new syllable.
+ for (int i = eventSize - 2; i >= 0; --i) {
+ if (isConsonant(mCurrentEvents.get(i).mCodePoint)) {
+ return clearAndGetResultingEvent(newEvent);
+ }
+ }
+ // If we come here, we didn't have a consonant so we reorder
+ mCurrentEvents.remove(eventSize - 1);
+ mCurrentEvents.add(newEvent);
+ mCurrentEvents.add(lastEvent);
+ return null;
+ } else { // lastCodePoint is a consonant/medial. But if it's something else it's fine
+ return clearAndGetResultingEvent(newEvent);
+ }
+ } else if (isMedial(codePoint)) {
+ final Event lastEvent = getLastEvent();
+ if (null == lastEvent) {
+ mCurrentEvents.add(newEvent);
+ return null;
+ } else if (VOWEL_E == lastEvent.mCodePoint) {
+ final int eventSize = mCurrentEvents.size();
+ // If there is already a consonant, then we are in the middle of a syllable, and we
+ // need to reorder.
+ boolean hasConsonant = false;
+ for (int i = eventSize - 2; i >= 0; --i) {
+ if (isConsonant(mCurrentEvents.get(i).mCodePoint)) {
+ hasConsonant = true;
+ break;
+ }
+ }
+ if (hasConsonant) {
+ mCurrentEvents.remove(eventSize - 1);
+ mCurrentEvents.add(newEvent);
+ mCurrentEvents.add(lastEvent);
+ return null;
+ }
+ // Otherwise, we just commit everything.
+ return clearAndGetResultingEvent(null);
+ } else { // lastCodePoint is a consonant/medial. But if it's something else it's fine
+ return clearAndGetResultingEvent(newEvent);
+ }
+ } else if (Constants.CODE_DELETE == newEvent.mKeyCode) {
+ final Event lastEvent = getLastEvent();
+ final int eventSize = mCurrentEvents.size();
+ if (null != lastEvent) {
+ if (VOWEL_E == lastEvent.mCodePoint) {
+ // We have a VOWEL_E at the end. There are four cases.
+ // - The vowel is the only code point in the buffer. Remove it.
+ // - The vowel is preceded by a ZWNJ. Remove both vowel E and ZWNJ.
+ // - The vowel is preceded by a consonant/medial, remove the consonant/medial.
+ // - In all other cases, it's strange, so just remove the last code point.
+ if (eventSize <= 1) {
+ mCurrentEvents.clear();
+ } else { // eventSize >= 2
+ final int previousCodePoint = mCurrentEvents.get(eventSize - 2).mCodePoint;
+ if (previousCodePoint == ZERO_WIDTH_NON_JOINER) {
+ mCurrentEvents.remove(eventSize - 1);
+ mCurrentEvents.remove(eventSize - 2);
+ } else if (isConsonantOrMedial(previousCodePoint)) {
+ mCurrentEvents.remove(eventSize - 2);
+ } else {
+ mCurrentEvents.remove(eventSize - 1);
+ }
+ }
+ return null;
+ } else if (eventSize > 0) {
+ mCurrentEvents.remove(eventSize - 1);
+ return null;
+ }
+ }
+ }
+ // This character is not part of the combining scheme, so we should reset everything.
+ if (mCurrentEvents.size() > 0) {
+ // If we have events in flight, then add the new event and return the resulting event.
+ mCurrentEvents.add(newEvent);
+ return clearAndGetResultingEvent(null);
+ } else {
+ // If we don't have any events in flight, then just pass this one through.
+ return newEvent;
+ }
+ }
+
+ @Override
+ public CharSequence getCombiningStateFeedback() {
+ return getCharSequence();
+ }
+
+ @Override
+ public void reset() {
+ mCurrentEvents.clear();
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
deleted file mode 100644
index d8b5758a6..000000000
--- a/java/src/com/android/inputmethod/keyboard/EmojiPalettesView.java
+++ /dev/null
@@ -1,974 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.keyboard;
-
-import static com.android.inputmethod.latin.Constants.NOT_A_COORDINATE;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.os.Build;
-import android.os.CountDownTimer;
-import android.preference.PreferenceManager;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.Pair;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TabHost;
-import android.widget.TabHost.OnTabChangeListener;
-import android.widget.TextView;
-
-import com.android.inputmethod.keyboard.internal.DynamicGridKeyboard;
-import com.android.inputmethod.keyboard.internal.EmojiLayoutParams;
-import com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView;
-import com.android.inputmethod.keyboard.internal.KeyDrawParams;
-import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
-import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.settings.Settings;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.ResourceUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-
-/**
- * View class to implement Emoji palettes.
- * The Emoji keyboard consists of group of views {@link R.layout#emoji_palettes_view}.
- * <ol>
- * <li> Emoji category tabs.
- * <li> Delete button.
- * <li> Emoji keyboard pages that can be scrolled by swiping horizontally or by selecting a tab.
- * <li> Back to main keyboard button and enter button.
- * </ol>
- * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
- */
-public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener,
- ViewPager.OnPageChangeListener, View.OnClickListener, View.OnTouchListener,
- EmojiPageKeyboardView.OnKeyEventListener {
- static final String TAG = EmojiPalettesView.class.getSimpleName();
- private static final boolean DEBUG_PAGER = false;
- private final int mKeyBackgroundId;
- private final int mEmojiFunctionalKeyBackgroundId;
- private final ColorStateList mTabLabelColor;
- private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
- private EmojiPalettesAdapter mEmojiPalettesAdapter;
- private final EmojiLayoutParams mEmojiLayoutParams;
-
- private TextView mAlphabetKeyLeft;
- private TextView mAlphabetKeyRight;
- private TabHost mTabHost;
- private ViewPager mEmojiPager;
- private int mCurrentPagerPosition = 0;
- private EmojiCategoryPageIndicatorView mEmojiCategoryPageIndicatorView;
-
- private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
-
- private static final int CATEGORY_ID_UNSPECIFIED = -1;
- public static final int CATEGORY_ID_RECENTS = 0;
- public static final int CATEGORY_ID_PEOPLE = 1;
- public static final int CATEGORY_ID_OBJECTS = 2;
- public static final int CATEGORY_ID_NATURE = 3;
- public static final int CATEGORY_ID_PLACES = 4;
- public static final int CATEGORY_ID_SYMBOLS = 5;
- public static final int CATEGORY_ID_EMOTICONS = 6;
-
- private static class CategoryProperties {
- public int mCategoryId;
- public int mPageCount;
- public CategoryProperties(final int categoryId, final int pageCount) {
- mCategoryId = categoryId;
- mPageCount = pageCount;
- }
- }
-
- private static class EmojiCategory {
- private static final String[] sCategoryName = {
- "recents",
- "people",
- "objects",
- "nature",
- "places",
- "symbols",
- "emoticons" };
- private static final int[] sCategoryIcon = {
- R.drawable.ic_emoji_recent_light,
- R.drawable.ic_emoji_people_light,
- R.drawable.ic_emoji_objects_light,
- R.drawable.ic_emoji_nature_light,
- R.drawable.ic_emoji_places_light,
- R.drawable.ic_emoji_symbols_light,
- 0 };
- private static final String[] sCategoryLabel =
- { null, null, null, null, null, null, ":-)" };
- private static final int[] sAccessibilityDescriptionResourceIdsForCategories = {
- R.string.spoken_descrption_emoji_category_recents,
- R.string.spoken_descrption_emoji_category_people,
- R.string.spoken_descrption_emoji_category_objects,
- R.string.spoken_descrption_emoji_category_nature,
- R.string.spoken_descrption_emoji_category_places,
- R.string.spoken_descrption_emoji_category_symbols,
- R.string.spoken_descrption_emoji_category_emoticons };
- private static final int[] sCategoryElementId = {
- KeyboardId.ELEMENT_EMOJI_RECENTS,
- KeyboardId.ELEMENT_EMOJI_CATEGORY1,
- KeyboardId.ELEMENT_EMOJI_CATEGORY2,
- KeyboardId.ELEMENT_EMOJI_CATEGORY3,
- KeyboardId.ELEMENT_EMOJI_CATEGORY4,
- KeyboardId.ELEMENT_EMOJI_CATEGORY5,
- KeyboardId.ELEMENT_EMOJI_CATEGORY6 };
- private final SharedPreferences mPrefs;
- private final Resources mRes;
- private final int mMaxPageKeyCount;
- private final KeyboardLayoutSet mLayoutSet;
- private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap();
- private final ArrayList<CategoryProperties> mShownCategories =
- CollectionUtils.newArrayList();
- private final ConcurrentHashMap<Long, DynamicGridKeyboard>
- mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>();
-
- private int mCurrentCategoryId = CATEGORY_ID_UNSPECIFIED;
- private int mCurrentCategoryPageId = 0;
-
- public EmojiCategory(final SharedPreferences prefs, final Resources res,
- final KeyboardLayoutSet layoutSet) {
- mPrefs = prefs;
- mRes = res;
- mMaxPageKeyCount = res.getInteger(R.integer.config_emoji_keyboard_max_page_key_count);
- mLayoutSet = layoutSet;
- for (int i = 0; i < sCategoryName.length; ++i) {
- mCategoryNameToIdMap.put(sCategoryName[i], i);
- }
- addShownCategoryId(CATEGORY_ID_RECENTS);
- if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2
- || android.os.Build.VERSION.CODENAME.equalsIgnoreCase("KeyLimePie")
- || android.os.Build.VERSION.CODENAME.equalsIgnoreCase("KitKat")) {
- addShownCategoryId(CATEGORY_ID_PEOPLE);
- addShownCategoryId(CATEGORY_ID_OBJECTS);
- addShownCategoryId(CATEGORY_ID_NATURE);
- addShownCategoryId(CATEGORY_ID_PLACES);
- mCurrentCategoryId =
- Settings.readLastShownEmojiCategoryId(mPrefs, CATEGORY_ID_PEOPLE);
- } else {
- mCurrentCategoryId =
- Settings.readLastShownEmojiCategoryId(mPrefs, CATEGORY_ID_SYMBOLS);
- }
- addShownCategoryId(CATEGORY_ID_SYMBOLS);
- addShownCategoryId(CATEGORY_ID_EMOTICONS);
- getKeyboard(CATEGORY_ID_RECENTS, 0 /* cagetoryPageId */)
- .loadRecentKeys(mCategoryKeyboardMap.values());
- }
-
- private void addShownCategoryId(final int categoryId) {
- // Load a keyboard of categoryId
- getKeyboard(categoryId, 0 /* cagetoryPageId */);
- final CategoryProperties properties =
- new CategoryProperties(categoryId, getCategoryPageCount(categoryId));
- mShownCategories.add(properties);
- }
-
- public String getCategoryName(final int categoryId, final int categoryPageId) {
- return sCategoryName[categoryId] + "-" + categoryPageId;
- }
-
- public int getCategoryId(final String name) {
- final String[] strings = name.split("-");
- return mCategoryNameToIdMap.get(strings[0]);
- }
-
- public int getCategoryIcon(final int categoryId) {
- return sCategoryIcon[categoryId];
- }
-
- public String getCategoryLabel(final int categoryId) {
- return sCategoryLabel[categoryId];
- }
-
- public String getAccessibilityDescription(final int categoryId) {
- return mRes.getString(sAccessibilityDescriptionResourceIdsForCategories[categoryId]);
- }
-
- public ArrayList<CategoryProperties> getShownCategories() {
- return mShownCategories;
- }
-
- public int getCurrentCategoryId() {
- return mCurrentCategoryId;
- }
-
- public int getCurrentCategoryPageSize() {
- return getCategoryPageSize(mCurrentCategoryId);
- }
-
- public int getCategoryPageSize(final int categoryId) {
- for (final CategoryProperties prop : mShownCategories) {
- if (prop.mCategoryId == categoryId) {
- return prop.mPageCount;
- }
- }
- Log.w(TAG, "Invalid category id: " + categoryId);
- // Should not reach here.
- return 0;
- }
-
- public void setCurrentCategoryId(final int categoryId) {
- mCurrentCategoryId = categoryId;
- Settings.writeLastShownEmojiCategoryId(mPrefs, categoryId);
- }
-
- public void setCurrentCategoryPageId(final int id) {
- mCurrentCategoryPageId = id;
- }
-
- public int getCurrentCategoryPageId() {
- return mCurrentCategoryPageId;
- }
-
- public void saveLastTypedCategoryPage() {
- Settings.writeLastTypedEmojiCategoryPageId(
- mPrefs, mCurrentCategoryId, mCurrentCategoryPageId);
- }
-
- public boolean isInRecentTab() {
- return mCurrentCategoryId == CATEGORY_ID_RECENTS;
- }
-
- public int getTabIdFromCategoryId(final int categoryId) {
- for (int i = 0; i < mShownCategories.size(); ++i) {
- if (mShownCategories.get(i).mCategoryId == categoryId) {
- return i;
- }
- }
- Log.w(TAG, "categoryId not found: " + categoryId);
- return 0;
- }
-
- // Returns the view pager's page position for the categoryId
- public int getPageIdFromCategoryId(final int categoryId) {
- final int lastSavedCategoryPageId =
- Settings.readLastTypedEmojiCategoryPageId(mPrefs, categoryId);
- int sum = 0;
- for (int i = 0; i < mShownCategories.size(); ++i) {
- final CategoryProperties props = mShownCategories.get(i);
- if (props.mCategoryId == categoryId) {
- return sum + lastSavedCategoryPageId;
- }
- sum += props.mPageCount;
- }
- Log.w(TAG, "categoryId not found: " + categoryId);
- return 0;
- }
-
- public int getRecentTabId() {
- return getTabIdFromCategoryId(CATEGORY_ID_RECENTS);
- }
-
- private int getCategoryPageCount(final int categoryId) {
- final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]);
- return (keyboard.getSortedKeys().size() - 1) / mMaxPageKeyCount + 1;
- }
-
- // Returns a pair of the category id and the category page id from the view pager's page
- // position. The category page id is numbered in each category. And the view page position
- // is the position of the current shown page in the view pager which contains all pages of
- // all categories.
- public Pair<Integer, Integer> getCategoryIdAndPageIdFromPagePosition(final int position) {
- int sum = 0;
- for (final CategoryProperties properties : mShownCategories) {
- final int temp = sum;
- sum += properties.mPageCount;
- if (sum > position) {
- return new Pair<Integer, Integer>(properties.mCategoryId, position - temp);
- }
- }
- return null;
- }
-
- // Returns a keyboard from the view pager's page position.
- public DynamicGridKeyboard getKeyboardFromPagePosition(final int position) {
- final Pair<Integer, Integer> categoryAndId =
- getCategoryIdAndPageIdFromPagePosition(position);
- if (categoryAndId != null) {
- return getKeyboard(categoryAndId.first, categoryAndId.second);
- }
- return null;
- }
-
- private static final Long getCategoryKeyboardMapKey(final int categoryId, final int id) {
- return (((long) categoryId) << Constants.MAX_INT_BIT_COUNT) | id;
- }
-
- public DynamicGridKeyboard getKeyboard(final int categoryId, final int id) {
- synchronized (mCategoryKeyboardMap) {
- final Long categotyKeyboardMapKey = getCategoryKeyboardMapKey(categoryId, id);
- if (mCategoryKeyboardMap.containsKey(categotyKeyboardMapKey)) {
- return mCategoryKeyboardMap.get(categotyKeyboardMapKey);
- }
-
- if (categoryId == CATEGORY_ID_RECENTS) {
- final DynamicGridKeyboard kbd = new DynamicGridKeyboard(mPrefs,
- mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
- mMaxPageKeyCount, categoryId);
- mCategoryKeyboardMap.put(categotyKeyboardMapKey, kbd);
- return kbd;
- }
-
- final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]);
- final Key[][] sortedKeys = sortKeysIntoPages(
- keyboard.getSortedKeys(), mMaxPageKeyCount);
- for (int pageId = 0; pageId < sortedKeys.length; ++pageId) {
- final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs,
- mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
- mMaxPageKeyCount, categoryId);
- for (final Key emojiKey : sortedKeys[pageId]) {
- if (emojiKey == null) {
- break;
- }
- tempKeyboard.addKeyLast(emojiKey);
- }
- mCategoryKeyboardMap.put(
- getCategoryKeyboardMapKey(categoryId, pageId), tempKeyboard);
- }
- return mCategoryKeyboardMap.get(categotyKeyboardMapKey);
- }
- }
-
- public int getTotalPageCountOfAllCategories() {
- int sum = 0;
- for (CategoryProperties properties : mShownCategories) {
- sum += properties.mPageCount;
- }
- return sum;
- }
-
- private static Comparator<Key> EMOJI_KEY_COMPARATOR = new Comparator<Key>() {
- @Override
- public int compare(final Key lhs, final Key rhs) {
- final Rect lHitBox = lhs.getHitBox();
- final Rect rHitBox = rhs.getHitBox();
- if (lHitBox.top < rHitBox.top) {
- return -1;
- } else if (lHitBox.top > rHitBox.top) {
- return 1;
- }
- if (lHitBox.left < rHitBox.left) {
- return -1;
- } else if (lHitBox.left > rHitBox.left) {
- return 1;
- }
- if (lhs.getCode() == rhs.getCode()) {
- return 0;
- }
- return lhs.getCode() < rhs.getCode() ? -1 : 1;
- }
- };
-
- private static Key[][] sortKeysIntoPages(final List<Key> inKeys, final int maxPageCount) {
- final ArrayList<Key> keys = CollectionUtils.newArrayList(inKeys);
- Collections.sort(keys, EMOJI_KEY_COMPARATOR);
- final int pageCount = (keys.size() - 1) / maxPageCount + 1;
- final Key[][] retval = new Key[pageCount][maxPageCount];
- for (int i = 0; i < keys.size(); ++i) {
- retval[i / maxPageCount][i % maxPageCount] = keys.get(i);
- }
- return retval;
- }
- }
-
- private final EmojiCategory mEmojiCategory;
-
- public EmojiPalettesView(final Context context, final AttributeSet attrs) {
- this(context, attrs, R.attr.emojiPalettesViewStyle);
- }
-
- public EmojiPalettesView(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs, defStyle);
- final TypedArray keyboardViewAttr = context.obtainStyledAttributes(attrs,
- R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
- mKeyBackgroundId = keyboardViewAttr.getResourceId(
- R.styleable.KeyboardView_keyBackground, 0);
- mEmojiFunctionalKeyBackgroundId = keyboardViewAttr.getResourceId(
- R.styleable.KeyboardView_keyBackgroundEmojiFunctional, 0);
- keyboardViewAttr.recycle();
- final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs,
- R.styleable.EmojiPalettesView, defStyle, R.style.EmojiPalettesView);
- mTabLabelColor = emojiPalettesViewAttr.getColorStateList(
- R.styleable.EmojiPalettesView_emojiTabLabelColor);
- emojiPalettesViewAttr.recycle();
- final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
- context, null /* editorInfo */);
- final Resources res = context.getResources();
- mEmojiLayoutParams = new EmojiLayoutParams(res);
- builder.setSubtype(SubtypeSwitcher.getInstance().getEmojiSubtype());
- builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
- mEmojiLayoutParams.mEmojiKeyboardHeight);
- builder.setOptions(false /* shortcutImeEnabled */, false /* showsVoiceInputKey */,
- false /* languageSwitchKeyEnabled */);
- mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context),
- context.getResources(), builder.build());
- mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(context);
- }
-
- @Override
- protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- final Resources res = getContext().getResources();
- // The main keyboard expands to the entire this {@link KeyboardView}.
- final int width = ResourceUtils.getDefaultKeyboardWidth(res)
- + getPaddingLeft() + getPaddingRight();
- final int height = ResourceUtils.getDefaultKeyboardHeight(res)
- + res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
- + getPaddingTop() + getPaddingBottom();
- setMeasuredDimension(width, height);
- }
-
- private void addTab(final TabHost host, final int categoryId) {
- final String tabId = mEmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */);
- final TabHost.TabSpec tspec = host.newTabSpec(tabId);
- tspec.setContent(R.id.emoji_keyboard_dummy);
- if (mEmojiCategory.getCategoryIcon(categoryId) != 0) {
- final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate(
- R.layout.emoji_keyboard_tab_icon, null);
- iconView.setImageResource(mEmojiCategory.getCategoryIcon(categoryId));
- iconView.setContentDescription(mEmojiCategory.getAccessibilityDescription(categoryId));
- tspec.setIndicator(iconView);
- }
- if (mEmojiCategory.getCategoryLabel(categoryId) != null) {
- final TextView textView = (TextView)LayoutInflater.from(getContext()).inflate(
- R.layout.emoji_keyboard_tab_label, null);
- textView.setText(mEmojiCategory.getCategoryLabel(categoryId));
- textView.setContentDescription(mEmojiCategory.getAccessibilityDescription(categoryId));
- textView.setTextColor(mTabLabelColor);
- tspec.setIndicator(textView);
- }
- host.addTab(tspec);
- }
-
- @Override
- protected void onFinishInflate() {
- mTabHost = (TabHost)findViewById(R.id.emoji_category_tabhost);
- mTabHost.setup();
- for (final CategoryProperties properties : mEmojiCategory.getShownCategories()) {
- addTab(mTabHost, properties.mCategoryId);
- }
- mTabHost.setOnTabChangedListener(this);
- mTabHost.getTabWidget().setStripEnabled(true);
-
- mEmojiPalettesAdapter = new EmojiPalettesAdapter(mEmojiCategory, this);
-
- mEmojiPager = (ViewPager)findViewById(R.id.emoji_keyboard_pager);
- mEmojiPager.setAdapter(mEmojiPalettesAdapter);
- mEmojiPager.setOnPageChangeListener(this);
- mEmojiPager.setOffscreenPageLimit(0);
- mEmojiPager.setPersistentDrawingCache(PERSISTENT_NO_CACHE);
- mEmojiLayoutParams.setPagerProperties(mEmojiPager);
-
- mEmojiCategoryPageIndicatorView =
- (EmojiCategoryPageIndicatorView)findViewById(R.id.emoji_category_page_id_view);
- mEmojiLayoutParams.setCategoryPageIdViewProperties(mEmojiCategoryPageIndicatorView);
-
- setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */);
-
- final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar);
- mEmojiLayoutParams.setActionBarProperties(actionBar);
-
- // deleteKey depends only on OnTouchListener.
- final ImageView deleteKey = (ImageView)findViewById(R.id.emoji_keyboard_delete);
- deleteKey.setTag(Constants.CODE_DELETE);
- deleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
-
- // {@link #mAlphabetKeyLeft}, {@link #mAlphabetKeyRight, and spaceKey depend on
- // {@link View.OnClickListener} as well as {@link View.OnTouchListener}.
- // {@link View.OnTouchListener} is used as the trigger of key-press, while
- // {@link View.OnClickListener} is used as the trigger of key-release which does not occur
- // if the event is canceled by moving off the finger from the view.
- // The text on alphabet keys are set at
- // {@link #startEmojiPalettes(String,int,float,Typeface)}.
- mAlphabetKeyLeft = (TextView)findViewById(R.id.emoji_keyboard_alphabet_left);
- mAlphabetKeyLeft.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
- mAlphabetKeyLeft.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
- mAlphabetKeyLeft.setOnTouchListener(this);
- mAlphabetKeyLeft.setOnClickListener(this);
- mAlphabetKeyRight = (TextView)findViewById(R.id.emoji_keyboard_alphabet_right);
- mAlphabetKeyRight.setBackgroundResource(mEmojiFunctionalKeyBackgroundId);
- mAlphabetKeyRight.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
- mAlphabetKeyRight.setOnTouchListener(this);
- mAlphabetKeyRight.setOnClickListener(this);
- final ImageView spaceKey = (ImageView)findViewById(R.id.emoji_keyboard_space);
- spaceKey.setBackgroundResource(mKeyBackgroundId);
- spaceKey.setTag(Constants.CODE_SPACE);
- spaceKey.setOnTouchListener(this);
- spaceKey.setOnClickListener(this);
- mEmojiLayoutParams.setKeyProperties(spaceKey);
- }
-
- @Override
- public boolean dispatchTouchEvent(final MotionEvent ev) {
- // Add here to the stack trace to nail down the {@link IllegalArgumentException} exception
- // in MotionEvent that sporadically happens.
- // TODO: Remove this override method once the issue has been addressed.
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- public void onTabChanged(final String tabId) {
- final int categoryId = mEmojiCategory.getCategoryId(tabId);
- setCurrentCategoryId(categoryId, false /* force */);
- updateEmojiCategoryPageIdView();
- }
-
- @Override
- public void onPageSelected(final int position) {
- final Pair<Integer, Integer> newPos =
- mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
- setCurrentCategoryId(newPos.first /* categoryId */, false /* force */);
- mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */);
- updateEmojiCategoryPageIdView();
- mCurrentPagerPosition = position;
- }
-
- @Override
- public void onPageScrollStateChanged(final int state) {
- // Ignore this message. Only want the actual page selected.
- }
-
- @Override
- public void onPageScrolled(final int position, final float positionOffset,
- final int positionOffsetPixels) {
- mEmojiPalettesAdapter.onPageScrolled();
- final Pair<Integer, Integer> newPos =
- mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
- final int newCategoryId = newPos.first;
- final int newCategorySize = mEmojiCategory.getCategoryPageSize(newCategoryId);
- final int currentCategoryId = mEmojiCategory.getCurrentCategoryId();
- final int currentCategoryPageId = mEmojiCategory.getCurrentCategoryPageId();
- final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageSize();
- if (newCategoryId == currentCategoryId) {
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- newCategorySize, newPos.second, positionOffset);
- } else if (newCategoryId > currentCategoryId) {
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- currentCategorySize, currentCategoryPageId, positionOffset);
- } else if (newCategoryId < currentCategoryId) {
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- currentCategorySize, currentCategoryPageId, positionOffset - 1);
- }
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnTouchListener}
- * interface to handle touch events from View-based elements such as the space bar.
- * Note that this method is used only for observing {@link MotionEvent#ACTION_DOWN} to trigger
- * {@link KeyboardActionListener#onPressKey}. {@link KeyboardActionListener#onReleaseKey} will
- * be covered by {@link #onClick} as long as the event is not canceled.
- */
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- if (event.getActionMasked() != MotionEvent.ACTION_DOWN) {
- return false;
- }
- final Object tag = v.getTag();
- if (!(tag instanceof Integer)) {
- return false;
- }
- final int code = (Integer) tag;
- mKeyboardActionListener.onPressKey(
- code, 0 /* repeatCount */, true /* isSinglePointer */);
- // It's important to return false here. Otherwise, {@link #onClick} and touch-down visual
- // feedback stop working.
- return false;
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnClickListener}
- * interface to handle non-canceled touch-up events from View-based elements such as the space
- * bar.
- */
- @Override
- public void onClick(View v) {
- final Object tag = v.getTag();
- if (!(tag instanceof Integer)) {
- return;
- }
- final int code = (Integer) tag;
- mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE,
- false /* isKeyRepeat */);
- mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through
- * {@link com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView.OnKeyEventListener}
- * interface to handle touch events from non-View-based elements such as Emoji buttons.
- */
- @Override
- public void onPressKey(final Key key) {
- final int code = key.getCode();
- mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through
- * {@link com.android.inputmethod.keyboard.internal.EmojiPageKeyboardView.OnKeyEventListener}
- * interface to handle touch events from non-View-based elements such as Emoji buttons.
- */
- @Override
- public void onReleaseKey(final Key key) {
- mEmojiPalettesAdapter.addRecentKey(key);
- mEmojiCategory.saveLastTypedCategoryPage();
- final int code = key.getCode();
- if (code == Constants.CODE_OUTPUT_TEXT) {
- mKeyboardActionListener.onTextInput(key.getOutputText());
- } else {
- mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE,
- false /* isKeyRepeat */);
- }
- mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
- }
-
- public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) {
- if (!enabled) return;
- // TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off?
- setLayerType(LAYER_TYPE_HARDWARE, null);
- }
-
- private static void setupAlphabetKey(final TextView alphabetKey, final String label,
- final KeyDrawParams params) {
- alphabetKey.setText(label);
- alphabetKey.setTextColor(params.mTextColor);
- alphabetKey.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mLabelSize);
- alphabetKey.setTypeface(params.mTypeface);
- }
-
- public void startEmojiPalettes(final String switchToAlphaLabel,
- final KeyVisualAttributes keyVisualAttr) {
- if (DEBUG_PAGER) {
- Log.d(TAG, "allocate emoji palettes memory " + mCurrentPagerPosition);
- }
- final KeyDrawParams params = new KeyDrawParams();
- params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);
- setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params);
- setupAlphabetKey(mAlphabetKeyRight, switchToAlphaLabel, params);
- mEmojiPager.setAdapter(mEmojiPalettesAdapter);
- mEmojiPager.setCurrentItem(mCurrentPagerPosition);
- }
-
- public void stopEmojiPalettes() {
- if (DEBUG_PAGER) {
- Log.d(TAG, "deallocate emoji palettes memory");
- }
- mEmojiPalettesAdapter.flushPendingRecentKeys();
- mEmojiPager.setAdapter(null);
- }
-
- public void setKeyboardActionListener(final KeyboardActionListener listener) {
- mKeyboardActionListener = listener;
- mDeleteKeyOnTouchListener.setKeyboardActionListener(mKeyboardActionListener);
- }
-
- private void updateEmojiCategoryPageIdView() {
- if (mEmojiCategoryPageIndicatorView == null) {
- return;
- }
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- mEmojiCategory.getCurrentCategoryPageSize(),
- mEmojiCategory.getCurrentCategoryPageId(), 0.0f /* offset */);
- }
-
- private void setCurrentCategoryId(final int categoryId, final boolean force) {
- final int oldCategoryId = mEmojiCategory.getCurrentCategoryId();
- if (oldCategoryId == categoryId && !force) {
- return;
- }
-
- if (oldCategoryId == CATEGORY_ID_RECENTS) {
- // Needs to save pending updates for recent keys when we get out of the recents
- // category because we don't want to move the recent emojis around while the user
- // is in the recents category.
- mEmojiPalettesAdapter.flushPendingRecentKeys();
- }
-
- mEmojiCategory.setCurrentCategoryId(categoryId);
- final int newTabId = mEmojiCategory.getTabIdFromCategoryId(categoryId);
- final int newCategoryPageId = mEmojiCategory.getPageIdFromCategoryId(categoryId);
- if (force || mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(
- mEmojiPager.getCurrentItem()).first != categoryId) {
- mEmojiPager.setCurrentItem(newCategoryPageId, false /* smoothScroll */);
- }
- if (force || mTabHost.getCurrentTab() != newTabId) {
- mTabHost.setCurrentTab(newTabId);
- }
- }
-
- private static class EmojiPalettesAdapter extends PagerAdapter {
- private final EmojiPageKeyboardView.OnKeyEventListener mListener;
- private final DynamicGridKeyboard mRecentsKeyboard;
- private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews =
- CollectionUtils.newSparseArray();
- private final EmojiCategory mEmojiCategory;
- private int mActivePosition = 0;
-
- public EmojiPalettesAdapter(final EmojiCategory emojiCategory,
- final EmojiPageKeyboardView.OnKeyEventListener listener) {
- mEmojiCategory = emojiCategory;
- mListener = listener;
- mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0);
- }
-
- public void flushPendingRecentKeys() {
- mRecentsKeyboard.flushPendingRecentKeys();
- final KeyboardView recentKeyboardView =
- mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
- if (recentKeyboardView != null) {
- recentKeyboardView.invalidateAllKeys();
- }
- }
-
- public void addRecentKey(final Key key) {
- if (mEmojiCategory.isInRecentTab()) {
- mRecentsKeyboard.addPendingKey(key);
- return;
- }
- mRecentsKeyboard.addKeyFirst(key);
- final KeyboardView recentKeyboardView =
- mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
- if (recentKeyboardView != null) {
- recentKeyboardView.invalidateAllKeys();
- }
- }
-
- public void onPageScrolled() {
- // Make sure the delayed key-down event (highlight effect and haptic feedback) will be
- // canceled.
- final EmojiPageKeyboardView currentKeyboardView =
- mActiveKeyboardViews.get(mActivePosition);
- if (currentKeyboardView != null) {
- currentKeyboardView.releaseCurrentKey();
- }
- }
-
- @Override
- public int getCount() {
- return mEmojiCategory.getTotalPageCountOfAllCategories();
- }
-
- @Override
- public void setPrimaryItem(final ViewGroup container, final int position,
- final Object object) {
- if (mActivePosition == position) {
- return;
- }
- final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(mActivePosition);
- if (oldKeyboardView != null) {
- oldKeyboardView.releaseCurrentKey();
- oldKeyboardView.deallocateMemory();
- }
- mActivePosition = position;
- }
-
- @Override
- public Object instantiateItem(final ViewGroup container, final int position) {
- if (DEBUG_PAGER) {
- Log.d(TAG, "instantiate item: " + position);
- }
- final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(position);
- if (oldKeyboardView != null) {
- oldKeyboardView.deallocateMemory();
- // This may be redundant but wanted to be safer..
- mActiveKeyboardViews.remove(position);
- }
- final Keyboard keyboard =
- mEmojiCategory.getKeyboardFromPagePosition(position);
- final LayoutInflater inflater = LayoutInflater.from(container.getContext());
- final EmojiPageKeyboardView keyboardView = (EmojiPageKeyboardView)inflater.inflate(
- R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
- keyboardView.setKeyboard(keyboard);
- keyboardView.setOnKeyEventListener(mListener);
- container.addView(keyboardView);
- mActiveKeyboardViews.put(position, keyboardView);
- return keyboardView;
- }
-
- @Override
- public boolean isViewFromObject(final View view, final Object object) {
- return view == object;
- }
-
- @Override
- public void destroyItem(final ViewGroup container, final int position,
- final Object object) {
- if (DEBUG_PAGER) {
- Log.d(TAG, "destroy item: " + position + ", " + object.getClass().getSimpleName());
- }
- final EmojiPageKeyboardView keyboardView = mActiveKeyboardViews.get(position);
- if (keyboardView != null) {
- keyboardView.deallocateMemory();
- mActiveKeyboardViews.remove(position);
- }
- if (object instanceof View) {
- container.removeView((View)object);
- } else {
- Log.w(TAG, "Warning!!! Emoji palette may be leaking. " + object);
- }
- }
- }
-
- private static class DeleteKeyOnTouchListener implements OnTouchListener {
- private static final long MAX_REPEAT_COUNT_TIME = TimeUnit.SECONDS.toMillis(30);
- private final int mDeleteKeyPressedBackgroundColor;
- private final long mKeyRepeatStartTimeout;
- private final long mKeyRepeatInterval;
-
- public DeleteKeyOnTouchListener(Context context) {
- final Resources res = context.getResources();
- mDeleteKeyPressedBackgroundColor =
- res.getColor(R.color.emoji_key_pressed_background_color);
- mKeyRepeatStartTimeout = res.getInteger(R.integer.config_key_repeat_start_timeout);
- mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
- mTimer = new CountDownTimer(MAX_REPEAT_COUNT_TIME, mKeyRepeatInterval) {
- @Override
- public void onTick(long millisUntilFinished) {
- final long elapsed = MAX_REPEAT_COUNT_TIME - millisUntilFinished;
- if (elapsed < mKeyRepeatStartTimeout) {
- return;
- }
- onKeyRepeat();
- }
- @Override
- public void onFinish() {
- onKeyRepeat();
- }
- };
- }
-
- /** Key-repeat state. */
- private static final int KEY_REPEAT_STATE_INITIALIZED = 0;
- // The key is touched but auto key-repeat is not started yet.
- private static final int KEY_REPEAT_STATE_KEY_DOWN = 1;
- // At least one key-repeat event has already been triggered and the key is not released.
- private static final int KEY_REPEAT_STATE_KEY_REPEAT = 2;
-
- private KeyboardActionListener mKeyboardActionListener =
- KeyboardActionListener.EMPTY_LISTENER;
-
- // TODO: Do the same things done in PointerTracker
- private final CountDownTimer mTimer;
- private int mState = KEY_REPEAT_STATE_INITIALIZED;
- private int mRepeatCount = 0;
-
- public void setKeyboardActionListener(final KeyboardActionListener listener) {
- mKeyboardActionListener = listener;
- }
-
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- onTouchDown(v);
- return true;
- case MotionEvent.ACTION_MOVE:
- final float x = event.getX();
- final float y = event.getY();
- if (x < 0.0f || v.getWidth() < x || y < 0.0f || v.getHeight() < y) {
- // Stop generating key events once the finger moves away from the view area.
- onTouchCanceled(v);
- }
- return true;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- onTouchUp(v);
- return true;
- }
- return false;
- }
-
- private void handleKeyDown() {
- mKeyboardActionListener.onPressKey(
- Constants.CODE_DELETE, mRepeatCount, true /* isSinglePointer */);
- }
-
- private void handleKeyUp() {
- mKeyboardActionListener.onCodeInput(Constants.CODE_DELETE,
- NOT_A_COORDINATE, NOT_A_COORDINATE, false /* isKeyRepeat */);
- mKeyboardActionListener.onReleaseKey(
- Constants.CODE_DELETE, false /* withSliding */);
- ++mRepeatCount;
- }
-
- private void onTouchDown(final View v) {
- mTimer.cancel();
- mRepeatCount = 0;
- handleKeyDown();
- v.setBackgroundColor(mDeleteKeyPressedBackgroundColor);
- mState = KEY_REPEAT_STATE_KEY_DOWN;
- mTimer.start();
- }
-
- private void onTouchUp(final View v) {
- mTimer.cancel();
- if (mState == KEY_REPEAT_STATE_KEY_DOWN) {
- handleKeyUp();
- }
- v.setBackgroundColor(Color.TRANSPARENT);
- mState = KEY_REPEAT_STATE_INITIALIZED;
- }
-
- private void onTouchCanceled(final View v) {
- mTimer.cancel();
- v.setBackgroundColor(Color.TRANSPARENT);
- mState = KEY_REPEAT_STATE_INITIALIZED;
- }
-
- // Called by {@link #mTimer} in the UI thread as an auto key-repeat signal.
- private void onKeyRepeat() {
- switch (mState) {
- case KEY_REPEAT_STATE_INITIALIZED:
- // Basically this should not happen.
- break;
- case KEY_REPEAT_STATE_KEY_DOWN:
- // Do not call {@link #handleKeyDown} here because it has already been called
- // in {@link #onTouchDown}.
- handleKeyUp();
- mState = KEY_REPEAT_STATE_KEY_REPEAT;
- break;
- case KEY_REPEAT_STATE_KEY_REPEAT:
- handleKeyDown();
- handleKeyUp();
- break;
- }
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index 816a94300..88cde1111 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -60,6 +60,7 @@ public class Key implements Comparable<Key> {
private final int mLabelFlags;
private static final int LABEL_FLAGS_ALIGN_LEFT = 0x01;
private static final int LABEL_FLAGS_ALIGN_RIGHT = 0x02;
+ private static final int LABEL_FLAGS_ALIGN_BUTTOM = 0x04;
private static final int LABEL_FLAGS_ALIGN_LEFT_OF_CENTER = 0x08;
private static final int LABEL_FLAGS_FONT_NORMAL = 0x10;
private static final int LABEL_FLAGS_FONT_MONO_SPACE = 0x20;
@@ -86,6 +87,7 @@ public class Key implements Comparable<Key> {
private static final int LABEL_FLAGS_PRESERVE_CASE = 0x10000;
private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x20000;
private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x40000;
+ private static final int LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR = 0x80000;
private static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000;
private static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000;
@@ -193,7 +195,8 @@ public class Key implements Comparable<Key> {
mHintLabel = hintLabel;
mLabelFlags = labelFlags;
mBackgroundType = backgroundType;
- mActionFlags = 0;
+ // TODO: Pass keyActionFlags as an argument.
+ mActionFlags = ACTION_FLAGS_NO_KEY_PREVIEW;
mMoreKeys = null;
mMoreKeysColumnAndFlags = 0;
mLabel = label;
@@ -218,7 +221,7 @@ public class Key implements Comparable<Key> {
*
* @param keySpec the key specification.
* @param keyAttr the Key XML attributes array.
- * @param keyStyle the {@link KeyStyle} of this key.
+ * @param style the {@link KeyStyle} of this key.
* @param params the keyboard building parameters.
* @param row the row that this key belongs to. row's x-coordinate will be the right edge of
* this key.
@@ -465,15 +468,24 @@ public class Key implements Comparable<Key> {
@Override
public String toString() {
- final String label;
- if (StringUtils.codePointCount(mLabel) == 1 && mLabel.codePointAt(0) == mCode) {
- label = "";
- } else {
- label = "/" + mLabel;
+ return toShortString() + " " + getX() + "," + getY() + " " + getWidth() + "x" + getHeight();
+ }
+
+ public String toShortString() {
+ final int code = getCode();
+ if (code == Constants.CODE_OUTPUT_TEXT) {
+ return getOutputText();
}
- return String.format(Locale.ROOT, "%s%s %d,%d %dx%d %s/%s/%s",
- Constants.printableCode(mCode), label, mX, mY, mWidth, mHeight, mHintLabel,
- KeyboardIconsSet.getIconName(mIconId), backgroundName(mBackgroundType));
+ return Constants.printableCode(code);
+ }
+
+ public String toLongString() {
+ final int iconId = getIconId();
+ final String topVisual = (iconId == KeyboardIconsSet.ICON_UNDEFINED)
+ ? KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(iconId) : getLabel();
+ final String hintLabel = getHintLabel();
+ final String visual = (hintLabel == null) ? topVisual : topVisual + "^" + hintLabel;
+ return toString() + " " + visual + "/" + backgroundName(mBackgroundType);
}
private static String backgroundName(final int backgroundType) {
@@ -583,6 +595,9 @@ public class Key implements Comparable<Key> {
}
public final int selectTextColor(final KeyDrawParams params) {
+ if ((mLabelFlags & LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR) != 0) {
+ return params.mFunctionalTextColor;
+ }
return isShiftedLetterActivated() ? params.mTextInactivatedColor : params.mTextColor;
}
@@ -642,6 +657,10 @@ public class Key implements Comparable<Key> {
return (mLabelFlags & LABEL_FLAGS_ALIGN_RIGHT) != 0;
}
+ public final boolean isAlignButtom() {
+ return (mLabelFlags & LABEL_FLAGS_ALIGN_BUTTOM) != 0;
+ }
+
public final boolean isAlignLeftOfCenter() {
return (mLabelFlags & LABEL_FLAGS_ALIGN_LEFT_OF_CENTER) != 0;
}
@@ -857,17 +876,6 @@ public class Key implements Comparable<Key> {
android.R.attr.state_empty
};
- // functional normal state (with properties)
- private static final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
- android.R.attr.state_single
- };
-
- // functional pressed state (with properties)
- private static final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
- android.R.attr.state_single,
- android.R.attr.state_pressed
- };
-
// action normal state (with properties)
private static final int[] KEY_STATE_ACTIVE_NORMAL = {
android.R.attr.state_active
@@ -880,25 +888,43 @@ public class Key implements Comparable<Key> {
};
/**
- * Returns the drawable state for the key, based on the current state and type of the key.
- * @return the drawable state of the key.
+ * Returns the background drawable for the key, based on the current state and type of the key.
+ * @return the background drawable of the key.
* @see android.graphics.drawable.StateListDrawable#setState(int[])
*/
- public final int[] getCurrentDrawableState() {
+ public final Drawable selectBackgroundDrawable(final Drawable keyBackground,
+ final Drawable functionalKeyBackground, final Drawable spacebarBackground) {
+ final Drawable background;
+ if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) {
+ background = functionalKeyBackground;
+ } else if (getCode() == Constants.CODE_SPACE) {
+ background = spacebarBackground;
+ } else {
+ background = keyBackground;
+ }
+ final int[] stateSet;
switch (mBackgroundType) {
- case BACKGROUND_TYPE_FUNCTIONAL:
- return mPressed ? KEY_STATE_FUNCTIONAL_PRESSED : KEY_STATE_FUNCTIONAL_NORMAL;
case BACKGROUND_TYPE_ACTION:
- return mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL;
+ stateSet = mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL;
+ break;
case BACKGROUND_TYPE_STICKY_OFF:
- return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
+ stateSet = mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
+ break;
case BACKGROUND_TYPE_STICKY_ON:
- return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
+ stateSet = mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
+ break;
case BACKGROUND_TYPE_EMPTY:
- return mPressed ? KEY_STATE_PRESSED : KEY_STATE_EMPTY;
+ stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_EMPTY;
+ break;
+ case BACKGROUND_TYPE_FUNCTIONAL:
+ stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
+ break;
default: /* BACKGROUND_TYPE_NORMAL */
- return mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
+ stateSet = mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
+ break;
}
+ background.setState(stateSet);
+ return background;
}
public static class Spacer extends Key {
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index f646a03c2..85dfea4e7 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -22,9 +22,9 @@ import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -83,7 +83,7 @@ public class Keyboard {
public final List<Key> mAltCodeKeysWhileTyping;
public final KeyboardIconsSet mIconsSet;
- private final SparseArray<Key> mKeyCache = CollectionUtils.newSparseArray();
+ private final SparseArray<Key> mKeyCache = new SparseArray<>();
private final ProximityInfo mProximityInfo;
private final boolean mProximityCharsCorrectionEnabled;
@@ -103,8 +103,7 @@ public class Keyboard {
mTopPadding = params.mTopPadding;
mVerticalGap = params.mVerticalGap;
- mSortedKeys = Collections.unmodifiableList(
- CollectionUtils.newArrayList(params.mSortedKeys));
+ mSortedKeys = Collections.unmodifiableList(new ArrayList<>(params.mSortedKeys));
mShiftKeys = Collections.unmodifiableList(params.mShiftKeys);
mAltCodeKeysWhileTyping = Collections.unmodifiableList(params.mAltCodeKeysWhileTyping);
mIconsSet = params.mIconsSet;
@@ -159,7 +158,7 @@ public class Keyboard {
/**
* Return the sorted list of keys of this keyboard.
* The keys are sorted from top-left to bottom-right order.
- * The list may contain {@link Spacer} object as well.
+ * The list may contain {@link Key.Spacer} object as well.
* @return the sorted unmodifiable list of {@link Key}s of this keyboard.
*/
public List<Key> getSortedKeys() {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 93a55fe6a..3c1167538 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -70,7 +70,6 @@ public final class KeyboardId {
public final int mElementId;
public final EditorInfo mEditorInfo;
public final boolean mClobberSettingsKey;
- public final boolean mSupportsSwitchingToShortcutIme;
public final boolean mLanguageSwitchKeyEnabled;
public final String mCustomActionLabel;
public final boolean mHasShortcutKey;
@@ -86,11 +85,10 @@ public final class KeyboardId {
mElementId = elementId;
mEditorInfo = params.mEditorInfo;
mClobberSettingsKey = params.mNoSettingsKey;
- mSupportsSwitchingToShortcutIme = params.mSupportsSwitchingToShortcutIme;
mLanguageSwitchKeyEnabled = params.mLanguageSwitchKeyEnabled;
mCustomActionLabel = (mEditorInfo.actionLabel != null)
? mEditorInfo.actionLabel.toString() : null;
- mHasShortcutKey = mSupportsSwitchingToShortcutIme && params.mShowsVoiceInputKey;
+ mHasShortcutKey = params.mVoiceInputKeyEnabled;
mHashCode = computeHashCode(this);
}
@@ -103,7 +101,6 @@ public final class KeyboardId {
id.mHeight,
id.passwordInput(),
id.mClobberSettingsKey,
- id.mSupportsSwitchingToShortcutIme,
id.mHasShortcutKey,
id.mLanguageSwitchKeyEnabled,
id.isMultiLine(),
@@ -124,7 +121,6 @@ public final class KeyboardId {
&& other.mHeight == mHeight
&& other.passwordInput() == passwordInput()
&& other.mClobberSettingsKey == mClobberSettingsKey
- && other.mSupportsSwitchingToShortcutIme == mSupportsSwitchingToShortcutIme
&& other.mHasShortcutKey == mHasShortcutKey
&& other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled
&& other.isMultiLine() == isMultiLine()
@@ -179,7 +175,7 @@ public final class KeyboardId {
@Override
public String toString() {
- return String.format(Locale.ROOT, "[%s %s:%s %dx%d %s %s%s%s%s%s%s%s%s%s]",
+ return String.format(Locale.ROOT, "[%s %s:%s %dx%d %s %s%s%s%s%s%s%s%s]",
elementIdToName(mElementId),
mLocale, mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
mWidth, mHeight,
@@ -189,7 +185,6 @@ public final class KeyboardId {
(navigatePrevious() ? " navigatePrevious" : ""),
(mClobberSettingsKey ? " clobberSettingsKey" : ""),
(passwordInput() ? " passwordInput" : ""),
- (mSupportsSwitchingToShortcutIme ? " supportsSwitchingToShortcutIme" : ""),
(mHasShortcutKey ? " hasShortcutKey" : ""),
(mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""),
(isMultiLine() ? " isMultiLine" : "")
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index cde5091c4..3e5cfc11a 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -17,8 +17,6 @@
package com.android.inputmethod.keyboard;
import static com.android.inputmethod.latin.Constants.ImeOption.FORCE_ASCII;
-import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE;
-import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE_COMPAT;
import static com.android.inputmethod.latin.Constants.ImeOption.NO_SETTINGS_KEY;
import android.content.Context;
@@ -41,7 +39,6 @@ import com.android.inputmethod.latin.InputAttributes;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import com.android.inputmethod.latin.utils.XmlParseUtils;
@@ -81,7 +78,7 @@ public final class KeyboardLayoutSet {
// them from disappearing from sKeyboardCache.
private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE];
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
- CollectionUtils.newHashMap();
+ new HashMap<>();
private static final KeysCache sKeysCache = new KeysCache();
@SuppressWarnings("serial")
@@ -103,12 +100,11 @@ public final class KeyboardLayoutSet {
public static final class Params {
String mKeyboardLayoutSetName;
int mMode;
- EditorInfo mEditorInfo;
boolean mDisableTouchPositionCorrectionDataForTest;
+ // TODO: Use {@link InputAttributes} instead of these variables.
+ EditorInfo mEditorInfo;
boolean mIsPasswordField;
- boolean mSupportsSwitchingToShortcutIme;
- boolean mShowsVoiceInputKey;
- boolean mNoMicrophoneKey;
+ boolean mVoiceInputKeyEnabled;
boolean mNoSettingsKey;
boolean mLanguageSwitchKeyEnabled;
InputMethodSubtype mSubtype;
@@ -117,7 +113,7 @@ public final class KeyboardLayoutSet {
int mKeyboardHeight;
// Sparse array of KeyboardLayoutSet element parameters indexed by element's id.
final SparseArray<ElementParams> mKeyboardLayoutSetElementIdToParamsMap =
- CollectionUtils.newSparseArray();
+ new SparseArray<>();
}
public static void clearKeyboardCache() {
@@ -181,7 +177,7 @@ public final class KeyboardLayoutSet {
}
final KeyboardBuilder<KeyboardParams> builder =
- new KeyboardBuilder<KeyboardParams>(mContext, new KeyboardParams());
+ new KeyboardBuilder<>(mContext, new KeyboardParams());
if (id.isAlphabetKeyboard()) {
builder.setAutoGenerate(sKeysCache);
}
@@ -192,7 +188,7 @@ public final class KeyboardLayoutSet {
}
builder.setProximityCharsCorrectionEnabled(elementParams.mProximityCharsCorrectionEnabled);
final Keyboard keyboard = builder.build();
- sKeyboardCache.put(id, new SoftReference<Keyboard>(keyboard));
+ sKeyboardCache.put(id, new SoftReference<>(keyboard));
if ((id.mElementId == KeyboardId.ELEMENT_ALPHABET
|| id.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED)
&& !mParams.mIsSpellChecker) {
@@ -229,14 +225,9 @@ public final class KeyboardLayoutSet {
final EditorInfo editorInfo = (ei != null) ? ei : EMPTY_EDITOR_INFO;
params.mMode = getKeyboardMode(editorInfo);
+ // TODO: Consolidate those with {@link InputAttributes}.
params.mEditorInfo = editorInfo;
params.mIsPasswordField = InputTypeUtils.isPasswordInputType(editorInfo.inputType);
- @SuppressWarnings("deprecation")
- final boolean deprecatedNoMicrophone = InputAttributes.inPrivateImeOptions(
- null, NO_MICROPHONE_COMPAT, editorInfo);
- params.mNoMicrophoneKey = InputAttributes.inPrivateImeOptions(
- mPackageName, NO_MICROPHONE, editorInfo)
- || deprecatedNoMicrophone;
params.mNoSettingsKey = InputAttributes.inPrivateImeOptions(
mPackageName, NO_SETTINGS_KEY, editorInfo);
}
@@ -249,6 +240,7 @@ public final class KeyboardLayoutSet {
public Builder setSubtype(final InputMethodSubtype subtype) {
final boolean asciiCapable = InputMethodSubtypeCompatUtils.isAsciiCapable(subtype);
+ // TODO: Consolidate with {@link InputAttributes}.
@SuppressWarnings("deprecation")
final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
mPackageName, FORCE_ASCII, mParams.mEditorInfo);
@@ -269,12 +261,13 @@ public final class KeyboardLayoutSet {
return this;
}
- public Builder setOptions(final boolean isShortcutImeEnabled,
- final boolean showsVoiceInputKey, final boolean languageSwitchKeyEnabled) {
- mParams.mSupportsSwitchingToShortcutIme =
- isShortcutImeEnabled && !mParams.mNoMicrophoneKey && !mParams.mIsPasswordField;
- mParams.mShowsVoiceInputKey = showsVoiceInputKey;
- mParams.mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
+ public Builder setVoiceInputKeyEnabled(final boolean enabled) {
+ mParams.mVoiceInputKeyEnabled = enabled;
+ return this;
+ }
+
+ public Builder setLanguageSwitchKeyEnabled(final boolean enabled) {
+ mParams.mLanguageSwitchKeyEnabled = enabled;
return this;
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 0235fde38..6aeff189f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -26,14 +26,13 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.EditorInfo;
-import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
+import com.android.inputmethod.keyboard.emoji.EmojiPalettesView;
import com.android.inputmethod.keyboard.internal.KeyboardState;
import com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
import com.android.inputmethod.latin.InputView;
import com.android.inputmethod.latin.LatinIME;
-import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.SubtypeSwitcher;
@@ -61,11 +60,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet();
private SettingsValues mCurrentSettingsValues;
- /** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of
- * what user actually typed. */
- private boolean mIsAutoCorrectionActive;
-
- private KeyboardTheme mKeyboardTheme = KeyboardTheme.getDefaultKeyboardTheme();
+ private KeyboardTheme mKeyboardTheme;
private Context mThemeContext;
private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
@@ -102,7 +97,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
final KeyboardTheme keyboardTheme) {
- if (mThemeContext == null || mKeyboardTheme.mThemeId != keyboardTheme.mThemeId) {
+ if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)) {
mKeyboardTheme = keyboardTheme;
mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
KeyboardLayoutSet.clearKeyboardCache();
@@ -120,10 +115,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
final int keyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res);
builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
builder.setSubtype(mSubtypeSwitcher.getCurrentSubtype());
- builder.setOptions(
- mSubtypeSwitcher.isShortcutImeEnabled(),
- settingsValues.mShowsVoiceInputKey,
- mLatinIME.shouldSwitchToOtherInputMethods());
+ builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
+ builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey());
mKeyboardLayoutSet = builder.build();
mCurrentSettingsValues = settingsValues;
try {
@@ -131,7 +124,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mKeyboardTextsSet.setLocale(mSubtypeSwitcher.getCurrentSubtypeLocale(), mThemeContext);
} catch (KeyboardLayoutSetException e) {
Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
- LatinImeLogger.logOnException(e.mKeyboardId.toString(), e.getCause());
return;
}
}
@@ -142,12 +134,10 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
}
- public void onFinishInputView() {
- mIsAutoCorrectionActive = false;
- }
-
public void onHideWindow() {
- mIsAutoCorrectionActive = false;
+ if (mKeyboardView != null) {
+ mKeyboardView.onHideWindow();
+ }
}
private void setKeyboard(final Keyboard keyboard) {
@@ -165,7 +155,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mCurrentSettingsValues.mKeyPreviewShowUpDuration,
mCurrentSettingsValues.mKeyPreviewDismissEndScale,
mCurrentSettingsValues.mKeyPreviewDismissDuration);
- keyboardView.updateAutoCorrectionState(mIsAutoCorrectionActive);
keyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady());
final boolean subtypeChanged = (oldKeyboard == null)
|| !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale);
@@ -251,10 +240,11 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void setEmojiKeyboard() {
+ final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
mMainKeyboardFrame.setVisibility(View.GONE);
mEmojiPalettesView.startEmojiPalettes(
mKeyboardTextsSet.getText(KeyboardTextsSet.SWITCH_TO_ALPHA_KEY_LABEL),
- mKeyboardView.getKeyVisualAttribute());
+ mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet);
mEmojiPalettesView.setVisibility(View.VISIBLE);
}
@@ -340,7 +330,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mKeyboardView.closing();
}
- updateKeyboardThemeAndContextThemeWrapper(mLatinIME, mKeyboardTheme);
+ updateKeyboardThemeAndContextThemeWrapper(
+ mLatinIME, KeyboardTheme.getKeyboardTheme(mPrefs));
mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
R.layout.input_view, null);
mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
@@ -353,11 +344,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
mEmojiPalettesView.setHardwareAcceleratedDrawingEnabled(
isHardwareAcceleratedDrawingEnabled);
mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
-
- // This always needs to be set since the accessibility state can
- // potentially change without the input view being re-created.
- AccessibleKeyboardViewProxy.getInstance().setView(mKeyboardView);
-
return mCurrentInputView;
}
@@ -367,15 +353,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
}
}
- public void onAutoCorrectionStateChanged(final boolean isAutoCorrection) {
- if (mIsAutoCorrectionActive != isAutoCorrection) {
- mIsAutoCorrectionActive = isAutoCorrection;
- if (mKeyboardView != null) {
- mKeyboardView.updateAutoCorrectionState(isAutoCorrection);
- }
- }
- }
-
public int getKeyboardShiftMode() {
final Keyboard keyboard = getKeyboard();
if (keyboard == null) {
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
index 4db72ad4d..0ea9c742f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
@@ -17,34 +17,76 @@
package com.android.inputmethod.keyboard;
import android.content.SharedPreferences;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.settings.Settings;
-public final class KeyboardTheme {
+import java.util.Arrays;
+
+public final class KeyboardTheme implements Comparable<KeyboardTheme> {
private static final String TAG = KeyboardTheme.class.getSimpleName();
+ static final String KLP_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916";
+ static final String LXX_KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509";
+
public static final int THEME_ID_ICS = 0;
public static final int THEME_ID_KLP = 2;
- private static final int DEFAULT_THEME_ID = THEME_ID_KLP;
+ public static final int THEME_ID_LXX_DARK = 3;
+ public static final int DEFAULT_THEME_ID = THEME_ID_KLP;
private static final KeyboardTheme[] KEYBOARD_THEMES = {
- new KeyboardTheme(THEME_ID_ICS, R.style.KeyboardTheme_ICS),
- new KeyboardTheme(THEME_ID_KLP, R.style.KeyboardTheme_KLP),
+ new KeyboardTheme(THEME_ID_ICS, R.style.KeyboardTheme_ICS,
+ // This has never been selected because we support ICS or later.
+ VERSION_CODES.BASE),
+ new KeyboardTheme(THEME_ID_KLP, R.style.KeyboardTheme_KLP,
+ // Default theme for ICS, JB, and KLP.
+ VERSION_CODES.ICE_CREAM_SANDWICH),
+ new KeyboardTheme(THEME_ID_LXX_DARK, R.style.KeyboardTheme_LXX_Dark,
+ // Default theme for LXX.
+ // TODO: Update this constant once the *next* version becomes available.
+ VERSION_CODES.CUR_DEVELOPMENT),
};
+ static {
+ // Sort {@link #KEYBOARD_THEME} by descending order of {@link #mMinApiVersion}.
+ Arrays.sort(KEYBOARD_THEMES);
+ }
+
public final int mThemeId;
public final int mStyleId;
+ private final int mMinApiVersion;
// Note: The themeId should be aligned with "themeId" attribute of Keyboard style
- // in values/style.xml.
- public KeyboardTheme(final int themeId, final int styleId) {
+ // in values/themes-<style>.xml.
+ private KeyboardTheme(final int themeId, final int styleId, final int minApiVersion) {
mThemeId = themeId;
mStyleId = styleId;
+ mMinApiVersion = minApiVersion;
+ }
+
+ @Override
+ public int compareTo(final KeyboardTheme rhs) {
+ if (mMinApiVersion > rhs.mMinApiVersion) return -1;
+ if (mMinApiVersion < rhs.mMinApiVersion) return 1;
+ return 0;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (o == this) return true;
+ return (o instanceof KeyboardTheme) && ((KeyboardTheme)o).mThemeId == mThemeId;
}
- private static KeyboardTheme searchKeyboardTheme(final int themeId) {
+ @Override
+ public int hashCode() {
+ return mThemeId;
+ }
+
+ @UsedForTesting
+ static KeyboardTheme searchKeyboardThemeById(final int themeId) {
// TODO: This search algorithm isn't optimal if there are many themes.
for (final KeyboardTheme theme : KEYBOARD_THEMES) {
if (theme.mThemeId == themeId) {
@@ -54,28 +96,87 @@ public final class KeyboardTheme {
return null;
}
- public static KeyboardTheme getDefaultKeyboardTheme() {
- return searchKeyboardTheme(DEFAULT_THEME_ID);
+ private static int getSdkVersion() {
+ final int sdkVersion = Build.VERSION.SDK_INT;
+ // TODO: Consider to remove this check once the *next* version becomes available.
+ if (sdkVersion == VERSION_CODES.KITKAT && Build.VERSION.CODENAME.startsWith("L")) {
+ return VERSION_CODES.CUR_DEVELOPMENT;
+ }
+ return sdkVersion;
+ }
+
+ @UsedForTesting
+ static KeyboardTheme getDefaultKeyboardTheme(final SharedPreferences prefs,
+ final int sdkVersion) {
+ final String klpThemeIdString = prefs.getString(KLP_KEYBOARD_THEME_KEY, null);
+ if (klpThemeIdString != null) {
+ if (sdkVersion <= VERSION_CODES.KITKAT) {
+ try {
+ final int themeId = Integer.parseInt(klpThemeIdString);
+ final KeyboardTheme theme = searchKeyboardThemeById(themeId);
+ if (theme != null) {
+ return theme;
+ }
+ Log.w(TAG, "Unknown keyboard theme in KLP preference: " + klpThemeIdString);
+ } catch (final NumberFormatException e) {
+ Log.w(TAG, "Illegal keyboard theme in KLP preference: " + klpThemeIdString, e);
+ }
+ }
+ // Remove old preference.
+ Log.i(TAG, "Remove KLP keyboard theme preference: " + klpThemeIdString);
+ prefs.edit().remove(KLP_KEYBOARD_THEME_KEY).apply();
+ }
+ // TODO: This search algorithm isn't optimal if there are many themes.
+ for (final KeyboardTheme theme : KEYBOARD_THEMES) {
+ if (sdkVersion >= theme.mMinApiVersion) {
+ return theme;
+ }
+ }
+ return searchKeyboardThemeById(DEFAULT_THEME_ID);
+ }
+
+ public static void saveKeyboardThemeId(final String themeIdString,
+ final SharedPreferences prefs) {
+ saveKeyboardThemeId(themeIdString, prefs, getSdkVersion());
+ }
+
+ @UsedForTesting
+ static String getPreferenceKey(final int sdkVersion) {
+ if (sdkVersion <= VERSION_CODES.KITKAT) {
+ return KLP_KEYBOARD_THEME_KEY;
+ }
+ return LXX_KEYBOARD_THEME_KEY;
+ }
+
+ @UsedForTesting
+ static void saveKeyboardThemeId(final String themeIdString,
+ final SharedPreferences prefs, final int sdkVersion) {
+ final String prefKey = getPreferenceKey(sdkVersion);
+ prefs.edit().putString(prefKey, themeIdString).apply();
}
public static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs) {
- final String themeIdString = prefs.getString(Settings.PREF_KEYBOARD_LAYOUT, null);
- if (themeIdString == null) {
- return getDefaultKeyboardTheme();
+ return getKeyboardTheme(prefs, getSdkVersion());
+ }
+
+ @UsedForTesting
+ static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs, final int sdkVersion) {
+ final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null);
+ if (lxxThemeIdString == null) {
+ return getDefaultKeyboardTheme(prefs, sdkVersion);
}
try {
- final int themeId = Integer.parseInt(themeIdString);
- final KeyboardTheme theme = searchKeyboardTheme(themeId);
+ final int themeId = Integer.parseInt(lxxThemeIdString);
+ final KeyboardTheme theme = searchKeyboardThemeById(themeId);
if (theme != null) {
return theme;
}
- Log.w(TAG, "Unknown keyboard theme in preference: " + themeIdString);
+ Log.w(TAG, "Unknown keyboard theme in LXX preference: " + lxxThemeIdString);
} catch (final NumberFormatException e) {
- Log.w(TAG, "Illegal keyboard theme in preference: " + themeIdString);
+ Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e);
}
- // Reset preference to default value.
- final String defaultThemeIdString = Integer.toString(DEFAULT_THEME_ID);
- prefs.edit().putString(Settings.PREF_KEYBOARD_LAYOUT, defaultThemeIdString).apply();
- return getDefaultKeyboardTheme();
+ // Remove preference that contains unknown or illegal theme id.
+ prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply();
+ return getDefaultKeyboardTheme(prefs, sdkVersion);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 8ca00b005..c4ca1c495 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -28,18 +28,15 @@ import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.view.View;
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.TypefaceUtils;
-import com.android.inputmethod.research.ResearchLogger;
import java.util.HashSet;
@@ -47,6 +44,9 @@ import java.util.HashSet;
* A view that renders a virtual {@link Keyboard}.
*
* @attr ref R.styleable#KeyboardView_keyBackground
+ * @attr ref R.styleable#KeyboardView_functionalKeyBackground
+ * @attr ref R.styleable#KeyboardView_spacebarBackground
+ * @attr ref R.styleable#KeyboardView_spacebarIconWidthRatio
* @attr ref R.styleable#KeyboardView_keyLabelHorizontalPadding
* @attr ref R.styleable#KeyboardView_keyHintLetterPadding
* @attr ref R.styleable#KeyboardView_keyPopupHintLetterPadding
@@ -81,7 +81,11 @@ public class KeyboardView extends View {
private final float mKeyTextShadowRadius;
private final float mVerticalCorrection;
private final Drawable mKeyBackground;
+ private final Drawable mFunctionalKeyBackground;
+ private final Drawable mSpacebarBackground;
+ private final float mSpacebarIconWidthRatio;
private final Rect mKeyBackgroundPadding = new Rect();
+ private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f;
// HORIZONTAL ELLIPSIS "...", character for popup hint.
private static final String POPUP_HINT_CHAR = "\u2026";
@@ -102,7 +106,7 @@ public class KeyboardView extends View {
/** True if all keys should be drawn */
private boolean mInvalidateAllKeys;
/** The keys that should be drawn */
- private final HashSet<Key> mInvalidatedKeys = CollectionUtils.newHashSet();
+ private final HashSet<Key> mInvalidatedKeys = new HashSet<>();
/** The working rectangle variable */
private final Rect mWorkingRect = new Rect();
/** The keyboard bitmap buffer for faster updates */
@@ -124,6 +128,15 @@ public class KeyboardView extends View {
R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
mKeyBackground = keyboardViewAttr.getDrawable(R.styleable.KeyboardView_keyBackground);
mKeyBackground.getPadding(mKeyBackgroundPadding);
+ final Drawable functionalKeyBackground = keyboardViewAttr.getDrawable(
+ R.styleable.KeyboardView_functionalKeyBackground);
+ mFunctionalKeyBackground = (functionalKeyBackground != null) ? functionalKeyBackground
+ : mKeyBackground;
+ final Drawable spacebarBackground = keyboardViewAttr.getDrawable(
+ R.styleable.KeyboardView_spacebarBackground);
+ mSpacebarBackground = (spacebarBackground != null) ? spacebarBackground : mKeyBackground;
+ mSpacebarIconWidthRatio = keyboardViewAttr.getFloat(
+ R.styleable.KeyboardView_spacebarIconWidthRatio, 1.0f);
mKeyLabelHorizontalPadding = keyboardViewAttr.getDimensionPixelOffset(
R.styleable.KeyboardView_keyLabelHorizontalPadding, 0);
mKeyHintLetterPadding = keyboardViewAttr.getDimension(
@@ -133,7 +146,7 @@ public class KeyboardView extends View {
mKeyShiftedLetterHintPadding = keyboardViewAttr.getDimension(
R.styleable.KeyboardView_keyShiftedLetterHintPadding, 0.0f);
mKeyTextShadowRadius = keyboardViewAttr.getFloat(
- R.styleable.KeyboardView_keyTextShadowRadius, 0.0f);
+ R.styleable.KeyboardView_keyTextShadowRadius, KET_TEXT_SHADOW_RADIUS_DISABLED);
mVerticalCorrection = keyboardViewAttr.getDimension(
R.styleable.KeyboardView_verticalCorrection, 0.0f);
keyboardViewAttr.recycle();
@@ -171,7 +184,6 @@ public class KeyboardView extends View {
*/
public void setKeyboard(final Keyboard keyboard) {
mKeyboard = keyboard;
- LatinImeLogger.onSetKeyboard(keyboard);
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes);
mKeyDrawParams.updateParams(keyHeight, keyboard.mKeyVisualAttributes);
@@ -301,13 +313,6 @@ public class KeyboardView extends View {
}
}
- // Research Logging (Development Only Diagnostics) indicator.
- // TODO: Reimplement using a keyboard background image specific to the ResearchLogger,
- // and remove this call.
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().paintIndicator(this, paint, canvas, width, height);
- }
-
mInvalidatedKeys.clear();
mInvalidateAllKeys = false;
}
@@ -323,7 +328,9 @@ public class KeyboardView extends View {
params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
if (!key.isSpacer()) {
- onDrawKeyBackground(key, canvas, mKeyBackground);
+ final Drawable background = key.selectBackgroundDrawable(
+ mKeyBackground, mFunctionalKeyBackground, mSpacebarBackground);
+ onDrawKeyBackground(key, canvas, background);
}
onDrawKeyTopVisuals(key, canvas, paint, params);
@@ -338,17 +345,12 @@ public class KeyboardView extends View {
final int bgHeight = key.getHeight() + padding.top + padding.bottom;
final int bgX = -padding.left;
final int bgY = -padding.top;
- final int[] drawableState = key.getCurrentDrawableState();
- background.setState(drawableState);
final Rect bounds = background.getBounds();
if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
background.setBounds(0, 0, bgWidth, bgHeight);
}
canvas.translate(bgX, bgY);
background.draw(canvas);
- if (LatinImeLogger.sVISUALDEBUG) {
- drawRectangle(canvas, 0.0f, 0.0f, bgWidth, bgHeight, 0x80c00000, new Paint());
- }
canvas.translate(-bgX, -bgY);
}
@@ -360,10 +362,6 @@ public class KeyboardView extends View {
final float centerX = keyWidth * 0.5f;
final float centerY = keyHeight * 0.5f;
- if (LatinImeLogger.sVISUALDEBUG) {
- drawRectangle(canvas, 0.0f, 0.0f, keyWidth, keyHeight, 0x800000c0, new Paint());
- }
-
// Draw key label.
final Drawable icon = key.getIcon(mKeyboard.mIconsSet, params.mAnimAlpha);
float positionX = centerX;
@@ -414,18 +412,23 @@ public class KeyboardView extends View {
}
}
- paint.setColor(key.selectTextColor(params));
if (key.isEnabled()) {
- // Set a drop shadow for the text
- paint.setShadowLayer(mKeyTextShadowRadius, 0.0f, 0.0f, params.mTextShadowColor);
+ paint.setColor(key.selectTextColor(params));
+ // Set a drop shadow for the text if the shadow radius is positive value.
+ if (mKeyTextShadowRadius > 0.0f) {
+ paint.setShadowLayer(mKeyTextShadowRadius, 0.0f, 0.0f, params.mTextShadowColor);
+ } else {
+ paint.clearShadowLayer();
+ }
} else {
// Make label invisible
paint.setColor(Color.TRANSPARENT);
+ paint.clearShadowLayer();
}
blendAlpha(paint, params.mAnimAlpha);
canvas.drawText(label, 0, label.length(), positionX, baseline, paint);
// Turn off drop shadow and reset x-scale.
- paint.setShadowLayer(0.0f, 0.0f, 0.0f, Color.TRANSPARENT);
+ paint.clearShadowLayer();
paint.setTextScaleX(1.0f);
if (icon != null) {
@@ -440,12 +443,6 @@ public class KeyboardView extends View {
drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
}
}
-
- if (LatinImeLogger.sVISUALDEBUG) {
- final Paint line = new Paint();
- drawHorizontalLine(canvas, baseline, keyWidth, 0xc0008000, line);
- drawVerticalLine(canvas, positionX, keyHeight, 0xc0800080, line);
- }
}
// Draw hint label.
@@ -485,37 +482,28 @@ public class KeyboardView extends View {
paint.setTextAlign(Align.CENTER);
}
canvas.drawText(hintLabel, 0, hintLabel.length(), hintX, hintY + adjustmentY, paint);
-
- if (LatinImeLogger.sVISUALDEBUG) {
- final Paint line = new Paint();
- drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
- drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
- }
}
// Draw key icon.
if (label == null && icon != null) {
- final int iconWidth = Math.min(icon.getIntrinsicWidth(), keyWidth);
+ final int iconWidth;
+ if (key.getCode() == Constants.CODE_SPACE && icon instanceof NinePatchDrawable) {
+ iconWidth = (int)(keyWidth * mSpacebarIconWidthRatio);
+ } else {
+ iconWidth = Math.min(icon.getIntrinsicWidth(), keyWidth);
+ }
final int iconHeight = icon.getIntrinsicHeight();
- final int iconX, alignX;
- final int iconY = (keyHeight - iconHeight) / 2;
+ final int iconY = key.isAlignButtom() ? keyHeight - iconHeight
+ : (keyHeight - iconHeight) / 2;
+ final int iconX;
if (key.isAlignLeft()) {
iconX = mKeyLabelHorizontalPadding;
- alignX = iconX;
} else if (key.isAlignRight()) {
iconX = keyWidth - mKeyLabelHorizontalPadding - iconWidth;
- alignX = iconX + iconWidth;
} else { // Align center
iconX = (keyWidth - iconWidth) / 2;
- alignX = iconX + iconWidth / 2;
}
drawIcon(canvas, icon, iconX, iconY, iconWidth, iconHeight);
-
- if (LatinImeLogger.sVISUALDEBUG) {
- final Paint line = new Paint();
- drawVerticalLine(canvas, alignX, keyHeight, 0xc0800080, line);
- drawRectangle(canvas, iconX, iconY, iconWidth, iconHeight, 0x80c00000, line);
- }
}
if (key.hasPopupHint() && key.getMoreKeys() != null) {
@@ -537,12 +525,6 @@ public class KeyboardView extends View {
- TypefaceUtils.getReferenceCharWidth(paint) / 2.0f;
final float hintY = keyHeight - mKeyPopupHintLetterPadding;
canvas.drawText(POPUP_HINT_CHAR, hintX, hintY, paint);
-
- if (LatinImeLogger.sVISUALDEBUG) {
- final Paint line = new Paint();
- drawHorizontalLine(canvas, (int)hintY, keyWidth, 0xc0808000, line);
- drawVerticalLine(canvas, (int)hintX, keyHeight, 0xc0808000, line);
- }
}
protected static void drawIcon(final Canvas canvas, final Drawable icon, final int x,
@@ -553,32 +535,6 @@ public class KeyboardView extends View {
canvas.translate(-x, -y);
}
- private static void drawHorizontalLine(final Canvas canvas, final float y, final float w,
- final int color, final Paint paint) {
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(1.0f);
- paint.setColor(color);
- canvas.drawLine(0.0f, y, w, y, paint);
- }
-
- private static void drawVerticalLine(final Canvas canvas, final float x, final float h,
- final int color, final Paint paint) {
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(1.0f);
- paint.setColor(color);
- canvas.drawLine(x, 0.0f, x, h, paint);
- }
-
- private static void drawRectangle(final Canvas canvas, final float x, final float y,
- final float w, final float h, final int color, final Paint paint) {
- paint.setStyle(Paint.Style.STROKE);
- paint.setStrokeWidth(1.0f);
- paint.setColor(color);
- canvas.translate(x, y);
- canvas.drawRect(0.0f, 0.0f, w, h, paint);
- canvas.translate(-x, -y);
- }
-
public Paint newLabelPaint(final Key key) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index ecef8cc6c..9a859bfdb 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -27,7 +27,6 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import android.util.Log;
@@ -39,7 +38,7 @@ import android.view.inputmethod.InputMethodSubtype;
import android.widget.TextView;
import com.android.inputmethod.accessibility.AccessibilityUtils;
-import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
+import com.android.inputmethod.accessibility.MainKeyboardAccessibilityDelegate;
import com.android.inputmethod.annotations.ExternallyReferenced;
import com.android.inputmethod.keyboard.internal.DrawingHandler;
import com.android.inputmethod.keyboard.internal.DrawingPreviewPlacerView;
@@ -53,29 +52,22 @@ import com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper;
import com.android.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview;
import com.android.inputmethod.keyboard.internal.TimerHandler;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.DebugSettings;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.SpacebarLanguageUtils;
import com.android.inputmethod.latin.utils.TypefaceUtils;
-import com.android.inputmethod.latin.utils.UsabilityStudyLogUtils;
-import com.android.inputmethod.research.ResearchLogger;
import java.util.WeakHashMap;
/**
* A view that is responsible for detecting key presses and touch movements.
*
- * @attr ref R.styleable#MainKeyboardView_autoCorrectionSpacebarLedEnabled
- * @attr ref R.styleable#MainKeyboardView_autoCorrectionSpacebarLedIcon
* @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextRatio
* @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextColor
+ * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextShadowRadius
* @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextShadowColor
- * @attr ref R.styleable#MainKeyboardView_spacebarBackground
* @attr ref R.styleable#MainKeyboardView_languageOnSpacebarFinalAlpha
* @attr ref R.styleable#MainKeyboardView_languageOnSpacebarFadeoutAnimator
* @attr ref R.styleable#MainKeyboardView_altCodeKeyWhileTypingFadeoutAnimator
@@ -118,8 +110,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
/* Space key and its icon and background. */
private Key mSpaceKey;
- private Drawable mSpacebarIcon;
- private final Drawable mSpacebarBackground;
// Stuff to draw language name on spacebar.
private final int mLanguageOnSpacebarFinalAlpha;
private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator;
@@ -129,14 +119,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final float mLanguageOnSpacebarTextRatio;
private float mLanguageOnSpacebarTextSize;
private final int mLanguageOnSpacebarTextColor;
+ private final float mLanguageOnSpacebarTextShadowRadius;
private final int mLanguageOnSpacebarTextShadowColor;
+ private static final float LANGUAGE_ON_SPACEBAR_TEXT_SHADOW_RADIUS_DISABLED = -1.0f;
// The minimum x-scale to fit the language name on spacebar.
private static final float MINIMUM_XSCALE_OF_LANGUAGE_NAME = 0.8f;
- // Stuff to draw auto correction LED on spacebar.
- private boolean mAutoCorrectionSpacebarLedOn;
- private final boolean mAutoCorrectionSpacebarLedEnabled;
- private final Drawable mAutoCorrectionSpacebarLedIcon;
- private static final int SPACE_LED_LENGTH_PERCENT = 80;
// Stuff to draw altCodeWhileTyping keys.
private final ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator;
@@ -151,7 +138,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final SlidingKeyInputDrawingPreview mSlidingKeyInputDrawingPreview;
// Key preview
- private static final boolean FADE_OUT_KEY_TOP_LETTER_WHEN_KEY_IS_PRESSED = false;
private final KeyPreviewDrawParams mKeyPreviewDrawParams;
private final KeyPreviewChoreographer mKeyPreviewChoreographer;
@@ -159,8 +145,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final Paint mBackgroundDimAlphaPaint = new Paint();
private boolean mNeedsToDimEntireKeyboard;
private final View mMoreKeysKeyboardContainer;
- private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache =
- CollectionUtils.newWeakHashMap();
+ private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = new WeakHashMap<>();
private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint;
// More keys panel (used by both more keys keyboard and more suggestions view)
// TODO: Consider extending to support multiple more keys panels
@@ -176,8 +161,9 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
private final TimerHandler mKeyTimerHandler;
private final int mLanguageOnSpacebarHorizontalMargin;
- private final DrawingHandler mDrawingHandler =
- new DrawingHandler(this);
+ private final DrawingHandler mDrawingHandler = new DrawingHandler(this);
+
+ private MainKeyboardAccessibilityDelegate mAccessibilityDelegate;
public MainKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.mainKeyboardViewStyle);
@@ -219,16 +205,13 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
R.styleable.MainKeyboardView_backgroundDimAlpha, 0);
mBackgroundDimAlphaPaint.setColor(Color.BLACK);
mBackgroundDimAlphaPaint.setAlpha(backgroundDimAlpha);
- mSpacebarBackground = mainKeyboardViewAttr.getDrawable(
- R.styleable.MainKeyboardView_spacebarBackground);
- mAutoCorrectionSpacebarLedEnabled = mainKeyboardViewAttr.getBoolean(
- R.styleable.MainKeyboardView_autoCorrectionSpacebarLedEnabled, false);
- mAutoCorrectionSpacebarLedIcon = mainKeyboardViewAttr.getDrawable(
- R.styleable.MainKeyboardView_autoCorrectionSpacebarLedIcon);
mLanguageOnSpacebarTextRatio = mainKeyboardViewAttr.getFraction(
R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f);
mLanguageOnSpacebarTextColor = mainKeyboardViewAttr.getColor(
R.styleable.MainKeyboardView_languageOnSpacebarTextColor, 0);
+ mLanguageOnSpacebarTextShadowRadius = mainKeyboardViewAttr.getFloat(
+ R.styleable.MainKeyboardView_languageOnSpacebarTextShadowRadius,
+ LANGUAGE_ON_SPACEBAR_TEXT_SHADOW_RADIUS_DISABLED);
mLanguageOnSpacebarTextShadowColor = mainKeyboardViewAttr.getColor(
R.styleable.MainKeyboardView_languageOnSpacebarTextShadowColor, 0);
mLanguageOnSpacebarFinalAlpha = mainKeyboardViewAttr.getInt(
@@ -395,18 +378,17 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mMoreKeysKeyboardCache.clear();
mSpaceKey = keyboard.getKey(Constants.CODE_SPACE);
- mSpacebarIcon = (mSpaceKey != null)
- ? mSpaceKey.getIcon(keyboard.mIconsSet, Constants.Color.ALPHA_OPAQUE) : null;
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
mLanguageOnSpacebarTextSize = keyHeight * mLanguageOnSpacebarTextRatio;
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- final int orientation = getContext().getResources().getConfiguration().orientation;
- ResearchLogger.mainKeyboardView_setKeyboard(keyboard, orientation);
- }
- // This always needs to be set since the accessibility state can
- // potentially change without the keyboard being set again.
- AccessibleKeyboardViewProxy.getInstance().setKeyboard(keyboard);
+ if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
+ if (mAccessibilityDelegate == null) {
+ mAccessibilityDelegate = new MainKeyboardAccessibilityDelegate(this, mKeyDetector);
+ }
+ mAccessibilityDelegate.setKeyboard(keyboard);
+ } else {
+ mAccessibilityDelegate = null;
+ }
}
/**
@@ -464,15 +446,15 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
@Override
public void showKeyPreview(final Key key) {
- // If key is invalid or IME is already closed, we must not show key preview.
- // Trying to show key preview while root window is closed causes
- // WindowManager.BadTokenException.
- if (key == null) {
+ // If the key is invalid or has no key preview, we must not show key preview.
+ if (key == null || key.noKeyPreview()) {
return;
}
-
- final KeyPreviewDrawParams previewParams = mKeyPreviewDrawParams;
final Keyboard keyboard = getKeyboard();
+ if (keyboard == null) {
+ return;
+ }
+ final KeyPreviewDrawParams previewParams = mKeyPreviewDrawParams;
if (!previewParams.isPopupEnabled()) {
previewParams.setVisibleOffset(-keyboard.mVerticalGap);
return;
@@ -549,6 +531,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
// Note that this method is called from a non-UI thread.
+ @SuppressWarnings("static-method")
public void setMainDictionaryAvailability(final boolean mainDictionaryAvailable) {
PointerTracker.setMainDictionaryAvailability(mainDictionaryAvailable);
}
@@ -565,24 +548,12 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
protected void onAttachedToWindow() {
super.onAttachedToWindow();
installPreviewPlacerView();
- // Notify the ResearchLogger (development only diagnostics) that the keyboard view has
- // been attached. This is needed to properly show the splash screen, which requires that
- // the window token of the KeyboardView be non-null.
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().mainKeyboardView_onAttachedToWindow(this);
- }
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mDrawingPreviewPlacerView.removeAllViews();
- // Notify the ResearchLogger (development only diagnostics) that the keyboard view has
- // been detached. This is needed to invalidate the reference of {@link MainKeyboardView}
- // to null.
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().mainKeyboardView_onDetachedFromWindow();
- }
}
private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) {
@@ -618,9 +589,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
if (key == null) {
return;
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.mainKeyboardView_onLongPress();
- }
final KeyboardActionListener listener = mKeyboardActionListener;
if (key.hasNoPanelAutoMoreKey()) {
final int moreKeyCode = key.getMoreKeys()[0].mCode;
@@ -733,14 +701,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
public boolean processMotionEvent(final MotionEvent me) {
- if (LatinImeLogger.sUsabilityStudy) {
- UsabilityStudyLogUtils.writeMotionEvent(me);
- }
- // Currently the same "move" event is being logged twice.
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.mainKeyboardView_processMotionEvent(me);
- }
-
final int index = me.getActionIndex();
final int id = me.getPointerId(index);
final PointerTracker tracker = PointerTracker.getPointerTracker(id);
@@ -769,22 +729,23 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
mMoreKeysKeyboardCache.clear();
}
+ public void onHideWindow() {
+ final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ accessibilityDelegate.onHideWindow();
+ }
+ }
+
/**
- * Receives hover events from the input framework.
- *
- * @param event The motion event to be dispatched.
- * @return {@code true} if the event was handled by the view, {@code false}
- * otherwise
+ * {@inheritDoc}
*/
@Override
- public boolean dispatchHoverEvent(final MotionEvent event) {
- if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(
- event, mKeyDetector);
+ public boolean onHoverEvent(final MotionEvent event) {
+ final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ return accessibilityDelegate.onHoverEvent(event);
}
-
- // Reflection doesn't support calling superclass methods.
- return false;
+ return super.onHoverEvent(event);
}
public void updateShortcutKey(final boolean available) {
@@ -825,14 +786,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
invalidateKey(mSpaceKey);
}
- public void updateAutoCorrectionState(final boolean isAutoCorrection) {
- if (!mAutoCorrectionSpacebarLedEnabled) {
- return;
- }
- mAutoCorrectionSpacebarLedOn = isAutoCorrection;
- invalidateKey(mSpaceKey);
- }
-
private void dimEntireKeyboard(final boolean dimmed) {
final boolean needsRedrawing = mNeedsToDimEntireKeyboard != dimmed;
mNeedsToDimEntireKeyboard = dimmed;
@@ -851,42 +804,25 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
}
- // Draw key background.
- @Override
- protected void onDrawKeyBackground(final Key key, final Canvas canvas,
- final Drawable background) {
- if (key.getCode() == Constants.CODE_SPACE) {
- super.onDrawKeyBackground(key, canvas, mSpacebarBackground);
- return;
- }
- super.onDrawKeyBackground(key, canvas, background);
- }
-
@Override
protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
final KeyDrawParams params) {
if (key.altCodeWhileTyping() && key.isEnabled()) {
params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha;
}
- // Don't draw key top letter when key preview is showing.
- if (FADE_OUT_KEY_TOP_LETTER_WHEN_KEY_IS_PRESSED
- && mKeyPreviewChoreographer.isShowingKeyPreview(key)) {
- // TODO: Fade out animation for the key top letter, and fade in animation for the key
- // background color when the user presses the key.
- return;
- }
+ super.onDrawKeyTopVisuals(key, canvas, paint, params);
final int code = key.getCode();
if (code == Constants.CODE_SPACE) {
- drawSpacebar(key, canvas, paint);
+ // If input language are explicitly selected.
+ if (mLanguageOnSpacebarFormatType != LanguageOnSpacebarHelper.FORMAT_TYPE_NONE) {
+ drawLanguageOnSpacebar(key, canvas, paint);
+ }
// Whether space key needs to show the "..." popup hint for special purposes
if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) {
drawKeyPopupHint(key, canvas, paint, params);
}
} else if (code == Constants.CODE_LANGUAGE_SWITCH) {
- super.onDrawKeyTopVisuals(key, canvas, paint, params);
drawKeyPopupHint(key, canvas, paint, params);
- } else {
- super.onDrawKeyTopVisuals(key, canvas, paint, params);
}
}
@@ -926,43 +862,29 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
return "";
}
- private void drawSpacebar(final Key key, final Canvas canvas, final Paint paint) {
+ private void drawLanguageOnSpacebar(final Key key, final Canvas canvas, final Paint paint) {
final int width = key.getWidth();
final int height = key.getHeight();
-
- // If input language are explicitly selected.
- if (mLanguageOnSpacebarFormatType != LanguageOnSpacebarHelper.FORMAT_TYPE_NONE) {
- paint.setTextAlign(Align.CENTER);
- paint.setTypeface(Typeface.DEFAULT);
- paint.setTextSize(mLanguageOnSpacebarTextSize);
- final InputMethodSubtype subtype = getKeyboard().mId.mSubtype;
- final String language = layoutLanguageOnSpacebar(paint, subtype, width);
- // Draw language text with shadow
- final float descent = paint.descent();
- final float textHeight = -paint.ascent() + descent;
- final float baseline = height / 2 + textHeight / 2;
- paint.setColor(mLanguageOnSpacebarTextShadowColor);
- paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
- canvas.drawText(language, width / 2, baseline - descent - 1, paint);
- paint.setColor(mLanguageOnSpacebarTextColor);
- paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
- canvas.drawText(language, width / 2, baseline - descent, paint);
- }
-
- // Draw the spacebar icon at the bottom
- if (mAutoCorrectionSpacebarLedOn) {
- final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100;
- final int iconHeight = mAutoCorrectionSpacebarLedIcon.getIntrinsicHeight();
- int x = (width - iconWidth) / 2;
- int y = height - iconHeight;
- drawIcon(canvas, mAutoCorrectionSpacebarLedIcon, x, y, iconWidth, iconHeight);
- } else if (mSpacebarIcon != null) {
- final int iconWidth = mSpacebarIcon.getIntrinsicWidth();
- final int iconHeight = mSpacebarIcon.getIntrinsicHeight();
- int x = (width - iconWidth) / 2;
- int y = height - iconHeight;
- drawIcon(canvas, mSpacebarIcon, x, y, iconWidth, iconHeight);
+ paint.setTextAlign(Align.CENTER);
+ paint.setTypeface(Typeface.DEFAULT);
+ paint.setTextSize(mLanguageOnSpacebarTextSize);
+ final InputMethodSubtype subtype = getKeyboard().mId.mSubtype;
+ final String language = layoutLanguageOnSpacebar(paint, subtype, width);
+ // Draw language text with shadow
+ final float descent = paint.descent();
+ final float textHeight = -paint.ascent() + descent;
+ final float baseline = height / 2 + textHeight / 2;
+ if (mLanguageOnSpacebarTextShadowRadius > 0.0f) {
+ paint.setShadowLayer(mLanguageOnSpacebarTextShadowRadius, 0, 0,
+ mLanguageOnSpacebarTextShadowColor);
+ } else {
+ paint.clearShadowLayer();
}
+ paint.setColor(mLanguageOnSpacebarTextColor);
+ paint.setAlpha(mLanguageOnSpacebarAnimAlpha);
+ canvas.drawText(language, width / 2, baseline - descent, paint);
+ paint.clearShadowLayer();
+ paint.setTextScaleX(1.0f);
}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index 65242dd76..0f575d30c 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -17,12 +17,13 @@
package com.android.inputmethod.keyboard;
import android.content.Context;
-import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.MoreKeysKeyboardAccessibilityDelegate;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.CoordinateUtils;
@@ -34,7 +35,7 @@ import com.android.inputmethod.latin.utils.CoordinateUtils;
public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel {
private final int[] mCoordinates = CoordinateUtils.newInstance();
- protected final KeyDetector mKeyDetector;
+ protected KeyDetector mKeyDetector;
private Controller mController = EMPTY_CONTROLLER;
protected KeyboardActionListener mListener;
private int mOriginX;
@@ -43,6 +44,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
private int mActivePointerId;
+ protected MoreKeysKeyboardAccessibilityDelegate mAccessibilityDelegate;
+
public MoreKeysKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
@@ -50,10 +53,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
public MoreKeysKeyboardView(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
-
- final Resources res = context.getResources();
- mKeyDetector = new MoreKeysDetector(
- res.getDimension(R.dimen.config_more_keys_keyboard_slide_allowance));
+ mKeyDetector = new MoreKeysDetector(getResources().getDimension(
+ R.dimen.config_more_keys_keyboard_slide_allowance));
}
@Override
@@ -71,8 +72,26 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
@Override
public void setKeyboard(final Keyboard keyboard) {
super.setKeyboard(keyboard);
- mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
- -getPaddingTop() + getVerticalCorrection());
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ // With accessibility mode on, any hover event outside {@link MoreKeysKeyboardView} is
+ // discarded at {@link InputView#dispatchHoverEvent(MotionEvent)}. Because only a hover
+ // event that is on this view is dispatched by the platform, we should use a
+ // {@link KeyDetector} that has no sliding allowance and no hysteresis.
+ if (mAccessibilityDelegate == null) {
+ mKeyDetector = new KeyDetector();
+ mAccessibilityDelegate = new MoreKeysKeyboardAccessibilityDelegate(
+ this, mKeyDetector);
+ mAccessibilityDelegate.setOpenAnnounce(R.string.spoken_open_more_keys_keyboard);
+ mAccessibilityDelegate.setCloseAnnounce(R.string.spoken_close_more_keys_keyboard);
+ }
+ mAccessibilityDelegate.setKeyboard(keyboard);
+ } else {
+ mKeyDetector = new MoreKeysDetector(getResources().getDimension(
+ R.dimen.config_more_keys_keyboard_slide_allowance));
+ mAccessibilityDelegate = null;
+ }
+ mKeyDetector.setKeyboard(
+ keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection());
}
@Override
@@ -98,6 +117,10 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
mOriginX = x + container.getPaddingLeft();
mOriginY = y + container.getPaddingTop();
controller.onShowMoreKeysPanel(this);
+ final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ accessibilityDelegate.onShowMoreKeysKeyboard();
+ }
}
/**
@@ -110,27 +133,33 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
@Override
public void onDownEvent(final int x, final int y, final int pointerId, final long eventTime) {
mActivePointerId = pointerId;
- onMoveKeyInternal(x, y, pointerId);
+ mCurrentKey = detectKey(x, y, pointerId);
}
@Override
- public void onMoveEvent(int x, int y, final int pointerId, long eventTime) {
+ public void onMoveEvent(final int x, final int y, final int pointerId, final long eventTime) {
if (mActivePointerId != pointerId) {
return;
}
final boolean hasOldKey = (mCurrentKey != null);
- onMoveKeyInternal(x, y, pointerId);
+ mCurrentKey = detectKey(x, y, pointerId);
if (hasOldKey && mCurrentKey == null) {
- // If the pointer has moved too far away from any target then cancel the panel.
+ // A more keys keyboard is canceled when detecting no key.
mController.onCancelMoreKeysPanel();
}
}
@Override
public void onUpEvent(final int x, final int y, final int pointerId, final long eventTime) {
- if (mCurrentKey != null && mActivePointerId == pointerId) {
+ if (mActivePointerId != pointerId) {
+ return;
+ }
+ // Calling {@link #detectKey(int,int,int)} here is harmless because the last move event and
+ // the following up event share the same coordinates.
+ mCurrentKey = detectKey(x, y, pointerId);
+ if (mCurrentKey != null) {
updateReleaseKeyGraphics(mCurrentKey);
- onCodeInput(mCurrentKey.getCode(), x, y);
+ onKeyInput(mCurrentKey, x, y);
mCurrentKey = null;
}
}
@@ -138,7 +167,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
/**
* Performs the specific action for this panel when the user presses a key on the panel.
*/
- protected void onCodeInput(final int code, final int x, final int y) {
+ protected void onKeyInput(final Key key, final int x, final int y) {
+ final int code = key.getCode();
if (code == Constants.CODE_OUTPUT_TEXT) {
mListener.onTextInput(mCurrentKey.getOutputText());
} else if (code != Constants.CODE_UNSPECIFIED) {
@@ -151,23 +181,22 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
}
}
- private void onMoveKeyInternal(int x, int y, int pointerId) {
- if (mActivePointerId != pointerId) {
- // Ignore old pointers when newer pointer is active.
- return;
- }
+ private Key detectKey(int x, int y, int pointerId) {
final Key oldKey = mCurrentKey;
final Key newKey = mKeyDetector.detectHitKey(x, y);
- if (newKey != oldKey) {
- mCurrentKey = newKey;
- invalidateKey(mCurrentKey);
- if (oldKey != null) {
- updateReleaseKeyGraphics(oldKey);
- }
- if (newKey != null) {
- updatePressKeyGraphics(newKey);
- }
+ if (newKey == oldKey) {
+ return newKey;
}
+ // A new key is detected.
+ if (oldKey != null) {
+ updateReleaseKeyGraphics(oldKey);
+ invalidateKey(oldKey);
+ }
+ if (newKey != null) {
+ updatePressKeyGraphics(newKey);
+ invalidateKey(newKey);
+ }
+ return newKey;
}
private void updateReleaseKeyGraphics(final Key key) {
@@ -222,6 +251,18 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
return true;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onHoverEvent(final MotionEvent event) {
+ final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ return accessibilityDelegate.onHoverEvent(event);
+ }
+ return super.onHoverEvent(event);
+ }
+
private View getContainerView() {
return (View)getParent();
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 4777166ea..b6905bc1c 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -35,12 +35,9 @@ import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.Settings;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
-import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList;
@@ -144,7 +141,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
// TODO: Device specific parameter would be better for device specific hack?
private static final float PHANTOM_SUDDEN_MOVE_THRESHOLD = 0.25f; // in keyWidth
- private static final ArrayList<PointerTracker> sTrackers = CollectionUtils.newArrayList();
+ private static final ArrayList<PointerTracker> sTrackers = new ArrayList<>();
private static final PointerTrackerQueue sPointerTrackerQueue = new PointerTrackerQueue();
public final int mPointerId;
@@ -336,10 +333,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
output, ignoreModifierKey ? " ignoreModifier" : "",
altersCode ? " altersCode" : "", key.isEnabled() ? "" : " disabled"));
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.pointerTracker_callListenerOnCodeInput(key, x, y, ignoreModifierKey,
- altersCode, code);
- }
if (ignoreModifierKey) {
return;
}
@@ -374,10 +367,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
withSliding ? " sliding" : "", ignoreModifierKey ? " ignoreModifier" : "",
key.isEnabled() ? "": " disabled"));
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.pointerTracker_callListenerOnRelease(key, primaryCode, withSliding,
- ignoreModifierKey);
- }
if (ignoreModifierKey) {
return;
}
@@ -397,9 +386,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onCancelInput", mPointerId));
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.pointerTracker_callListenerOnCancelInput();
- }
sListener.onCancelInput();
}
@@ -690,10 +676,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
private void onDownEvent(final int x, final int y, final long eventTime,
final KeyDetector keyDetector) {
+ setKeyDetectorInner(keyDetector);
if (DEBUG_EVENT) {
printTouchEvent("onDownEvent:", x, y, eventTime);
}
- setKeyDetectorInner(keyDetector);
// Naive up-to-down noise filter.
final long deltaT = eventTime - mUpTime;
if (deltaT < sParams.mTouchNoiseThresholdTime) {
@@ -703,9 +689,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
Log.w(TAG, String.format("[%d] onDownEvent:"
+ " ignore potential noise: time=%d distance=%d",
mPointerId, deltaT, distance));
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.pointerTracker_onDownEvent(deltaT, distance * distance);
- }
cancelTrackingForAction();
return;
}
@@ -877,10 +860,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
lastX, lastY, Constants.printableCode(oldKey.getCode()),
x, y, Constants.printableCode(key.getCode())));
}
- // TODO: This should be moved to outside of this nested if-clause?
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.pointerTracker_onMoveEvent(x, y, lastX, lastY);
- }
onUpEventInternal(x, y, eventTime);
onDownEventInternal(x, y, eventTime);
}
@@ -1054,8 +1033,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final int translatedY = mMoreKeysPanel.translateY(y);
mMoreKeysPanel.onUpEvent(translatedX, translatedY, mPointerId, eventTime);
}
- mMoreKeysPanel.dismissMoreKeysPanel();
- mMoreKeysPanel = null;
+ dismissMoreKeysPanel();
return;
}
@@ -1100,6 +1078,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
mIsTrackingForActionDisabled = true;
}
+ public boolean isInOperation() {
+ return !mIsTrackingForActionDisabled;
+ }
+
+ public void cancelLongPressTimer() {
+ sTimerProxy.cancelLongPressTimerOf(this);
+ }
+
public void onLongPressed() {
resetKeySelectionByDraggingFinger();
cancelTrackingForAction();
@@ -1122,10 +1108,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
sTimerProxy.cancelKeyTimersOf(this);
setReleasedKeyGraphics(mCurrentKey);
resetKeySelectionByDraggingFinger();
- if (isShowingMoreKeysPanel()) {
- mMoreKeysPanel.dismissMoreKeysPanel();
- mMoreKeysPanel = null;
- }
+ dismissMoreKeysPanel();
}
private boolean isMajorEnoughMoveToBeOnNewKey(final int x, final int y, final long eventTime,
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index c89bda40e..c19cd671a 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -22,7 +22,6 @@ import android.util.Log;
import com.android.inputmethod.keyboard.internal.TouchPositionCorrection;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import java.util.ArrayList;
@@ -55,6 +54,7 @@ public class ProximityInfo {
private final List<Key>[] mGridNeighbors;
private final String mLocaleStr;
+ @SuppressWarnings("unchecked")
ProximityInfo(final String localeStr, final int gridWidth, final int gridHeight,
final int minWidth, final int height, final int mostCommonKeyWidth,
final int mostCommonKeyHeight, final List<Key> sortedKeys,
@@ -360,7 +360,7 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
for (int i = 0; i < gridSize; ++i) {
final int indexStart = i * keyCount;
final int indexEnd = indexStart + neighborCountPerCell[i];
- final ArrayList<Key> neighbors = CollectionUtils.newArrayList(indexEnd - indexStart);
+ final ArrayList<Key> neighbors = new ArrayList<>(indexEnd - indexStart);
for (int index = indexStart; index < indexEnd; index++) {
neighbors.add(neighborsFlatBuffer[index]);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java
index 67a222732..daeb1f928 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/DynamicGridKeyboard.java
@@ -14,17 +14,15 @@
* limitations under the License.
*/
-package com.android.inputmethod.keyboard.internal;
+package com.android.inputmethod.keyboard.emoji;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;
-import com.android.inputmethod.keyboard.EmojiPalettesView;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.settings.Settings;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.JsonUtils;
import java.util.ArrayDeque;
@@ -36,7 +34,7 @@ import java.util.List;
/**
* This is a Keyboard class where you can add keys dynamically shown in a grid layout
*/
-public class DynamicGridKeyboard extends Keyboard {
+final class DynamicGridKeyboard extends Keyboard {
private static final String TAG = DynamicGridKeyboard.class.getSimpleName();
private static final int TEMPLATE_KEY_CODE_0 = 0x30;
private static final int TEMPLATE_KEY_CODE_1 = 0x31;
@@ -48,8 +46,8 @@ public class DynamicGridKeyboard extends Keyboard {
private final int mColumnsNum;
private final int mMaxKeyCount;
private final boolean mIsRecents;
- private final ArrayDeque<GridKey> mGridKeys = CollectionUtils.newArrayDeque();
- private final ArrayDeque<Key> mPendingKeys = CollectionUtils.newArrayDeque();
+ private final ArrayDeque<GridKey> mGridKeys = new ArrayDeque<>();
+ private final ArrayDeque<Key> mPendingKeys = new ArrayDeque<>();
private List<Key> mCachedGridKeys;
@@ -62,7 +60,7 @@ public class DynamicGridKeyboard extends Keyboard {
mVerticalStep = key0.getHeight() + mVerticalGap;
mColumnsNum = mBaseWidth / mHorizontalStep;
mMaxKeyCount = maxKeyCount;
- mIsRecents = categoryId == EmojiPalettesView.CATEGORY_ID_RECENTS;
+ mIsRecents = categoryId == EmojiCategory.ID_RECENTS;
mPrefs = prefs;
}
@@ -132,7 +130,7 @@ public class DynamicGridKeyboard extends Keyboard {
}
private void saveRecentKeys() {
- final ArrayList<Object> keys = CollectionUtils.newArrayList();
+ final ArrayList<Object> keys = new ArrayList<>();
for (final Key key : mGridKeys) {
if (key.getOutputText() != null) {
keys.add(key.getOutputText());
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java
new file mode 100644
index 000000000..512d4615d
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategory.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.emoji;
+
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.os.Build;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardId;
+import com.android.inputmethod.keyboard.KeyboardLayoutSet;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.settings.Settings;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+final class EmojiCategory {
+ private final String TAG = EmojiCategory.class.getSimpleName();
+
+ private static final int ID_UNSPECIFIED = -1;
+ public static final int ID_RECENTS = 0;
+ private static final int ID_PEOPLE = 1;
+ private static final int ID_OBJECTS = 2;
+ private static final int ID_NATURE = 3;
+ private static final int ID_PLACES = 4;
+ private static final int ID_SYMBOLS = 5;
+ private static final int ID_EMOTICONS = 6;
+
+ public final class CategoryProperties {
+ public final int mCategoryId;
+ public final int mPageCount;
+ public CategoryProperties(final int categoryId, final int pageCount) {
+ mCategoryId = categoryId;
+ mPageCount = pageCount;
+ }
+ }
+
+ private static final String[] sCategoryName = {
+ "recents",
+ "people",
+ "objects",
+ "nature",
+ "places",
+ "symbols",
+ "emoticons" };
+
+ private static final int[] sCategoryTabIconAttr = {
+ R.styleable.EmojiPalettesView_iconEmojiRecentsTab,
+ R.styleable.EmojiPalettesView_iconEmojiCategory1Tab,
+ R.styleable.EmojiPalettesView_iconEmojiCategory2Tab,
+ R.styleable.EmojiPalettesView_iconEmojiCategory3Tab,
+ R.styleable.EmojiPalettesView_iconEmojiCategory4Tab,
+ R.styleable.EmojiPalettesView_iconEmojiCategory5Tab,
+ R.styleable.EmojiPalettesView_iconEmojiCategory6Tab };
+
+ private static final int[] sAccessibilityDescriptionResourceIdsForCategories = {
+ R.string.spoken_descrption_emoji_category_recents,
+ R.string.spoken_descrption_emoji_category_people,
+ R.string.spoken_descrption_emoji_category_objects,
+ R.string.spoken_descrption_emoji_category_nature,
+ R.string.spoken_descrption_emoji_category_places,
+ R.string.spoken_descrption_emoji_category_symbols,
+ R.string.spoken_descrption_emoji_category_emoticons };
+
+ private static final int[] sCategoryElementId = {
+ KeyboardId.ELEMENT_EMOJI_RECENTS,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY1,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY2,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY3,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY4,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY5,
+ KeyboardId.ELEMENT_EMOJI_CATEGORY6 };
+
+ private final SharedPreferences mPrefs;
+ private final Resources mRes;
+ private final int mMaxPageKeyCount;
+ private final KeyboardLayoutSet mLayoutSet;
+ private final HashMap<String, Integer> mCategoryNameToIdMap = new HashMap<>();
+ private final int[] mCategoryTabIconId = new int[sCategoryName.length];
+ private final ArrayList<CategoryProperties> mShownCategories = new ArrayList<>();
+ private final ConcurrentHashMap<Long, DynamicGridKeyboard> mCategoryKeyboardMap =
+ new ConcurrentHashMap<>();
+
+ private int mCurrentCategoryId = EmojiCategory.ID_UNSPECIFIED;
+ private int mCurrentCategoryPageId = 0;
+
+ public EmojiCategory(final SharedPreferences prefs, final Resources res,
+ final KeyboardLayoutSet layoutSet, final TypedArray emojiPaletteViewAttr) {
+ mPrefs = prefs;
+ mRes = res;
+ mMaxPageKeyCount = res.getInteger(R.integer.config_emoji_keyboard_max_page_key_count);
+ mLayoutSet = layoutSet;
+ for (int i = 0; i < sCategoryName.length; ++i) {
+ mCategoryNameToIdMap.put(sCategoryName[i], i);
+ mCategoryTabIconId[i] = emojiPaletteViewAttr.getResourceId(
+ sCategoryTabIconAttr[i], 0);
+ }
+ addShownCategoryId(EmojiCategory.ID_RECENTS);
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2
+ || android.os.Build.VERSION.CODENAME.equalsIgnoreCase("KeyLimePie")
+ || android.os.Build.VERSION.CODENAME.equalsIgnoreCase("KitKat")) {
+ addShownCategoryId(EmojiCategory.ID_PEOPLE);
+ addShownCategoryId(EmojiCategory.ID_OBJECTS);
+ addShownCategoryId(EmojiCategory.ID_NATURE);
+ addShownCategoryId(EmojiCategory.ID_PLACES);
+ mCurrentCategoryId =
+ Settings.readLastShownEmojiCategoryId(mPrefs, EmojiCategory.ID_PEOPLE);
+ } else {
+ mCurrentCategoryId =
+ Settings.readLastShownEmojiCategoryId(mPrefs, EmojiCategory.ID_SYMBOLS);
+ }
+ addShownCategoryId(EmojiCategory.ID_SYMBOLS);
+ addShownCategoryId(EmojiCategory.ID_EMOTICONS);
+ getKeyboard(EmojiCategory.ID_RECENTS, 0 /* cagetoryPageId */)
+ .loadRecentKeys(mCategoryKeyboardMap.values());
+ }
+
+ private void addShownCategoryId(final int categoryId) {
+ // Load a keyboard of categoryId
+ getKeyboard(categoryId, 0 /* cagetoryPageId */);
+ final CategoryProperties properties =
+ new CategoryProperties(categoryId, getCategoryPageCount(categoryId));
+ mShownCategories.add(properties);
+ }
+
+ public String getCategoryName(final int categoryId, final int categoryPageId) {
+ return sCategoryName[categoryId] + "-" + categoryPageId;
+ }
+
+ public int getCategoryId(final String name) {
+ final String[] strings = name.split("-");
+ return mCategoryNameToIdMap.get(strings[0]);
+ }
+
+ public int getCategoryTabIcon(final int categoryId) {
+ return mCategoryTabIconId[categoryId];
+ }
+
+ public String getAccessibilityDescription(final int categoryId) {
+ return mRes.getString(sAccessibilityDescriptionResourceIdsForCategories[categoryId]);
+ }
+
+ public ArrayList<CategoryProperties> getShownCategories() {
+ return mShownCategories;
+ }
+
+ public int getCurrentCategoryId() {
+ return mCurrentCategoryId;
+ }
+
+ public int getCurrentCategoryPageSize() {
+ return getCategoryPageSize(mCurrentCategoryId);
+ }
+
+ public int getCategoryPageSize(final int categoryId) {
+ for (final CategoryProperties prop : mShownCategories) {
+ if (prop.mCategoryId == categoryId) {
+ return prop.mPageCount;
+ }
+ }
+ Log.w(TAG, "Invalid category id: " + categoryId);
+ // Should not reach here.
+ return 0;
+ }
+
+ public void setCurrentCategoryId(final int categoryId) {
+ mCurrentCategoryId = categoryId;
+ Settings.writeLastShownEmojiCategoryId(mPrefs, categoryId);
+ }
+
+ public void setCurrentCategoryPageId(final int id) {
+ mCurrentCategoryPageId = id;
+ }
+
+ public int getCurrentCategoryPageId() {
+ return mCurrentCategoryPageId;
+ }
+
+ public void saveLastTypedCategoryPage() {
+ Settings.writeLastTypedEmojiCategoryPageId(
+ mPrefs, mCurrentCategoryId, mCurrentCategoryPageId);
+ }
+
+ public boolean isInRecentTab() {
+ return mCurrentCategoryId == EmojiCategory.ID_RECENTS;
+ }
+
+ public int getTabIdFromCategoryId(final int categoryId) {
+ for (int i = 0; i < mShownCategories.size(); ++i) {
+ if (mShownCategories.get(i).mCategoryId == categoryId) {
+ return i;
+ }
+ }
+ Log.w(TAG, "categoryId not found: " + categoryId);
+ return 0;
+ }
+
+ // Returns the view pager's page position for the categoryId
+ public int getPageIdFromCategoryId(final int categoryId) {
+ final int lastSavedCategoryPageId =
+ Settings.readLastTypedEmojiCategoryPageId(mPrefs, categoryId);
+ int sum = 0;
+ for (int i = 0; i < mShownCategories.size(); ++i) {
+ final CategoryProperties props = mShownCategories.get(i);
+ if (props.mCategoryId == categoryId) {
+ return sum + lastSavedCategoryPageId;
+ }
+ sum += props.mPageCount;
+ }
+ Log.w(TAG, "categoryId not found: " + categoryId);
+ return 0;
+ }
+
+ public int getRecentTabId() {
+ return getTabIdFromCategoryId(EmojiCategory.ID_RECENTS);
+ }
+
+ private int getCategoryPageCount(final int categoryId) {
+ final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]);
+ return (keyboard.getSortedKeys().size() - 1) / mMaxPageKeyCount + 1;
+ }
+
+ // Returns a pair of the category id and the category page id from the view pager's page
+ // position. The category page id is numbered in each category. And the view page position
+ // is the position of the current shown page in the view pager which contains all pages of
+ // all categories.
+ public Pair<Integer, Integer> getCategoryIdAndPageIdFromPagePosition(final int position) {
+ int sum = 0;
+ for (final CategoryProperties properties : mShownCategories) {
+ final int temp = sum;
+ sum += properties.mPageCount;
+ if (sum > position) {
+ return new Pair<>(properties.mCategoryId, position - temp);
+ }
+ }
+ return null;
+ }
+
+ // Returns a keyboard from the view pager's page position.
+ public DynamicGridKeyboard getKeyboardFromPagePosition(final int position) {
+ final Pair<Integer, Integer> categoryAndId =
+ getCategoryIdAndPageIdFromPagePosition(position);
+ if (categoryAndId != null) {
+ return getKeyboard(categoryAndId.first, categoryAndId.second);
+ }
+ return null;
+ }
+
+ private static final Long getCategoryKeyboardMapKey(final int categoryId, final int id) {
+ return (((long) categoryId) << Constants.MAX_INT_BIT_COUNT) | id;
+ }
+
+ public DynamicGridKeyboard getKeyboard(final int categoryId, final int id) {
+ synchronized (mCategoryKeyboardMap) {
+ final Long categotyKeyboardMapKey = getCategoryKeyboardMapKey(categoryId, id);
+ if (mCategoryKeyboardMap.containsKey(categotyKeyboardMapKey)) {
+ return mCategoryKeyboardMap.get(categotyKeyboardMapKey);
+ }
+
+ if (categoryId == EmojiCategory.ID_RECENTS) {
+ final DynamicGridKeyboard kbd = new DynamicGridKeyboard(mPrefs,
+ mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
+ mMaxPageKeyCount, categoryId);
+ mCategoryKeyboardMap.put(categotyKeyboardMapKey, kbd);
+ return kbd;
+ }
+
+ final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]);
+ final Key[][] sortedKeys = sortKeysIntoPages(
+ keyboard.getSortedKeys(), mMaxPageKeyCount);
+ for (int pageId = 0; pageId < sortedKeys.length; ++pageId) {
+ final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs,
+ mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
+ mMaxPageKeyCount, categoryId);
+ for (final Key emojiKey : sortedKeys[pageId]) {
+ if (emojiKey == null) {
+ break;
+ }
+ tempKeyboard.addKeyLast(emojiKey);
+ }
+ mCategoryKeyboardMap.put(
+ getCategoryKeyboardMapKey(categoryId, pageId), tempKeyboard);
+ }
+ return mCategoryKeyboardMap.get(categotyKeyboardMapKey);
+ }
+ }
+
+ public int getTotalPageCountOfAllCategories() {
+ int sum = 0;
+ for (CategoryProperties properties : mShownCategories) {
+ sum += properties.mPageCount;
+ }
+ return sum;
+ }
+
+ private static Comparator<Key> EMOJI_KEY_COMPARATOR = new Comparator<Key>() {
+ @Override
+ public int compare(final Key lhs, final Key rhs) {
+ final Rect lHitBox = lhs.getHitBox();
+ final Rect rHitBox = rhs.getHitBox();
+ if (lHitBox.top < rHitBox.top) {
+ return -1;
+ } else if (lHitBox.top > rHitBox.top) {
+ return 1;
+ }
+ if (lHitBox.left < rHitBox.left) {
+ return -1;
+ } else if (lHitBox.left > rHitBox.left) {
+ return 1;
+ }
+ if (lhs.getCode() == rhs.getCode()) {
+ return 0;
+ }
+ return lhs.getCode() < rhs.getCode() ? -1 : 1;
+ }
+ };
+
+ private static Key[][] sortKeysIntoPages(final List<Key> inKeys, final int maxPageCount) {
+ final ArrayList<Key> keys = new ArrayList<>(inKeys);
+ Collections.sort(keys, EMOJI_KEY_COMPARATOR);
+ final int pageCount = (keys.size() - 1) / maxPageCount + 1;
+ final Key[][] retval = new Key[pageCount][maxPageCount];
+ for (int i = 0; i < keys.size(); ++i) {
+ retval[i / maxPageCount][i % maxPageCount] = keys.get(i);
+ }
+ return retval;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java
index d56a3cf25..43d62c71a 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiCategoryPageIndicatorView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiCategoryPageIndicatorView.java
@@ -14,31 +14,33 @@
* limitations under the License.
*/
-package com.android.inputmethod.keyboard;
-
-import com.android.inputmethod.latin.R;
+package com.android.inputmethod.keyboard.emoji;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
-import android.widget.LinearLayout;
+import android.view.View;
-public class EmojiCategoryPageIndicatorView extends LinearLayout {
- private static final float BOTTOM_MARGIN_RATIO = 0.66f;
+public final class EmojiCategoryPageIndicatorView extends View {
+ private static final float BOTTOM_MARGIN_RATIO = 1.0f;
private final Paint mPaint = new Paint();
private int mCategoryPageSize = 0;
private int mCurrentCategoryPageId = 0;
private float mOffset = 0.0f;
- public EmojiCategoryPageIndicatorView(final Context context) {
- this(context, null /* attrs */);
+ public EmojiCategoryPageIndicatorView(final Context context, final AttributeSet attrs) {
+ this(context, attrs, 0);
}
- public EmojiCategoryPageIndicatorView(final Context context, final AttributeSet attrs) {
- super(context, attrs);
- mPaint.setColor(context.getResources().getColor(
- R.color.emoji_category_page_id_view_foreground));
+ public EmojiCategoryPageIndicatorView(final Context context, final AttributeSet attrs,
+ final int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public void setColors(final int foregroundColor, final int backgroundColor) {
+ mPaint.setColor(foregroundColor);
+ setBackgroundColor(backgroundColor);
}
public void setCategoryPageId(final int size, final int id, final float offset) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java
index d57ea5a94..582e09124 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/EmojiLayoutParams.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiLayoutParams.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.inputmethod.keyboard.internal;
-
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.ResourceUtils;
+package com.android.inputmethod.keyboard.emoji;
import android.content.res.Resources;
import android.support.v4.view.ViewPager;
-import android.widget.ImageView;
+import android.view.View;
import android.widget.LinearLayout;
-public class EmojiLayoutParams {
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+
+final class EmojiLayoutParams {
private static final int DEFAULT_KEYBOARD_ROWS = 4;
public final int mEmojiPagerHeight;
@@ -67,10 +67,10 @@ public class EmojiLayoutParams {
vp.setLayoutParams(lp);
}
- public void setCategoryPageIdViewProperties(final LinearLayout ll) {
- final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
+ public void setCategoryPageIdViewProperties(final View v) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) v.getLayoutParams();
lp.height = mEmojiCategoryPageIdViewHeight;
- ll.setLayoutParams(lp);
+ v.setLayoutParams(lp);
}
public int getActionBarHeight() {
@@ -83,10 +83,10 @@ public class EmojiLayoutParams {
ll.setLayoutParams(lp);
}
- public void setKeyProperties(final ImageView ib) {
- final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ib.getLayoutParams();
+ public void setKeyProperties(final View v) {
+ final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = mKeyHorizontalGap / 2;
lp.rightMargin = mKeyHorizontalGap / 2;
- ib.setLayoutParams(lp);
+ v.setLayoutParams(lp);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
index e175a051e..80ba60c82 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/EmojiPageKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.inputmethod.keyboard.internal;
+package com.android.inputmethod.keyboard.emoji;
import android.content.Context;
import android.os.Handler;
@@ -22,19 +22,20 @@ import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.KeyboardAccessibilityDelegate;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyDetector;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.latin.R;
/**
* This is an extended {@link KeyboardView} class that hosts an emoji page keyboard.
- * Multi-touch unsupported. No {@link PointerTracker}s. No gesture support.
+ * Multi-touch unsupported. No gesture support.
*/
// TODO: Implement key popup preview.
-public final class EmojiPageKeyboardView extends KeyboardView implements
+final class EmojiPageKeyboardView extends KeyboardView implements
GestureDetector.OnGestureListener {
private static final long KEY_PRESS_DELAY_TIME = 250; // msec
private static final long KEY_RELEASE_DELAY_TIME = 30; // msec
@@ -54,6 +55,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
private OnKeyEventListener mListener = EMPTY_LISTENER;
private final KeyDetector mKeyDetector = new KeyDetector();
private final GestureDetector mGestureDetector;
+ private KeyboardAccessibilityDelegate<EmojiPageKeyboardView> mAccessibilityDelegate;
public EmojiPageKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.keyboardViewStyle);
@@ -78,6 +80,27 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
public void setKeyboard(final Keyboard keyboard) {
super.setKeyboard(keyboard);
mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
+ if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
+ if (mAccessibilityDelegate == null) {
+ mAccessibilityDelegate = new KeyboardAccessibilityDelegate<>(this, mKeyDetector);
+ }
+ mAccessibilityDelegate.setKeyboard(keyboard);
+ } else {
+ mAccessibilityDelegate = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onHoverEvent(final MotionEvent event) {
+ final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> accessibilityDelegate =
+ mAccessibilityDelegate;
+ if (accessibilityDelegate != null) {
+ return accessibilityDelegate.onHoverEvent(event);
+ }
+ return super.onHoverEvent(event);
}
/**
@@ -90,7 +113,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
}
final Key key = getKey(e);
if (key != null && key != mCurrentKey) {
- releaseCurrentKey();
+ releaseCurrentKey(false /* withKeyRegistering */);
}
return true;
}
@@ -107,7 +130,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
return mKeyDetector.detectHitKey(x, y);
}
- public void releaseCurrentKey() {
+ public void releaseCurrentKey(final boolean withKeyRegistering) {
mHandler.removeCallbacks(mPendingKeyDown);
mPendingKeyDown = null;
final Key currentKey = mCurrentKey;
@@ -116,13 +139,16 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
}
currentKey.onReleased();
invalidateKey(currentKey);
+ if (withKeyRegistering) {
+ mListener.onReleaseKey(currentKey);
+ }
mCurrentKey = null;
}
@Override
public boolean onDown(final MotionEvent e) {
final Key key = getKey(e);
- releaseCurrentKey();
+ releaseCurrentKey(false /* withKeyRegistering */);
mCurrentKey = key;
if (key == null) {
return false;
@@ -151,7 +177,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
final Key key = getKey(e);
final Runnable pendingKeyDown = mPendingKeyDown;
final Key currentKey = mCurrentKey;
- releaseCurrentKey();
+ releaseCurrentKey(false /* withKeyRegistering */);
if (key == null) {
return false;
}
@@ -177,14 +203,14 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
@Override
public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
final float distanceY) {
- releaseCurrentKey();
+ releaseCurrentKey(false /* withKeyRegistering */);
return false;
}
@Override
public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX,
final float velocityY) {
- releaseCurrentKey();
+ releaseCurrentKey(false /* withKeyRegistering */);
return false;
}
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java
new file mode 100644
index 000000000..68056e0eb
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.emoji;
+
+import android.support.v4.view.PagerAdapter;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.latin.R;
+
+final class EmojiPalettesAdapter extends PagerAdapter {
+ private static final String TAG = EmojiPalettesAdapter.class.getSimpleName();
+ private static final boolean DEBUG_PAGER = false;
+
+ private final EmojiPageKeyboardView.OnKeyEventListener mListener;
+ private final DynamicGridKeyboard mRecentsKeyboard;
+ private final SparseArray<EmojiPageKeyboardView> mActiveKeyboardViews = new SparseArray<>();
+ private final EmojiCategory mEmojiCategory;
+ private int mActivePosition = 0;
+
+ public EmojiPalettesAdapter(final EmojiCategory emojiCategory,
+ final EmojiPageKeyboardView.OnKeyEventListener listener) {
+ mEmojiCategory = emojiCategory;
+ mListener = listener;
+ mRecentsKeyboard = mEmojiCategory.getKeyboard(EmojiCategory.ID_RECENTS, 0);
+ }
+
+ public void flushPendingRecentKeys() {
+ mRecentsKeyboard.flushPendingRecentKeys();
+ final KeyboardView recentKeyboardView =
+ mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
+ if (recentKeyboardView != null) {
+ recentKeyboardView.invalidateAllKeys();
+ }
+ }
+
+ public void addRecentKey(final Key key) {
+ if (mEmojiCategory.isInRecentTab()) {
+ mRecentsKeyboard.addPendingKey(key);
+ return;
+ }
+ mRecentsKeyboard.addKeyFirst(key);
+ final KeyboardView recentKeyboardView =
+ mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
+ if (recentKeyboardView != null) {
+ recentKeyboardView.invalidateAllKeys();
+ }
+ }
+
+ public void onPageScrolled() {
+ releaseCurrentKey(false /* withKeyRegistering */);
+ }
+
+ public void releaseCurrentKey(final boolean withKeyRegistering) {
+ // Make sure the delayed key-down event (highlight effect and haptic feedback) will be
+ // canceled.
+ final EmojiPageKeyboardView currentKeyboardView =
+ mActiveKeyboardViews.get(mActivePosition);
+ if (currentKeyboardView == null) {
+ return;
+ }
+ currentKeyboardView.releaseCurrentKey(withKeyRegistering);
+ }
+
+ @Override
+ public int getCount() {
+ return mEmojiCategory.getTotalPageCountOfAllCategories();
+ }
+
+ @Override
+ public void setPrimaryItem(final ViewGroup container, final int position,
+ final Object object) {
+ if (mActivePosition == position) {
+ return;
+ }
+ final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(mActivePosition);
+ if (oldKeyboardView != null) {
+ oldKeyboardView.releaseCurrentKey(false /* withKeyRegistering */);
+ oldKeyboardView.deallocateMemory();
+ }
+ mActivePosition = position;
+ }
+
+ @Override
+ public Object instantiateItem(final ViewGroup container, final int position) {
+ if (DEBUG_PAGER) {
+ Log.d(TAG, "instantiate item: " + position);
+ }
+ final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(position);
+ if (oldKeyboardView != null) {
+ oldKeyboardView.deallocateMemory();
+ // This may be redundant but wanted to be safer..
+ mActiveKeyboardViews.remove(position);
+ }
+ final Keyboard keyboard =
+ mEmojiCategory.getKeyboardFromPagePosition(position);
+ final LayoutInflater inflater = LayoutInflater.from(container.getContext());
+ final EmojiPageKeyboardView keyboardView = (EmojiPageKeyboardView)inflater.inflate(
+ R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
+ keyboardView.setKeyboard(keyboard);
+ keyboardView.setOnKeyEventListener(mListener);
+ container.addView(keyboardView);
+ mActiveKeyboardViews.put(position, keyboardView);
+ return keyboardView;
+ }
+
+ @Override
+ public boolean isViewFromObject(final View view, final Object object) {
+ return view == object;
+ }
+
+ @Override
+ public void destroyItem(final ViewGroup container, final int position,
+ final Object object) {
+ if (DEBUG_PAGER) {
+ Log.d(TAG, "destroy item: " + position + ", " + object.getClass().getSimpleName());
+ }
+ final EmojiPageKeyboardView keyboardView = mActiveKeyboardViews.get(position);
+ if (keyboardView != null) {
+ keyboardView.deallocateMemory();
+ mActiveKeyboardViews.remove(position);
+ }
+ if (object instanceof View) {
+ container.removeView((View)object);
+ } else {
+ Log.w(TAG, "Warning!!! Emoji palette may be leaking. " + object);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
new file mode 100644
index 000000000..e37cd2369
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.emoji;
+
+import static com.android.inputmethod.latin.Constants.NOT_A_COORDINATE;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.os.CountDownTimer;
+import android.preference.PreferenceManager;
+import android.support.v4.view.ViewPager;
+import android.util.AttributeSet;
+import android.util.Pair;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TabHost;
+import android.widget.TabHost.OnTabChangeListener;
+import android.widget.TabWidget;
+import android.widget.TextView;
+
+import com.android.inputmethod.keyboard.Key;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
+import com.android.inputmethod.keyboard.KeyboardLayoutSet;
+import com.android.inputmethod.keyboard.KeyboardView;
+import com.android.inputmethod.keyboard.internal.KeyDrawParams;
+import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
+import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.SubtypeSwitcher;
+import com.android.inputmethod.latin.utils.ResourceUtils;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * View class to implement Emoji palettes.
+ * The Emoji keyboard consists of group of views layout/emoji_palettes_view.
+ * <ol>
+ * <li> Emoji category tabs.
+ * <li> Delete button.
+ * <li> Emoji keyboard pages that can be scrolled by swiping horizontally or by selecting a tab.
+ * <li> Back to main keyboard button and enter button.
+ * </ol>
+ * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
+ */
+public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener,
+ ViewPager.OnPageChangeListener, View.OnClickListener, View.OnTouchListener,
+ EmojiPageKeyboardView.OnKeyEventListener {
+ private final int mFunctionalKeyBackgroundId;
+ private final int mSpacebarBackgroundId;
+ private final boolean mCategoryIndicatorEnabled;
+ private final int mCategoryIndicatorDrawableResId;
+ private final int mCategoryIndicatorBackgroundResId;
+ private final int mCategoryPageIndicatorColor;
+ private final int mCategoryPageIndicatorBackground;
+ private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
+ private EmojiPalettesAdapter mEmojiPalettesAdapter;
+ private final EmojiLayoutParams mEmojiLayoutParams;
+
+ private ImageButton mDeleteKey;
+ private TextView mAlphabetKeyLeft;
+ private TextView mAlphabetKeyRight;
+ private View mSpacebar;
+ // TODO: Remove this workaround.
+ private View mSpacebarIcon;
+ private TabHost mTabHost;
+ private ViewPager mEmojiPager;
+ private int mCurrentPagerPosition = 0;
+ private EmojiCategoryPageIndicatorView mEmojiCategoryPageIndicatorView;
+
+ private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
+
+ private final EmojiCategory mEmojiCategory;
+
+ public EmojiPalettesView(final Context context, final AttributeSet attrs) {
+ this(context, attrs, R.attr.emojiPalettesViewStyle);
+ }
+
+ public EmojiPalettesView(final Context context, final AttributeSet attrs, final int defStyle) {
+ super(context, attrs, defStyle);
+ final TypedArray keyboardViewAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+ final int keyBackgroundId = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_keyBackground, 0);
+ mFunctionalKeyBackgroundId = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_functionalKeyBackground, keyBackgroundId);
+ mSpacebarBackgroundId = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_spacebarBackground, keyBackgroundId);
+ keyboardViewAttr.recycle();
+ final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
+ context, null /* editorInfo */);
+ final Resources res = context.getResources();
+ mEmojiLayoutParams = new EmojiLayoutParams(res);
+ builder.setSubtype(SubtypeSwitcher.getInstance().getEmojiSubtype());
+ builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
+ mEmojiLayoutParams.mEmojiKeyboardHeight);
+ final KeyboardLayoutSet layoutSet = builder.build();
+ final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.EmojiPalettesView, defStyle, R.style.EmojiPalettesView);
+ mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context),
+ res, layoutSet, emojiPalettesViewAttr);
+ mCategoryIndicatorEnabled = emojiPalettesViewAttr.getBoolean(
+ R.styleable.EmojiPalettesView_categoryIndicatorEnabled, false);
+ mCategoryIndicatorDrawableResId = emojiPalettesViewAttr.getResourceId(
+ R.styleable.EmojiPalettesView_categoryIndicatorDrawable, 0);
+ mCategoryIndicatorBackgroundResId = emojiPalettesViewAttr.getResourceId(
+ R.styleable.EmojiPalettesView_categoryIndicatorBackground, 0);
+ mCategoryPageIndicatorColor = emojiPalettesViewAttr.getColor(
+ R.styleable.EmojiPalettesView_categoryPageIndicatorColor, 0);
+ mCategoryPageIndicatorBackground = emojiPalettesViewAttr.getColor(
+ R.styleable.EmojiPalettesView_categoryPageIndicatorBackground, 0);
+ emojiPalettesViewAttr.recycle();
+ mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(context);
+ }
+
+ @Override
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ final Resources res = getContext().getResources();
+ // The main keyboard expands to the entire this {@link KeyboardView}.
+ final int width = ResourceUtils.getDefaultKeyboardWidth(res)
+ + getPaddingLeft() + getPaddingRight();
+ final int height = ResourceUtils.getDefaultKeyboardHeight(res)
+ + res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
+ + getPaddingTop() + getPaddingBottom();
+ setMeasuredDimension(width, height);
+ }
+
+ private void addTab(final TabHost host, final int categoryId) {
+ final String tabId = mEmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */);
+ final TabHost.TabSpec tspec = host.newTabSpec(tabId);
+ tspec.setContent(R.id.emoji_keyboard_dummy);
+ final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate(
+ R.layout.emoji_keyboard_tab_icon, null);
+ iconView.setImageResource(mEmojiCategory.getCategoryTabIcon(categoryId));
+ iconView.setContentDescription(mEmojiCategory.getAccessibilityDescription(categoryId));
+ tspec.setIndicator(iconView);
+ host.addTab(tspec);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ mTabHost = (TabHost)findViewById(R.id.emoji_category_tabhost);
+ mTabHost.setup();
+ for (final EmojiCategory.CategoryProperties properties
+ : mEmojiCategory.getShownCategories()) {
+ addTab(mTabHost, properties.mCategoryId);
+ }
+ mTabHost.setOnTabChangedListener(this);
+ final TabWidget tabWidget = mTabHost.getTabWidget();
+ tabWidget.setStripEnabled(mCategoryIndicatorEnabled);
+ if (mCategoryIndicatorEnabled) {
+ // On TabWidget's strip, what looks like an indicator is actually a background.
+ // And what looks like a background are actually left and right drawables.
+ tabWidget.setBackgroundResource(mCategoryIndicatorDrawableResId);
+ tabWidget.setLeftStripDrawable(mCategoryIndicatorBackgroundResId);
+ tabWidget.setRightStripDrawable(mCategoryIndicatorBackgroundResId);
+ }
+
+ mEmojiPalettesAdapter = new EmojiPalettesAdapter(mEmojiCategory, this);
+
+ mEmojiPager = (ViewPager)findViewById(R.id.emoji_keyboard_pager);
+ mEmojiPager.setAdapter(mEmojiPalettesAdapter);
+ mEmojiPager.setOnPageChangeListener(this);
+ mEmojiPager.setOffscreenPageLimit(0);
+ mEmojiPager.setPersistentDrawingCache(PERSISTENT_NO_CACHE);
+ mEmojiLayoutParams.setPagerProperties(mEmojiPager);
+
+ mEmojiCategoryPageIndicatorView =
+ (EmojiCategoryPageIndicatorView)findViewById(R.id.emoji_category_page_id_view);
+ mEmojiCategoryPageIndicatorView.setColors(
+ mCategoryPageIndicatorColor, mCategoryPageIndicatorBackground);
+ mEmojiLayoutParams.setCategoryPageIdViewProperties(mEmojiCategoryPageIndicatorView);
+
+ setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */);
+
+ final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar);
+ mEmojiLayoutParams.setActionBarProperties(actionBar);
+
+ // deleteKey depends only on OnTouchListener.
+ mDeleteKey = (ImageButton)findViewById(R.id.emoji_keyboard_delete);
+ mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId);
+ mDeleteKey.setTag(Constants.CODE_DELETE);
+ mDeleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
+
+ // {@link #mAlphabetKeyLeft}, {@link #mAlphabetKeyRight, and spaceKey depend on
+ // {@link View.OnClickListener} as well as {@link View.OnTouchListener}.
+ // {@link View.OnTouchListener} is used as the trigger of key-press, while
+ // {@link View.OnClickListener} is used as the trigger of key-release which does not occur
+ // if the event is canceled by moving off the finger from the view.
+ // The text on alphabet keys are set at
+ // {@link #startEmojiPalettes(String,int,float,Typeface)}.
+ mAlphabetKeyLeft = (TextView)findViewById(R.id.emoji_keyboard_alphabet_left);
+ mAlphabetKeyLeft.setBackgroundResource(mFunctionalKeyBackgroundId);
+ mAlphabetKeyLeft.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
+ mAlphabetKeyLeft.setOnTouchListener(this);
+ mAlphabetKeyLeft.setOnClickListener(this);
+ mAlphabetKeyRight = (TextView)findViewById(R.id.emoji_keyboard_alphabet_right);
+ mAlphabetKeyRight.setBackgroundResource(mFunctionalKeyBackgroundId);
+ mAlphabetKeyRight.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
+ mAlphabetKeyRight.setOnTouchListener(this);
+ mAlphabetKeyRight.setOnClickListener(this);
+ mSpacebar = findViewById(R.id.emoji_keyboard_space);
+ mSpacebar.setBackgroundResource(mSpacebarBackgroundId);
+ mSpacebar.setTag(Constants.CODE_SPACE);
+ mSpacebar.setOnTouchListener(this);
+ mSpacebar.setOnClickListener(this);
+ mEmojiLayoutParams.setKeyProperties(mSpacebar);
+ mSpacebarIcon = findViewById(R.id.emoji_keyboard_space_icon);
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(final MotionEvent ev) {
+ // Add here to the stack trace to nail down the {@link IllegalArgumentException} exception
+ // in MotionEvent that sporadically happens.
+ // TODO: Remove this override method once the issue has been addressed.
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
+ public void onTabChanged(final String tabId) {
+ AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
+ Constants.CODE_UNSPECIFIED, this);
+ final int categoryId = mEmojiCategory.getCategoryId(tabId);
+ setCurrentCategoryId(categoryId, false /* force */);
+ updateEmojiCategoryPageIdView();
+ }
+
+ @Override
+ public void onPageSelected(final int position) {
+ final Pair<Integer, Integer> newPos =
+ mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
+ setCurrentCategoryId(newPos.first /* categoryId */, false /* force */);
+ mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */);
+ updateEmojiCategoryPageIdView();
+ mCurrentPagerPosition = position;
+ }
+
+ @Override
+ public void onPageScrollStateChanged(final int state) {
+ // Ignore this message. Only want the actual page selected.
+ }
+
+ @Override
+ public void onPageScrolled(final int position, final float positionOffset,
+ final int positionOffsetPixels) {
+ mEmojiPalettesAdapter.onPageScrolled();
+ final Pair<Integer, Integer> newPos =
+ mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
+ final int newCategoryId = newPos.first;
+ final int newCategorySize = mEmojiCategory.getCategoryPageSize(newCategoryId);
+ final int currentCategoryId = mEmojiCategory.getCurrentCategoryId();
+ final int currentCategoryPageId = mEmojiCategory.getCurrentCategoryPageId();
+ final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageSize();
+ if (newCategoryId == currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ newCategorySize, newPos.second, positionOffset);
+ } else if (newCategoryId > currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ currentCategorySize, currentCategoryPageId, positionOffset);
+ } else if (newCategoryId < currentCategoryId) {
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ currentCategorySize, currentCategoryPageId, positionOffset - 1);
+ }
+ }
+
+ /**
+ * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnTouchListener}
+ * interface to handle touch events from View-based elements such as the space bar.
+ * Note that this method is used only for observing {@link MotionEvent#ACTION_DOWN} to trigger
+ * {@link KeyboardActionListener#onPressKey}. {@link KeyboardActionListener#onReleaseKey} will
+ * be covered by {@link #onClick} as long as the event is not canceled.
+ */
+ @Override
+ public boolean onTouch(final View v, final MotionEvent event) {
+ if (event.getActionMasked() != MotionEvent.ACTION_DOWN) {
+ return false;
+ }
+ final Object tag = v.getTag();
+ if (!(tag instanceof Integer)) {
+ return false;
+ }
+ final int code = (Integer) tag;
+ mKeyboardActionListener.onPressKey(
+ code, 0 /* repeatCount */, true /* isSinglePointer */);
+ // It's important to return false here. Otherwise, {@link #onClick} and touch-down visual
+ // feedback stop working.
+ return false;
+ }
+
+ /**
+ * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnClickListener}
+ * interface to handle non-canceled touch-up events from View-based elements such as the space
+ * bar.
+ */
+ @Override
+ public void onClick(View v) {
+ final Object tag = v.getTag();
+ if (!(tag instanceof Integer)) {
+ return;
+ }
+ final int code = (Integer) tag;
+ mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE,
+ false /* isKeyRepeat */);
+ mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
+ }
+
+ /**
+ * Called from {@link EmojiPageKeyboardView} through
+ * {@link com.android.inputmethod.keyboard.emoji.EmojiPageKeyboardView.OnKeyEventListener}
+ * interface to handle touch events from non-View-based elements such as Emoji buttons.
+ */
+ @Override
+ public void onPressKey(final Key key) {
+ final int code = key.getCode();
+ mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
+ }
+
+ /**
+ * Called from {@link EmojiPageKeyboardView} through
+ * {@link com.android.inputmethod.keyboard.emoji.EmojiPageKeyboardView.OnKeyEventListener}
+ * interface to handle touch events from non-View-based elements such as Emoji buttons.
+ */
+ @Override
+ public void onReleaseKey(final Key key) {
+ mEmojiPalettesAdapter.addRecentKey(key);
+ mEmojiCategory.saveLastTypedCategoryPage();
+ final int code = key.getCode();
+ if (code == Constants.CODE_OUTPUT_TEXT) {
+ mKeyboardActionListener.onTextInput(key.getOutputText());
+ } else {
+ mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE,
+ false /* isKeyRepeat */);
+ }
+ mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
+ }
+
+ public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) {
+ if (!enabled) return;
+ // TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off?
+ setLayerType(LAYER_TYPE_HARDWARE, null);
+ }
+
+ private static void setupAlphabetKey(final TextView alphabetKey, final String label,
+ final KeyDrawParams params) {
+ alphabetKey.setText(label);
+ alphabetKey.setTextColor(params.mFunctionalTextColor);
+ alphabetKey.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mLabelSize);
+ alphabetKey.setTypeface(params.mTypeface);
+ }
+
+ public void startEmojiPalettes(final String switchToAlphaLabel,
+ final KeyVisualAttributes keyVisualAttr, final KeyboardIconsSet iconSet) {
+ final int deleteIconResId = iconSet.getIconResourceId(KeyboardIconsSet.NAME_DELETE_KEY);
+ if (deleteIconResId != 0) {
+ mDeleteKey.setImageResource(deleteIconResId);
+ }
+ final int spacebarResId = iconSet.getIconResourceId(KeyboardIconsSet.NAME_SPACE_KEY);
+ if (spacebarResId != 0) {
+ // TODO: Remove this workaround to place the spacebar icon.
+ mSpacebarIcon.setBackgroundResource(spacebarResId);
+ }
+ final KeyDrawParams params = new KeyDrawParams();
+ params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);
+ setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params);
+ setupAlphabetKey(mAlphabetKeyRight, switchToAlphaLabel, params);
+ mEmojiPager.setAdapter(mEmojiPalettesAdapter);
+ mEmojiPager.setCurrentItem(mCurrentPagerPosition);
+ }
+
+ public void stopEmojiPalettes() {
+ mEmojiPalettesAdapter.releaseCurrentKey(true /* withKeyRegistering */);
+ mEmojiPalettesAdapter.flushPendingRecentKeys();
+ mEmojiPager.setAdapter(null);
+ }
+
+ public void setKeyboardActionListener(final KeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ mDeleteKeyOnTouchListener.setKeyboardActionListener(mKeyboardActionListener);
+ }
+
+ private void updateEmojiCategoryPageIdView() {
+ if (mEmojiCategoryPageIndicatorView == null) {
+ return;
+ }
+ mEmojiCategoryPageIndicatorView.setCategoryPageId(
+ mEmojiCategory.getCurrentCategoryPageSize(),
+ mEmojiCategory.getCurrentCategoryPageId(), 0.0f /* offset */);
+ }
+
+ private void setCurrentCategoryId(final int categoryId, final boolean force) {
+ final int oldCategoryId = mEmojiCategory.getCurrentCategoryId();
+ if (oldCategoryId == categoryId && !force) {
+ return;
+ }
+
+ if (oldCategoryId == EmojiCategory.ID_RECENTS) {
+ // Needs to save pending updates for recent keys when we get out of the recents
+ // category because we don't want to move the recent emojis around while the user
+ // is in the recents category.
+ mEmojiPalettesAdapter.flushPendingRecentKeys();
+ }
+
+ mEmojiCategory.setCurrentCategoryId(categoryId);
+ final int newTabId = mEmojiCategory.getTabIdFromCategoryId(categoryId);
+ final int newCategoryPageId = mEmojiCategory.getPageIdFromCategoryId(categoryId);
+ if (force || mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(
+ mEmojiPager.getCurrentItem()).first != categoryId) {
+ mEmojiPager.setCurrentItem(newCategoryPageId, false /* smoothScroll */);
+ }
+ if (force || mTabHost.getCurrentTab() != newTabId) {
+ mTabHost.setCurrentTab(newTabId);
+ }
+ }
+
+ private static class DeleteKeyOnTouchListener implements OnTouchListener {
+ static final long MAX_REPEAT_COUNT_TIME = TimeUnit.SECONDS.toMillis(30);
+ final long mKeyRepeatStartTimeout;
+ final long mKeyRepeatInterval;
+
+ public DeleteKeyOnTouchListener(Context context) {
+ final Resources res = context.getResources();
+ mKeyRepeatStartTimeout = res.getInteger(R.integer.config_key_repeat_start_timeout);
+ mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
+ mTimer = new CountDownTimer(MAX_REPEAT_COUNT_TIME, mKeyRepeatInterval) {
+ @Override
+ public void onTick(long millisUntilFinished) {
+ final long elapsed = MAX_REPEAT_COUNT_TIME - millisUntilFinished;
+ if (elapsed < mKeyRepeatStartTimeout) {
+ return;
+ }
+ onKeyRepeat();
+ }
+ @Override
+ public void onFinish() {
+ onKeyRepeat();
+ }
+ };
+ }
+
+ /** Key-repeat state. */
+ private static final int KEY_REPEAT_STATE_INITIALIZED = 0;
+ // The key is touched but auto key-repeat is not started yet.
+ private static final int KEY_REPEAT_STATE_KEY_DOWN = 1;
+ // At least one key-repeat event has already been triggered and the key is not released.
+ private static final int KEY_REPEAT_STATE_KEY_REPEAT = 2;
+
+ private KeyboardActionListener mKeyboardActionListener =
+ KeyboardActionListener.EMPTY_LISTENER;
+
+ // TODO: Do the same things done in PointerTracker
+ private final CountDownTimer mTimer;
+ private int mState = KEY_REPEAT_STATE_INITIALIZED;
+ private int mRepeatCount = 0;
+
+ public void setKeyboardActionListener(final KeyboardActionListener listener) {
+ mKeyboardActionListener = listener;
+ }
+
+ @Override
+ public boolean onTouch(final View v, final MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ onTouchDown(v);
+ return true;
+ case MotionEvent.ACTION_MOVE:
+ final float x = event.getX();
+ final float y = event.getY();
+ if (x < 0.0f || v.getWidth() < x || y < 0.0f || v.getHeight() < y) {
+ // Stop generating key events once the finger moves away from the view area.
+ onTouchCanceled(v);
+ }
+ return true;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ onTouchUp(v);
+ return true;
+ }
+ return false;
+ }
+
+ private void handleKeyDown() {
+ mKeyboardActionListener.onPressKey(
+ Constants.CODE_DELETE, mRepeatCount, true /* isSinglePointer */);
+ }
+
+ private void handleKeyUp() {
+ mKeyboardActionListener.onCodeInput(Constants.CODE_DELETE,
+ NOT_A_COORDINATE, NOT_A_COORDINATE, false /* isKeyRepeat */);
+ mKeyboardActionListener.onReleaseKey(
+ Constants.CODE_DELETE, false /* withSliding */);
+ ++mRepeatCount;
+ }
+
+ private void onTouchDown(final View v) {
+ mTimer.cancel();
+ mRepeatCount = 0;
+ handleKeyDown();
+ v.setPressed(true /* pressed */);
+ mState = KEY_REPEAT_STATE_KEY_DOWN;
+ mTimer.start();
+ }
+
+ private void onTouchUp(final View v) {
+ mTimer.cancel();
+ if (mState == KEY_REPEAT_STATE_KEY_DOWN) {
+ handleKeyUp();
+ }
+ v.setPressed(false /* pressed */);
+ mState = KEY_REPEAT_STATE_INITIALIZED;
+ }
+
+ private void onTouchCanceled(final View v) {
+ mTimer.cancel();
+ v.setBackgroundColor(Color.TRANSPARENT);
+ mState = KEY_REPEAT_STATE_INITIALIZED;
+ }
+
+ // Called by {@link #mTimer} in the UI thread as an auto key-repeat signal.
+ void onKeyRepeat() {
+ switch (mState) {
+ case KEY_REPEAT_STATE_INITIALIZED:
+ // Basically this should not happen.
+ break;
+ case KEY_REPEAT_STATE_KEY_DOWN:
+ // Do not call {@link #handleKeyDown} here because it has already been called
+ // in {@link #onTouchDown}.
+ handleKeyUp();
+ mState = KEY_REPEAT_STATE_KEY_REPEAT;
+ break;
+ case KEY_REPEAT_STATE_KEY_REPEAT:
+ handleKeyDown();
+ handleKeyUp();
+ break;
+ }
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
index fdc2458d4..3b4c43418 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DrawingPreviewPlacerView.java
@@ -24,7 +24,6 @@ import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import java.util.ArrayList;
@@ -32,7 +31,7 @@ import java.util.ArrayList;
public final class DrawingPreviewPlacerView extends RelativeLayout {
private final int[] mKeyboardViewOrigin = CoordinateUtils.newInstance();
- private final ArrayList<AbstractDrawingPreview> mPreviews = CollectionUtils.newArrayList();
+ private final ArrayList<AbstractDrawingPreview> mPreviews = new ArrayList<>();
public DrawingPreviewPlacerView(final Context context, final AttributeSet attrs) {
super(context, attrs);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
index d8b00c707..72628e38a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureTrailsDrawingPreview.java
@@ -29,15 +29,13 @@ import android.util.SparseArray;
import android.view.View;
import com.android.inputmethod.keyboard.PointerTracker;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
/**
* Draw preview graphics of multiple gesture trails during gesture input.
*/
public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
- private final SparseArray<GestureTrailDrawingPoints> mGestureTrails =
- CollectionUtils.newSparseArray();
+ private final SparseArray<GestureTrailDrawingPoints> mGestureTrails = new SparseArray<>();
private final GestureTrailDrawingParams mDrawingParams;
private final Paint mGesturePaint;
private int mOffscreenWidth;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
index 1716fa049..07ac06bab 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
@@ -35,6 +35,7 @@ public final class KeyDrawParams {
public int mTextColor;
public int mTextInactivatedColor;
public int mTextShadowColor;
+ public int mFunctionalTextColor;
public int mHintLetterColor;
public int mHintLabelColor;
public int mShiftedLetterHintInactivatedColor;
@@ -60,6 +61,7 @@ public final class KeyDrawParams {
mTextColor = copyFrom.mTextColor;
mTextInactivatedColor = copyFrom.mTextInactivatedColor;
mTextShadowColor = copyFrom.mTextShadowColor;
+ mFunctionalTextColor = copyFrom.mFunctionalTextColor;
mHintLetterColor = copyFrom.mHintLetterColor;
mHintLabelColor = copyFrom.mHintLabelColor;
mShiftedLetterHintInactivatedColor = copyFrom.mShiftedLetterHintInactivatedColor;
@@ -93,6 +95,7 @@ public final class KeyDrawParams {
mTextColor = selectColor(attr.mTextColor, mTextColor);
mTextInactivatedColor = selectColor(attr.mTextInactivatedColor, mTextInactivatedColor);
mTextShadowColor = selectColor(attr.mTextShadowColor, mTextShadowColor);
+ mFunctionalTextColor = selectColor(attr.mFunctionalTextColor, mFunctionalTextColor);
mHintLetterColor = selectColor(attr.mHintLetterColor, mHintLetterColor);
mHintLabelColor = selectColor(attr.mHintLabelColor, mHintLabelColor);
mShiftedLetterHintInactivatedColor = selectColor(
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
index 625d1f0a4..605519b02 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewChoreographer.java
@@ -32,7 +32,6 @@ import android.widget.TextView;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.ViewLayoutUtils;
@@ -48,9 +47,9 @@ import java.util.HashSet;
*/
public final class KeyPreviewChoreographer {
// Free {@link TextView} pool that can be used for key preview.
- private final ArrayDeque<TextView> mFreeKeyPreviewTextViews = CollectionUtils.newArrayDeque();
+ private final ArrayDeque<TextView> mFreeKeyPreviewTextViews = new ArrayDeque<>();
// Map from {@link Key} to {@link TextView} that is currently being displayed as key preview.
- private final HashMap<Key,TextView> mShowingKeyPreviewTextViews = CollectionUtils.newHashMap();
+ private final HashMap<Key,TextView> mShowingKeyPreviewTextViews = new HashMap<>();
private final KeyPreviewDrawParams mParams;
@@ -83,7 +82,7 @@ public final class KeyPreviewChoreographer {
}
public void dismissAllKeyPreviews() {
- for (final Key key : new HashSet<Key>(mShowingKeyPreviewTextViews.keySet())) {
+ for (final Key key : new HashSet<>(mShowingKeyPreviewTextViews.keySet())) {
dismissKeyPreview(key, false /* withAnimation */);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
index 700c9b07c..0b0e761d2 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
@@ -21,7 +21,6 @@ import android.util.Log;
import android.util.SparseArray;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.XmlParseUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -34,7 +33,7 @@ public final class KeyStylesSet {
private static final String TAG = KeyStylesSet.class.getSimpleName();
private static final boolean DEBUG = false;
- private final HashMap<String, KeyStyle> mStyles = CollectionUtils.newHashMap();
+ private final HashMap<String, KeyStyle> mStyles = new HashMap<>();
private final KeyboardTextsSet mTextsSet;
private final KeyStyle mEmptyKeyStyle;
@@ -75,7 +74,7 @@ public final class KeyStylesSet {
private static final class DeclaredKeyStyle extends KeyStyle {
private final HashMap<String, KeyStyle> mStyles;
private final String mParentStyleName;
- private final SparseArray<Object> mStyleAttributes = CollectionUtils.newSparseArray();
+ private final SparseArray<Object> mStyleAttributes = new SparseArray<>();
public DeclaredKeyStyle(final String parentStyleName, final KeyboardTextsSet textsSet,
final HashMap<String, KeyStyle> styles) {
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
index df386fce4..133462ac7 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyVisualAttributes.java
@@ -40,6 +40,7 @@ public final class KeyVisualAttributes {
public final int mTextColor;
public final int mTextInactivatedColor;
public final int mTextShadowColor;
+ public final int mFunctionalTextColor;
public final int mHintLetterColor;
public final int mHintLabelColor;
public final int mShiftedLetterHintInactivatedColor;
@@ -61,6 +62,7 @@ public final class KeyVisualAttributes {
R.styleable.Keyboard_Key_keyTextColor,
R.styleable.Keyboard_Key_keyTextInactivatedColor,
R.styleable.Keyboard_Key_keyTextShadowColor,
+ R.styleable.Keyboard_Key_functionalTextColor,
R.styleable.Keyboard_Key_keyHintLetterColor,
R.styleable.Keyboard_Key_keyHintLabelColor,
R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor,
@@ -122,6 +124,7 @@ public final class KeyVisualAttributes {
mTextInactivatedColor = keyAttr.getColor(
R.styleable.Keyboard_Key_keyTextInactivatedColor, 0);
mTextShadowColor = keyAttr.getColor(R.styleable.Keyboard_Key_keyTextShadowColor, 0);
+ mFunctionalTextColor = keyAttr.getColor(R.styleable.Keyboard_Key_functionalTextColor, 0);
mHintLetterColor = keyAttr.getColor(R.styleable.Keyboard_Key_keyHintLetterColor, 0);
mHintLabelColor = keyAttr.getColor(R.styleable.Keyboard_Key_keyHintLabelColor, 0);
mShiftedLetterHintInactivatedColor = keyAttr.getColor(
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index dfe0df04c..8bff27574 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -444,6 +444,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
continue;
}
final int labelFlags = row.getDefaultKeyLabelFlags();
+ // TODO: Should be able to assign default keyActionFlags as well.
final int backgroundType = row.getDefaultBackgroundType();
final int x = (int)row.getKeyX(null);
final int y = row.getKeyY();
@@ -652,9 +653,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
final boolean clobberSettingsKeyMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
- final boolean supportsSwitchingToShortcutImeMatched = matchBoolean(caseAttr,
- R.styleable.Keyboard_Case_supportsSwitchingToShortcutIme,
- id.mSupportsSwitchingToShortcutIme);
final boolean hasShortcutKeyMatched = matchBoolean(caseAttr,
R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
final boolean languageSwitchKeyEnabledMatched = matchBoolean(caseAttr,
@@ -664,6 +662,8 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
final boolean imeActionMatched = matchInteger(caseAttr,
R.styleable.Keyboard_Case_imeAction, id.imeAction());
+ final boolean isIconDefinedMatched = isIconDefined(caseAttr,
+ R.styleable.Keyboard_Case_isIconDefined, mParams.mIconsSet);
final boolean localeCodeMatched = matchString(caseAttr,
R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
final boolean languageCodeMatched = matchString(caseAttr,
@@ -672,10 +672,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
final boolean selected = keyboardLayoutSetMatched && keyboardLayoutSetElementMatched
&& modeMatched && navigateNextMatched && navigatePreviousMatched
- && passwordInputMatched && clobberSettingsKeyMatched
- && supportsSwitchingToShortcutImeMatched && hasShortcutKeyMatched
+ && passwordInputMatched && clobberSettingsKeyMatched && hasShortcutKeyMatched
&& languageSwitchKeyEnabledMatched && isMultiLineMatched && imeActionMatched
- && localeCodeMatched && languageCodeMatched && countryCodeMatched;
+ && isIconDefinedMatched && localeCodeMatched && languageCodeMatched
+ && countryCodeMatched;
if (DEBUG) {
startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
@@ -695,15 +695,14 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
"clobberSettingsKey"),
booleanAttr(caseAttr, R.styleable.Keyboard_Case_passwordInput,
"passwordInput"),
- booleanAttr(
- caseAttr, R.styleable.Keyboard_Case_supportsSwitchingToShortcutIme,
- "supportsSwitchingToShortcutIme"),
booleanAttr(caseAttr, R.styleable.Keyboard_Case_hasShortcutKey,
"hasShortcutKey"),
booleanAttr(caseAttr, R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
"languageSwitchKeyEnabled"),
booleanAttr(caseAttr, R.styleable.Keyboard_Case_isMultiLine,
"isMultiLine"),
+ textAttr(caseAttr.getString(R.styleable.Keyboard_Case_isIconDefined),
+ "isIconDefined"),
textAttr(caseAttr.getString(R.styleable.Keyboard_Case_localeCode),
"localeCode"),
textAttr(caseAttr.getString(R.styleable.Keyboard_Case_languageCode),
@@ -755,6 +754,16 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
return false;
}
+ private static boolean isIconDefined(final TypedArray a, final int index,
+ final KeyboardIconsSet iconsSet) {
+ if (!a.hasValue(index)) {
+ return true;
+ }
+ final String iconName = a.getString(index);
+ final int iconId = KeyboardIconsSet.getIconId(iconName);
+ return iconsSet.getIconDrawable(iconId) != null;
+ }
+
private boolean parseDefault(final XmlPullParser parser, final KeyboardRow row,
final boolean skip) throws XmlPullParserException, IOException {
if (DEBUG) startTag("<%s>", TAG_DEFAULT);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
index 06da5719b..62b69dcc9 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardCodesSet.java
@@ -17,14 +17,13 @@
package com.android.inputmethod.keyboard.internal;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.HashMap;
public final class KeyboardCodesSet {
public static final String PREFIX_CODE = "!code/";
- private static final HashMap<String, Integer> sNameToIdMap = CollectionUtils.newHashMap();
+ private static final HashMap<String, Integer> sNameToIdMap = new HashMap<>();
private KeyboardCodesSet() {
// This utility class is not publicly instantiable.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index 6c9b5adc3..7146deb4b 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -23,7 +23,6 @@ import android.util.Log;
import android.util.SparseIntArray;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.HashMap;
@@ -42,7 +41,12 @@ public final class KeyboardIconsSet {
public static final String NAME_SPACE_KEY = "space_key";
public static final String NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout";
public static final String NAME_ENTER_KEY = "enter_key";
+ public static final String NAME_GO_KEY = "go_key";
public static final String NAME_SEARCH_KEY = "search_key";
+ public static final String NAME_SEND_KEY = "send_key";
+ public static final String NAME_NEXT_KEY = "next_key";
+ public static final String NAME_DONE_KEY = "done_key";
+ public static final String NAME_PREVIOUS_KEY = "previous_key";
public static final String NAME_TAB_KEY = "tab_key";
public static final String NANE_TAB_KEY_PREVIEW = "tab_key_preview";
public static final String NAME_SHORTCUT_KEY = "shortcut_key";
@@ -55,7 +59,7 @@ public final class KeyboardIconsSet {
private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray();
// Icon name to icon id map.
- private static final HashMap<String, Integer> sNameToIdsMap = CollectionUtils.newHashMap();
+ private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<>();
private static final Object[] NAMES_AND_ATTR_IDS = {
NAME_UNDEFINED, ATTR_UNDEFINED,
@@ -64,7 +68,12 @@ public final class KeyboardIconsSet {
NAME_SETTINGS_KEY, R.styleable.Keyboard_iconSettingsKey,
NAME_SPACE_KEY, R.styleable.Keyboard_iconSpaceKey,
NAME_ENTER_KEY, R.styleable.Keyboard_iconEnterKey,
+ NAME_GO_KEY, R.styleable.Keyboard_iconGoKey,
NAME_SEARCH_KEY, R.styleable.Keyboard_iconSearchKey,
+ NAME_SEND_KEY, R.styleable.Keyboard_iconSendKey,
+ NAME_NEXT_KEY, R.styleable.Keyboard_iconNextKey,
+ NAME_DONE_KEY, R.styleable.Keyboard_iconDoneKey,
+ NAME_PREVIOUS_KEY, R.styleable.Keyboard_iconPreviousKey,
NAME_TAB_KEY, R.styleable.Keyboard_iconTabKey,
NAME_SHORTCUT_KEY, R.styleable.Keyboard_iconShortcutKey,
NAME_SPACE_KEY_FOR_NUMBER_LAYOUT, R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
@@ -80,6 +89,7 @@ public final class KeyboardIconsSet {
private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
private static final String[] ICON_NAMES = new String[NUM_ICONS];
private final Drawable[] mIcons = new Drawable[NUM_ICONS];
+ private final int[] mIconResourceIds = new int[NUM_ICONS];
static {
int iconId = ICON_UNDEFINED;
@@ -87,7 +97,7 @@ public final class KeyboardIconsSet {
final String name = (String)NAMES_AND_ATTR_IDS[i];
final Integer attrId = (Integer)NAMES_AND_ATTR_IDS[i + 1];
if (attrId != ATTR_UNDEFINED) {
- ATTR_ID_TO_ICON_ID.put(attrId, iconId);
+ ATTR_ID_TO_ICON_ID.put(attrId, iconId);
}
sNameToIdsMap.put(name, iconId);
ICON_NAMES[iconId] = name;
@@ -104,6 +114,7 @@ public final class KeyboardIconsSet {
setDefaultBounds(icon);
final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
mIcons[iconId] = icon;
+ mIconResourceIds[iconId] = keyboardAttrs.getResourceId(attrId, 0);
} catch (Resources.NotFoundException e) {
Log.w(TAG, "Drawable resource for icon #"
+ keyboardAttrs.getResources().getResourceEntryName(attrId)
@@ -128,6 +139,14 @@ public final class KeyboardIconsSet {
throw new RuntimeException("unknown icon name: " + name);
}
+ public int getIconResourceId(final String name) {
+ final int iconId = getIconId(name);
+ if (isValidIconId(iconId)) {
+ return mIconResourceIds[iconId];
+ }
+ throw new RuntimeException("unknown icon name: " + name);
+ }
+
public Drawable getIconDrawable(final int iconId) {
if (isValidIconId(iconId)) {
return mIcons[iconId];
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
index a61a79b85..5df9d3ece 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParams.java
@@ -21,7 +21,6 @@ import android.util.SparseIntArray;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList;
import java.util.Comparator;
@@ -61,9 +60,9 @@ public class KeyboardParams {
public int GRID_HEIGHT;
// Keys are sorted from top-left to bottom-right order.
- public final SortedSet<Key> mSortedKeys = new TreeSet<Key>(ROW_COLUMN_COMPARATOR);
- public final ArrayList<Key> mShiftKeys = CollectionUtils.newArrayList();
- public final ArrayList<Key> mAltCodeKeysWhileTyping = CollectionUtils.newArrayList();
+ public final SortedSet<Key> mSortedKeys = new TreeSet<>(ROW_COLUMN_COMPARATOR);
+ public final ArrayList<Key> mShiftKeys = new ArrayList<>();
+ public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<>();
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
index 0f9497c27..92daf0742 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardRow.java
@@ -23,7 +23,6 @@ import android.util.Xml;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -44,8 +43,9 @@ public final class KeyboardRow {
/** The height of this row. */
private final int mRowHeight;
- private final ArrayDeque<RowAttributes> mRowAttributesStack = CollectionUtils.newArrayDeque();
+ private final ArrayDeque<RowAttributes> mRowAttributesStack = new ArrayDeque<>();
+ // TODO: Add keyActionFlags.
private static class RowAttributes {
/** Default width of a key in this row. */
public final float mDefaultKeyWidth;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index 0047aa4a1..cd6abeed3 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -22,7 +22,6 @@ import android.text.TextUtils;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.RunInLocale;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -38,7 +37,7 @@ public final class KeyboardTextsSet {
private String[] mTextsTable;
// Resource name to text map.
- private HashMap<String, String> mResourceNameToTextsMap = CollectionUtils.newHashMap();
+ private HashMap<String, String> mResourceNameToTextsMap = new HashMap<>();
public void setLocale(final Locale locale, final Context context) {
mTextsTable = KeyboardTextsTable.getTextsTable(locale);
@@ -141,6 +140,7 @@ public final class KeyboardTextsSet {
"label_send_key",
"label_next_key",
"label_done_key",
+ "label_search_key",
"label_previous_key",
// Other labels.
"label_pause_key",
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 14fa76744..ab2555802 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -16,8 +16,6 @@
package com.android.inputmethod.keyboard.internal;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
import java.util.HashMap;
import java.util.Locale;
@@ -44,14 +42,12 @@ import java.util.Locale;
*/
public final class KeyboardTextsTable {
// Name to index map.
- private static final HashMap<String, Integer> sNameToIndexesMap = CollectionUtils.newHashMap();
+ private static final HashMap<String, Integer> sNameToIndexesMap = new HashMap<>();
// Locale to texts table map.
- private static final HashMap<String, String[]> sLocaleToTextsTableMap =
- CollectionUtils.newHashMap();
+ private static final HashMap<String, String[]> sLocaleToTextsTableMap = new HashMap<>();
// TODO: Remove this variable after debugging.
// Texts table to locale maps.
- private static final HashMap<String[], String> sTextsTableToLocaleMap =
- CollectionUtils.newHashMap();
+ private static final HashMap<String[], String> sTextsTableToLocaleMap = new HashMap<>();
public static String getText(final String name, final String[] textsTable) {
final Integer indexObj = sNameToIndexesMap.get(name);
@@ -95,18 +91,18 @@ public final class KeyboardTextsTable {
/* 5:23 */ "morekeys_c",
/* 6:23 */ "double_quotes",
/* 7:22 */ "morekeys_n",
- /* 8:22 */ "single_quotes",
- /* 9:21 */ "keylabel_to_alpha",
+ /* 8:22 */ "keylabel_to_alpha",
+ /* 9:22 */ "single_quotes",
/* 10:20 */ "morekeys_s",
/* 11:14 */ "morekeys_y",
/* 12:13 */ "morekeys_d",
/* 13:12 */ "morekeys_z",
/* 14:10 */ "morekeys_t",
/* 15:10 */ "morekeys_l",
- /* 16: 9 */ "morekeys_g",
- /* 17: 9 */ "single_angle_quotes",
- /* 18: 9 */ "double_angle_quotes",
- /* 19: 9 */ "keyspec_currency",
+ /* 16:10 */ "keyspec_currency",
+ /* 17: 9 */ "morekeys_g",
+ /* 18: 9 */ "single_angle_quotes",
+ /* 19: 9 */ "double_angle_quotes",
/* 20: 8 */ "morekeys_r",
/* 21: 6 */ "morekeys_k",
/* 22: 6 */ "morekeys_cyrillic_ie",
@@ -119,29 +115,29 @@ public final class KeyboardTextsTable {
/* 29: 5 */ "keyspec_east_slavic_row2_11",
/* 30: 5 */ "keyspec_east_slavic_row3_5",
/* 31: 5 */ "morekeys_cyrillic_soft_sign",
- /* 32: 4 */ "morekeys_nordic_row2_11",
- /* 33: 4 */ "morekeys_punctuation",
- /* 34: 4 */ "keyspec_symbols_1",
- /* 35: 4 */ "keyspec_symbols_2",
- /* 36: 4 */ "keyspec_symbols_3",
- /* 37: 4 */ "keyspec_symbols_4",
- /* 38: 4 */ "keyspec_symbols_5",
- /* 39: 4 */ "keyspec_symbols_6",
- /* 40: 4 */ "keyspec_symbols_7",
- /* 41: 4 */ "keyspec_symbols_8",
- /* 42: 4 */ "keyspec_symbols_9",
- /* 43: 4 */ "keyspec_symbols_0",
- /* 44: 4 */ "keylabel_to_symbol",
- /* 45: 4 */ "additional_morekeys_symbols_1",
- /* 46: 4 */ "additional_morekeys_symbols_2",
- /* 47: 4 */ "additional_morekeys_symbols_3",
- /* 48: 4 */ "additional_morekeys_symbols_4",
- /* 49: 4 */ "additional_morekeys_symbols_5",
- /* 50: 4 */ "additional_morekeys_symbols_6",
- /* 51: 4 */ "additional_morekeys_symbols_7",
- /* 52: 4 */ "additional_morekeys_symbols_8",
- /* 53: 4 */ "additional_morekeys_symbols_9",
- /* 54: 4 */ "additional_morekeys_symbols_0",
+ /* 32: 5 */ "keyspec_symbols_1",
+ /* 33: 5 */ "keyspec_symbols_2",
+ /* 34: 5 */ "keyspec_symbols_3",
+ /* 35: 5 */ "keyspec_symbols_4",
+ /* 36: 5 */ "keyspec_symbols_5",
+ /* 37: 5 */ "keyspec_symbols_6",
+ /* 38: 5 */ "keyspec_symbols_7",
+ /* 39: 5 */ "keyspec_symbols_8",
+ /* 40: 5 */ "keyspec_symbols_9",
+ /* 41: 5 */ "keyspec_symbols_0",
+ /* 42: 5 */ "keylabel_to_symbol",
+ /* 43: 5 */ "additional_morekeys_symbols_1",
+ /* 44: 5 */ "additional_morekeys_symbols_2",
+ /* 45: 5 */ "additional_morekeys_symbols_3",
+ /* 46: 5 */ "additional_morekeys_symbols_4",
+ /* 47: 5 */ "additional_morekeys_symbols_5",
+ /* 48: 5 */ "additional_morekeys_symbols_6",
+ /* 49: 5 */ "additional_morekeys_symbols_7",
+ /* 50: 5 */ "additional_morekeys_symbols_8",
+ /* 51: 5 */ "additional_morekeys_symbols_9",
+ /* 52: 5 */ "additional_morekeys_symbols_0",
+ /* 53: 4 */ "morekeys_nordic_row2_11",
+ /* 54: 4 */ "morekeys_punctuation",
/* 55: 4 */ "keyspec_tablet_comma",
/* 56: 3 */ "keyspec_swiss_row1_11",
/* 57: 3 */ "keyspec_swiss_row2_10",
@@ -266,19 +262,19 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_lqm_rqm",
/* morekeys_n */ EMPTY,
- /* single_quotes */ "!text/single_lqm_rqm",
// Label for "switch to alphabetic" key.
/* keylabel_to_alpha */ "ABC",
+ /* single_quotes */ "!text/single_lqm_rqm",
/* morekeys_s ~ */
- EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
- /* ~ morekeys_g */
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+ /* ~ morekeys_l */
+ /* keyspec_currency */ "$",
+ /* morekeys_g */ EMPTY,
/* single_angle_quotes */ "!text/single_laqm_raqm",
/* double_angle_quotes */ "!text/double_laqm_raqm",
- /* keyspec_currency */ "$",
/* morekeys_r ~ */
- EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
- /* ~ morekeys_nordic_row2_11 */
- /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&",
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+ /* ~ morekeys_cyrillic_soft_sign */
/* keyspec_symbols_1 */ "1",
/* keyspec_symbols_2 */ "2",
/* keyspec_symbols_3 */ "3",
@@ -292,8 +288,9 @@ public final class KeyboardTextsTable {
// Label for "switch to symbols" key.
/* keylabel_to_symbol */ "?123",
/* additional_morekeys_symbols_1 ~ */
- EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
- /* ~ additional_morekeys_symbols_0 */
+ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
+ /* ~ morekeys_nordic_row2_11 */
+ /* morekeys_punctuation */ "!autoColumnOrder!8,\\,,?,!,#,!text/keyspec_right_parenthesis,!text/keyspec_left_parenthesis,/,;,',@,:,-,\",+,\\%,&",
/* keyspec_tablet_comma */ ",",
/* keyspec_swiss_row1_11 ~ */
EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
@@ -515,7 +512,7 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes ~ */
+ /* keylabel_to_alpha ~ */
null, null, null,
/* ~ morekeys_s */
// U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
@@ -526,18 +523,18 @@ public final class KeyboardTextsTable {
/* Locale ar: Arabic */
private static final String[] TEXTS_ar = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0623: "أ" ARABIC LETTER ALEF WITH HAMZA ABOVE
// U+200C: ZERO WIDTH NON-JOINER
// U+0628: "ب" ARABIC LETTER BEH
// U+062C: "ج" ARABIC LETTER JEEM
/* keylabel_to_alpha */ "\u0623\u200C\u0628\u200C\u062C",
- /* morekeys_s ~ */
+ /* single_quotes ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null, null,
- /* ~ morekeys_punctuation */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_cyrillic_soft_sign */
// U+0661: "١" ARABIC-INDIC DIGIT ONE
/* keyspec_symbols_1 */ "\u0661",
// U+0662: "٢" ARABIC-INDIC DIGIT TWO
@@ -573,6 +570,8 @@ public final class KeyboardTextsTable {
// U+066B: "٫" ARABIC DECIMAL SEPARATOR
// U+066C: "٬" ARABIC THOUSANDS SEPARATOR
/* additional_morekeys_symbols_0 */ "0,\u066B,\u066C",
+ /* morekeys_nordic_row2_11 */ null,
+ /* morekeys_punctuation */ null,
// U+061F: "؟" ARABIC QUESTION MARK
// U+060C: "،" ARABIC COMMA
// U+061B: "؛" ARABIC SEMICOLON
@@ -603,7 +602,7 @@ public final class KeyboardTextsTable {
/* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
/* keyspec_left_single_angle_quote */ "\u2039|\u203A",
/* keyspec_right_single_angle_quote */ "\u203A|\u2039",
- /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,\",\'",
+ /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,\",\'",
// U+0651: "ّ" ARABIC SHADDA
/* keyhintlabel_period */ "\u0651",
/* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics",
@@ -688,15 +687,15 @@ public final class KeyboardTextsTable {
/* morekeys_c */ "\u00E7,\u0107,\u010D",
/* double_quotes ~ */
null, null, null, null,
- /* ~ keylabel_to_alpha */
+ /* ~ single_quotes */
// U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
/* morekeys_s */ "\u015F,\u00DF,\u015B,\u0161",
/* morekeys_y ~ */
- null, null, null, null, null,
- /* ~ morekeys_l */
+ null, null, null, null, null, null,
+ /* ~ keyspec_currency */
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
/* morekeys_g */ "\u011F",
};
@@ -708,12 +707,12 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
+ /* single_quotes */ "!text/single_9qm_lqm",
/* morekeys_s ~ */
null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_k */
@@ -742,7 +741,6 @@ public final class KeyboardTextsTable {
// single_quotes of Bulgarian is default single_quotes_right_left.
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ null,
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
@@ -802,23 +800,23 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes ~ */
+ /* keylabel_to_alpha ~ */
null, null, null, null, null, null, null,
/* ~ morekeys_t */
// U+00B7: "·" MIDDLE DOT
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
/* morekeys_l */ "l\u00B7l,\u0142",
- /* morekeys_g ~ */
+ /* keyspec_currency ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null,
/* ~ morekeys_nordic_row2_11 */
// U+00B7: "·" MIDDLE DOT
/* morekeys_punctuation */ "!autoColumnOrder!9,\\,,?,!,\u00B7,#,),(,/,;,',@,:,-,\",+,\\%,&",
- /* keyspec_symbols_1 ~ */
+ /* keyspec_tablet_comma ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null,
/* ~ keyspec_south_slavic_row3_8 */
/* morekeys_tablet_punctuation */ "!autoColumnOrder!8,\\,,',\u00B7,#,),(,/,;,@,:,-,\",+,\\%,&",
// U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
@@ -877,8 +875,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u0148,\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -894,11 +892,11 @@ public final class KeyboardTextsTable {
/* morekeys_z */ "\u017E,\u017A,\u017C",
// U+0165: "ť" LATIN SMALL LETTER T WITH CARON
/* morekeys_t */ "\u0165",
- /* morekeys_l */ null,
- /* morekeys_g */ null,
+ /* morekeys_l ~ */
+ null, null, null,
+ /* ~ morekeys_g */
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
- /* keyspec_currency */ null,
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
/* morekeys_r */ "\u0159",
};
@@ -936,8 +934,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
@@ -951,11 +949,12 @@ public final class KeyboardTextsTable {
/* morekeys_t */ null,
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
/* morekeys_l */ "\u0142",
+ /* keyspec_currency */ null,
/* morekeys_g */ null,
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
- /* keyspec_currency ~ */
- null, null, null, null,
+ /* morekeys_r ~ */
+ null, null, null,
/* ~ morekeys_cyrillic_ie */
// U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
/* keyspec_nordic_row1_11 */ "\u00E5",
@@ -966,8 +965,9 @@ public final class KeyboardTextsTable {
// U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
/* morekeys_nordic_row2_10 */ "\u00E4",
/* keyspec_east_slavic_row1_9 ~ */
- null, null, null, null, null,
- /* ~ morekeys_cyrillic_soft_sign */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ additional_morekeys_symbols_0 */
// U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
/* morekeys_nordic_row2_11 */ "\u00F6",
};
@@ -1010,21 +1010,21 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
/* morekeys_s */ "\u00DF,\u015B,\u0161",
/* morekeys_y ~ */
- null, null, null, null, null, null,
+ null, null, null, null, null, null, null,
/* ~ morekeys_g */
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
- /* keyspec_currency ~ */
+ /* morekeys_r ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null,
+ null, null, null, null, null, null,
/* ~ keyspec_tablet_comma */
// U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
/* keyspec_swiss_row1_11 */ "\u00FC",
@@ -1043,8 +1043,8 @@ public final class KeyboardTextsTable {
/* Locale el: Greek */
private static final String[] TEXTS_el = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0391: "Α" GREEK CAPITAL LETTER ALPHA
// U+0392: "Β" GREEK CAPITAL LETTER BETA
@@ -1063,40 +1063,40 @@ public final class KeyboardTextsTable {
// U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
// U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
/* morekeys_a */ "\u00E0,\u00E1,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101",
+ // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
// U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
// U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
// U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
- // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
// U+0153: "œ" LATIN SMALL LIGATURE OE
// U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
// U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
// U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
- /* morekeys_o */ "\u00F4,\u00F6,\u00F2,\u00F3,\u0153,\u00F8,\u014D,\u00F5",
+ /* morekeys_o */ "\u00F3,\u00F4,\u00F6,\u00F2,\u0153,\u00F8,\u014D,\u00F5",
+ // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
// U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
// U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
// U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
- // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
// U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
- /* morekeys_u */ "\u00FB,\u00FC,\u00F9,\u00FA,\u016B",
- // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+ /* morekeys_u */ "\u00FA,\u00FB,\u00FC,\u00F9,\u016B",
// U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+ // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
// U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
// U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
// U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
- /* morekeys_e */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0113",
+ /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0113",
+ // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
// U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
// U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
- // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
// U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
// U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
- /* morekeys_i */ "\u00EE,\u00EF,\u00ED,\u012B,\u00EC",
+ /* morekeys_i */ "\u00ED,\u00EE,\u00EF,\u012B,\u00EC",
// U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
/* morekeys_c */ "\u00E7",
/* double_quotes */ null,
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
/* morekeys_n */ "\u00F1",
- /* single_quotes */ null,
/* keylabel_to_alpha */ null,
+ /* single_quotes */ null,
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
/* morekeys_s */ "\u00DF",
};
@@ -1169,8 +1169,8 @@ public final class KeyboardTextsTable {
// U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
// U+014B: "ŋ" LATIN SMALL LETTER ENG
/* morekeys_n */ "\u00F1,\u0144,\u0146,\u0148,\u0149,\u014B",
- /* single_quotes */ null,
/* keylabel_to_alpha */ null,
+ /* single_quotes */ null,
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -1201,13 +1201,13 @@ public final class KeyboardTextsTable {
// U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
/* morekeys_l */ "\u013A,\u013C,\u013E,\u0140,\u0142",
+ /* keyspec_currency */ null,
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
// U+0121: "ġ" LATIN SMALL LETTER G WITH DOT ABOVE
// U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
/* morekeys_g */ "\u011F,\u0121,\u0123",
- /* single_angle_quotes ~ */
- null, null, null,
- /* ~ keyspec_currency */
+ /* single_angle_quotes */ null,
+ /* double_angle_quotes */ null,
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
// U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
// U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
@@ -1301,9 +1301,11 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes ~ */
+ /* keylabel_to_alpha ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null,
/* ~ morekeys_nordic_row2_11 */
// U+00A1: "¡" INVERTED EXCLAMATION MARK
// U+00BF: "¿" INVERTED QUESTION MARK
@@ -1366,8 +1368,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u0146,\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -1390,12 +1392,12 @@ public final class KeyboardTextsTable {
// U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE
// U+013E: "ľ" LATIN SMALL LETTER L WITH CARON
/* morekeys_l */ "\u013C,\u0142,\u013A,\u013E",
+ /* keyspec_currency */ null,
// U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
/* morekeys_g */ "\u0123,\u011F",
- /* single_angle_quotes ~ */
- null, null, null,
- /* ~ keyspec_currency */
+ /* single_angle_quotes */ null,
+ /* double_angle_quotes */ null,
// U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
// U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
@@ -1470,22 +1472,22 @@ public final class KeyboardTextsTable {
/* Locale fa: Persian */
private static final String[] TEXTS_fa = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0627: "ا" ARABIC LETTER ALEF
// U+200C: ZERO WIDTH NON-JOINER
// U+0628: "ب" ARABIC LETTER BEH
// U+067E: "پ" ARABIC LETTER PEH
/* keylabel_to_alpha */ "\u0627\u200C\u0628\u200C\u067E",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+FDFC: "﷼" RIAL SIGN
/* keyspec_currency */ "\uFDFC",
- /* morekeys_r ~ */
- null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- /* ~ morekeys_punctuation */
+ /* morekeys_g ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ morekeys_cyrillic_soft_sign */
// U+06F1: "۱" EXTENDED ARABIC-INDIC DIGIT ONE
/* keyspec_symbols_1 */ "\u06F1",
// U+06F2: "۲" EXTENDED ARABIC-INDIC DIGIT TWO
@@ -1521,6 +1523,8 @@ public final class KeyboardTextsTable {
// U+066B: "٫" ARABIC DECIMAL SEPARATOR
// U+066C: "٬" ARABIC THOUSANDS SEPARATOR
/* additional_morekeys_symbols_0 */ "0,\u066B,\u066C",
+ /* morekeys_nordic_row2_11 */ null,
+ /* morekeys_punctuation */ null,
// U+060C: "،" ARABIC COMMA
// U+061B: "؛" ARABIC SEMICOLON
// U+061F: "؟" ARABIC QUESTION MARK
@@ -1547,7 +1551,7 @@ public final class KeyboardTextsTable {
/* keyspec_right_double_angle_quote */ "\u00BB|\u00AB",
/* keyspec_left_single_angle_quote */ "\u2039|\u203A",
/* keyspec_right_single_angle_quote */ "\u203A|\u2039",
- /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,/,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
+ /* morekeys_tablet_comma */ "!fixedColumnOrder!4,:,!,\u061F,\u061B,-,!text/keyspec_left_double_angle_quote,!text/keyspec_right_double_angle_quote",
// U+064B: "ً" ARABIC FATHATAN
/* keyhintlabel_period */ "\u064B",
/* morekeys_tablet_period */ "!text/morekeys_arabic_diacritics",
@@ -1629,7 +1633,7 @@ public final class KeyboardTextsTable {
/* morekeys_u */ "\u00FC",
/* morekeys_e ~ */
null, null, null, null, null, null, null,
- /* ~ keylabel_to_alpha */
+ /* ~ single_quotes */
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -1652,8 +1656,9 @@ public final class KeyboardTextsTable {
// U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
/* morekeys_nordic_row2_10 */ "\u00F8",
/* keyspec_east_slavic_row1_9 ~ */
- null, null, null, null, null,
- /* ~ morekeys_cyrillic_soft_sign */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ additional_morekeys_symbols_0 */
// U+00E6: "æ" LATIN SMALL LETTER AE
/* morekeys_nordic_row2_11 */ "\u00E6",
};
@@ -1786,21 +1791,21 @@ public final class KeyboardTextsTable {
/* Locale hi: Hindi */
private static final String[] TEXTS_hi = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0915: "क" DEVANAGARI LETTER KA
// U+0916: "ख" DEVANAGARI LETTER KHA
// U+0917: "ग" DEVANAGARI LETTER GA
/* keylabel_to_alpha */ "\u0915\u0916\u0917",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+20B9: "₹" INDIAN RUPEE SIGN
/* keyspec_currency */ "\u20B9",
- /* morekeys_r ~ */
- null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- /* ~ morekeys_punctuation */
+ /* morekeys_g ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ morekeys_cyrillic_soft_sign */
// U+0967: "१" DEVANAGARI DIGIT ONE
/* keyspec_symbols_1 */ "\u0967",
// U+0968: "२" DEVANAGARI DIGIT TWO
@@ -1848,8 +1853,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_rqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_rqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
@@ -1862,7 +1867,7 @@ public final class KeyboardTextsTable {
// U+017C: "ż" LATIN SMALL LETTER Z WITH DOT ABOVE
/* morekeys_z */ "\u017E,\u017A,\u017C",
/* morekeys_t ~ */
- null, null, null,
+ null, null, null, null,
/* ~ morekeys_g */
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
@@ -1914,8 +1919,9 @@ public final class KeyboardTextsTable {
/* morekeys_c */ null,
/* double_quotes */ "!text/double_9qm_rqm",
/* morekeys_n */ null,
+ /* keylabel_to_alpha */ null,
/* single_quotes */ "!text/single_9qm_rqm",
- /* keylabel_to_alpha ~ */
+ /* morekeys_s ~ */
null, null, null, null, null, null, null, null,
/* ~ morekeys_g */
/* single_angle_quotes */ "!text/single_raqm_laqm",
@@ -1925,16 +1931,17 @@ public final class KeyboardTextsTable {
/* Locale hy_AM: Armenian (Armenia) */
private static final String[] TEXTS_hy_AM = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0531: "Ա" ARMENIAN CAPITAL LETTER AYB
// U+0532: "Բ" ARMENIAN CAPITAL LETTER BEN
// U+0533: "Գ" ARMENIAN CAPITAL LETTER GIM
/* keylabel_to_alpha */ "\u0531\u0532\u0533",
- /* morekeys_s ~ */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null,
/* ~ morekeys_nordic_row2_11 */
// U+055E: "՞" ARMENIAN QUESTION MARK
// U+055C: "՜" ARMENIAN EXCLAMATION MARK
@@ -1947,10 +1954,6 @@ public final class KeyboardTextsTable {
// U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
// U+055F: "՟" ARMENIAN ABBREVIATION MARK
/* morekeys_punctuation */ "!autoColumnOrder!8,\\,,\u055E,\u055C,.,\u055A,\u0559,?,!,\u055D,\u055B,\u058A,\u00BB,\u00AB,\u055F,;,:",
- /* keyspec_symbols_1 ~ */
- null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null,
- /* ~ additional_morekeys_symbols_0 */
// U+058F: "֏" ARMENIAN DRAM SIGN
// TODO: Enable this when we have glyph for the following letter
// <string name="keyspec_currency">&#x058F;</string>
@@ -2026,8 +2029,8 @@ public final class KeyboardTextsTable {
/* morekeys_c */ null,
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
/* morekeys_s */ null,
// U+00FD: "ý" LATIN SMALL LETTER Y WITH ACUTE
// U+00FF: "ÿ" LATIN SMALL LETTER Y WITH DIAERESIS
@@ -2109,21 +2112,21 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_rqm_9qm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_rqm_9qm",
// Label for "switch to alphabetic" key.
// U+05D0: "א" HEBREW LETTER ALEF
// U+05D1: "ב" HEBREW LETTER BET
// U+05D2: "ג" HEBREW LETTER GIMEL
/* keylabel_to_alpha */ "\u05D0\u05D1\u05D2",
+ /* single_quotes */ "!text/single_rqm_9qm",
/* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+20AA: "₪" NEW SHEQEL SIGN
/* keyspec_currency */ "\u20AA",
- /* morekeys_r ~ */
+ /* morekeys_g ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_swiss_row2_11 */
// U+2605: "★" BLACK STAR
/* morekeys_star */ "\u2605",
@@ -2166,26 +2169,26 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
// Label for "switch to alphabetic" key.
// U+10D0: "ა" GEORGIAN LETTER AN
// U+10D1: "ბ" GEORGIAN LETTER BAN
// U+10D2: "გ" GEORGIAN LETTER GAN
/* keylabel_to_alpha */ "\u10D0\u10D1\u10D2",
+ /* single_quotes */ "!text/single_9qm_lqm",
};
/* Locale kk: Kazakh */
private static final String[] TEXTS_kk = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null, null, null, null,
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_k */
// U+0451: "ё" CYRILLIC SMALL LETTER IO
/* morekeys_cyrillic_ie */ "\u0451",
@@ -2202,7 +2205,7 @@ public final class KeyboardTextsTable {
/* keyspec_east_slavic_row3_5 */ "\u0438",
// U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
/* morekeys_cyrillic_soft_sign */ "\u044A",
- /* morekeys_nordic_row2_11 ~ */
+ /* keyspec_symbols_1 ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -2234,14 +2237,14 @@ public final class KeyboardTextsTable {
/* Locale km_KH: Khmer (Cambodia) */
private static final String[] TEXTS_km_KH = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+1780: "ក" KHMER LETTER KA
// U+1781: "ខ" KHMER LETTER KHA
// U+1782: "គ" KHMER LETTER KO
/* keylabel_to_alpha */ "\u1780\u1781\u1782",
- /* morekeys_s ~ */
+ /* single_quotes ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -2249,7 +2252,7 @@ public final class KeyboardTextsTable {
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null,
+ null, null, null, null, null, null, null,
/* ~ morekeys_cyrillic_a */
// U+17DB: "៛" KHMER CURRENCY SYMBOL RIEL
/* morekeys_currency_dollar */ "\u17DB,\u00A2,\u00A3,\u20AC,\u00A5,\u20B1",
@@ -2258,15 +2261,15 @@ public final class KeyboardTextsTable {
/* Locale ky: Kirghiz */
private static final String[] TEXTS_ky = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null, null, null, null,
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_k */
// U+0451: "ё" CYRILLIC SMALL LETTER IO
/* morekeys_cyrillic_ie */ "\u0451",
@@ -2283,7 +2286,7 @@ public final class KeyboardTextsTable {
/* keyspec_east_slavic_row3_5 */ "\u0438",
// U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
/* morekeys_cyrillic_soft_sign */ "\u044A",
- /* morekeys_nordic_row2_11 ~ */
+ /* keyspec_symbols_1 ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -2301,16 +2304,16 @@ public final class KeyboardTextsTable {
/* Locale lo_LA: Lao (Laos) */
private static final String[] TEXTS_lo_LA = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0E81: "ກ" LAO LETTER KO
// U+0E82: "ຂ" LAO LETTER KHO SUNG
// U+0E84: "ຄ" LAO LETTER KHO TAM
/* keylabel_to_alpha */ "\u0E81\u0E82\u0E84",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+20AD: "₭" KIP SIGN
/* keyspec_currency */ "\u20AD",
};
@@ -2372,8 +2375,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u0146,\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -2396,12 +2399,12 @@ public final class KeyboardTextsTable {
// U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE
// U+013E: "ľ" LATIN SMALL LETTER L WITH CARON
/* morekeys_l */ "\u013C,\u0142,\u013A,\u013E",
+ /* keyspec_currency */ null,
// U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
/* morekeys_g */ "\u0123,\u011F",
- /* single_angle_quotes ~ */
- null, null, null,
- /* ~ keyspec_currency */
+ /* single_angle_quotes */ null,
+ /* double_angle_quotes */ null,
// U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
// U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
@@ -2466,8 +2469,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u0146,\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -2490,12 +2493,12 @@ public final class KeyboardTextsTable {
// U+013A: "ĺ" LATIN SMALL LETTER L WITH ACUTE
// U+013E: "ľ" LATIN SMALL LETTER L WITH CARON
/* morekeys_l */ "\u013C,\u0142,\u013A,\u013E",
+ /* keyspec_currency */ null,
// U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
/* morekeys_g */ "\u0123,\u011F",
- /* single_angle_quotes ~ */
- null, null, null,
- /* ~ keyspec_currency */
+ /* single_angle_quotes */ null,
+ /* double_angle_quotes */ null,
// U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
// U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
@@ -2511,12 +2514,12 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
+ /* single_quotes */ "!text/single_9qm_lqm",
/* morekeys_s ~ */
null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_k */
@@ -2544,39 +2547,88 @@ public final class KeyboardTextsTable {
/* Locale mn_MN: Mongolian (Mongolia) */
private static final String[] TEXTS_mn_MN = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+20AE: "₮" TUGRIK SIGN
/* keyspec_currency */ "\u20AE",
};
+ /* Locale mr_IN: Marathi (India) */
+ private static final String[] TEXTS_mr_IN = {
+ /* morekeys_a ~ */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
+ // Label for "switch to alphabetic" key.
+ // U+0915: "क" DEVANAGARI LETTER KA
+ // U+0916: "ख" DEVANAGARI LETTER KHA
+ // U+0917: "ग" DEVANAGARI LETTER GA
+ /* keylabel_to_alpha */ "\u0915\u0916\u0917",
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
+ // U+20B9: "₹" INDIAN RUPEE SIGN
+ /* keyspec_currency */ "\u20B9",
+ /* morekeys_g ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ morekeys_cyrillic_soft_sign */
+ // U+0967: "१" DEVANAGARI DIGIT ONE
+ /* keyspec_symbols_1 */ "\u0967",
+ // U+0968: "२" DEVANAGARI DIGIT TWO
+ /* keyspec_symbols_2 */ "\u0968",
+ // U+0969: "३" DEVANAGARI DIGIT THREE
+ /* keyspec_symbols_3 */ "\u0969",
+ // U+096A: "४" DEVANAGARI DIGIT FOUR
+ /* keyspec_symbols_4 */ "\u096A",
+ // U+096B: "५" DEVANAGARI DIGIT FIVE
+ /* keyspec_symbols_5 */ "\u096B",
+ // U+096C: "६" DEVANAGARI DIGIT SIX
+ /* keyspec_symbols_6 */ "\u096C",
+ // U+096D: "७" DEVANAGARI DIGIT SEVEN
+ /* keyspec_symbols_7 */ "\u096D",
+ // U+096E: "८" DEVANAGARI DIGIT EIGHT
+ /* keyspec_symbols_8 */ "\u096E",
+ // U+096F: "९" DEVANAGARI DIGIT NINE
+ /* keyspec_symbols_9 */ "\u096F",
+ // U+0966: "०" DEVANAGARI DIGIT ZERO
+ /* keyspec_symbols_0 */ "\u0966",
+ // Label for "switch to symbols" key.
+ /* keylabel_to_symbol */ "?\u0967\u0968\u0969",
+ /* additional_morekeys_symbols_1 */ "1",
+ /* additional_morekeys_symbols_2 */ "2",
+ /* additional_morekeys_symbols_3 */ "3",
+ /* additional_morekeys_symbols_4 */ "4",
+ /* additional_morekeys_symbols_5 */ "5",
+ /* additional_morekeys_symbols_6 */ "6",
+ /* additional_morekeys_symbols_7 */ "7",
+ /* additional_morekeys_symbols_8 */ "8",
+ /* additional_morekeys_symbols_9 */ "9",
+ /* additional_morekeys_symbols_0 */ "0",
+ };
+
/* Locale my_MM: Burmese (Myanmar) */
private static final String[] TEXTS_my_MM = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+1000: "က" MYANMAR LETTER KA
// U+1001: "ခ" MYANMAR LETTER KHA
// U+1002: "ဂ" MYANMAR LETTER GA
/* keylabel_to_alpha */ "\u1000\u1001\u1002",
- /* morekeys_s ~ */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null, null, null,
/* ~ morekeys_nordic_row2_11 */
/* morekeys_punctuation */ "!autoColumnOrder!9,\u104A,.,?,!,#,),(,/,;,...,',@,:,-,\",+,\\%,&",
- /* keyspec_symbols_1 ~ */
- null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null, null,
- /* ~ additional_morekeys_symbols_0 */
// U+104A: "၊" MYANMAR SIGN LITTLE SECTION
// U+104B: "။" MYANMAR SIGN SECTION
/* keyspec_tablet_comma */ "\u104A",
@@ -2633,9 +2685,10 @@ public final class KeyboardTextsTable {
/* morekeys_c */ null,
/* double_quotes */ "!text/double_9qm_rqm",
/* morekeys_n */ null,
+ /* keylabel_to_alpha */ null,
/* single_quotes */ "!text/single_9qm_rqm",
- /* keylabel_to_alpha ~ */
- null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* morekeys_s ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_cyrillic_ie */
// U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
/* keyspec_nordic_row1_11 */ "\u00E5",
@@ -2646,8 +2699,9 @@ public final class KeyboardTextsTable {
// U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
/* morekeys_nordic_row2_10 */ "\u00F6",
/* keyspec_east_slavic_row1_9 ~ */
- null, null, null, null, null,
- /* ~ morekeys_cyrillic_soft_sign */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ additional_morekeys_symbols_0 */
// U+00E4: "ä" LATIN SMALL LETTER A WITH DIAERESIS
/* morekeys_nordic_row2_11 */ "\u00E4",
};
@@ -2655,21 +2709,21 @@ public final class KeyboardTextsTable {
/* Locale ne_NP: Nepali (Nepal) */
private static final String[] TEXTS_ne_NP = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0915: "क" DEVANAGARI LETTER KA
// U+0916: "ख" DEVANAGARI LETTER KHA
// U+0917: "ग" DEVANAGARI LETTER GA
/* keylabel_to_alpha */ "\u0915\u0916\u0917",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN
/* keyspec_currency */ "\u0930\u0941.",
- /* morekeys_r ~ */
- null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- /* ~ morekeys_punctuation */
+ /* morekeys_g ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ morekeys_cyrillic_soft_sign */
// U+0967: "१" DEVANAGARI DIGIT ONE
/* keyspec_symbols_1 */ "\u0967",
// U+0968: "२" DEVANAGARI DIGIT TWO
@@ -2751,8 +2805,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_rqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_rqm",
/* morekeys_s */ null,
// U+0133: "ij" LATIN SMALL LIGATURE IJ
/* morekeys_y */ "\u0133",
@@ -2797,8 +2851,8 @@ public final class KeyboardTextsTable {
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
/* morekeys_n */ "\u0144,\u00F1",
- /* single_quotes */ "!text/single_9qm_rqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_rqm",
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
@@ -2900,8 +2954,8 @@ public final class KeyboardTextsTable {
/* morekeys_c */ null,
/* double_quotes */ "!text/double_9qm_rqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_rqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_rqm",
// U+0219: "ș" LATIN SMALL LETTER S WITH COMMA BELOW
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -2921,12 +2975,12 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
+ /* single_quotes */ "!text/single_9qm_lqm",
/* morekeys_s ~ */
null, null, null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_k */
@@ -3004,8 +3058,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0144: "ń" LATIN SMALL LETTER N WITH ACUTE
/* morekeys_n */ "\u0148,\u0146,\u00F1,\u0144",
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
@@ -3028,12 +3082,12 @@ public final class KeyboardTextsTable {
// U+013C: "ļ" LATIN SMALL LETTER L WITH CEDILLA
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
/* morekeys_l */ "\u013E,\u013A,\u013C,\u0142",
+ /* keyspec_currency */ null,
// U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
/* morekeys_g */ "\u0123,\u011F",
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
- /* keyspec_currency */ null,
// U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
// U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
@@ -3052,8 +3106,8 @@ public final class KeyboardTextsTable {
/* morekeys_c */ "\u010D,\u0107",
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
/* keylabel_to_alpha */ null,
+ /* single_quotes */ "!text/single_9qm_lqm",
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
/* morekeys_s */ "\u0161",
/* morekeys_y */ null,
@@ -3062,7 +3116,7 @@ public final class KeyboardTextsTable {
// U+017E: "ž" LATIN SMALL LETTER Z WITH CARON
/* morekeys_z */ "\u017E",
/* morekeys_t ~ */
- null, null, null,
+ null, null, null, null,
/* ~ morekeys_g */
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
@@ -3075,21 +3129,20 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
// END: More keys definitions for Serbian (Cyrillic)
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
+ /* single_quotes */ "!text/single_9qm_lqm",
/* morekeys_s ~ */
- null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null,
/* ~ morekeys_g */
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
- /* keyspec_currency ~ */
- null, null, null,
- /* ~ morekeys_k */
+ /* morekeys_r */ null,
+ /* morekeys_k */ null,
// U+0450: "ѐ" CYRILLIC SMALL LETTER IE WITH GRAVE
/* morekeys_cyrillic_ie */ "\u0450",
/* keyspec_nordic_row1_11 ~ */
@@ -3169,8 +3222,8 @@ public final class KeyboardTextsTable {
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
// U+0148: "ň" LATIN SMALL LETTER N WITH CARON
/* morekeys_n */ "\u0144,\u00F1,\u0148",
- /* single_quotes */ null,
/* keylabel_to_alpha */ null,
+ /* single_quotes */ null,
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
// U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
@@ -3191,10 +3244,10 @@ public final class KeyboardTextsTable {
/* morekeys_t */ "\u0165,\u00FE",
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
/* morekeys_l */ "\u0142",
+ /* keyspec_currency */ null,
/* morekeys_g */ null,
/* single_angle_quotes */ "!text/single_raqm_laqm",
/* double_angle_quotes */ "!text/double_raqm_laqm",
- /* keyspec_currency */ null,
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
/* morekeys_r */ "\u0159",
/* morekeys_k */ null,
@@ -3209,8 +3262,9 @@ public final class KeyboardTextsTable {
// U+0153: "œ" LATIN SMALL LIGATURE OE
/* morekeys_nordic_row2_10 */ "\u00F8,\u0153",
/* keyspec_east_slavic_row1_9 ~ */
- null, null, null, null, null,
- /* ~ morekeys_cyrillic_soft_sign */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null,
+ /* ~ additional_morekeys_symbols_0 */
// U+00E6: "æ" LATIN SMALL LETTER AE
/* morekeys_nordic_row2_11 */ "\u00E6",
};
@@ -3259,29 +3313,29 @@ public final class KeyboardTextsTable {
/* double_quotes */ null,
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
/* morekeys_n */ "\u00F1",
- /* single_quotes */ null,
/* keylabel_to_alpha */ null,
+ /* single_quotes */ null,
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
/* morekeys_s */ "\u00DF",
/* morekeys_y ~ */
- null, null, null, null, null,
- /* ~ morekeys_l */
+ null, null, null, null, null, null,
+ /* ~ keyspec_currency */
/* morekeys_g */ "g\'",
};
/* Locale th: Thai */
private static final String[] TEXTS_th = {
/* morekeys_a ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ single_quotes */
+ null, null, null, null, null, null, null, null,
+ /* ~ morekeys_n */
// Label for "switch to alphabetic" key.
// U+0E01: "ก" THAI CHARACTER KO KAI
// U+0E02: "ข" THAI CHARACTER KHO KHAI
// U+0E04: "ค" THAI CHARACTER KHO KHWAI
/* keylabel_to_alpha */ "\u0E01\u0E02\u0E04",
- /* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ /* single_quotes ~ */
+ null, null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+0E3F: "฿" THAI CURRENCY SYMBOL BAHT
/* keyspec_currency */ "\u0E3F",
};
@@ -3374,15 +3428,15 @@ public final class KeyboardTextsTable {
/* morekeys_c */ "\u00E7,\u0107,\u010D",
/* double_quotes ~ */
null, null, null, null,
- /* ~ keylabel_to_alpha */
+ /* ~ single_quotes */
// U+015F: "ş" LATIN SMALL LETTER S WITH CEDILLA
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+0161: "š" LATIN SMALL LETTER S WITH CARON
/* morekeys_s */ "\u015F,\u00DF,\u015B,\u0161",
/* morekeys_y ~ */
- null, null, null, null, null,
- /* ~ morekeys_l */
+ null, null, null, null, null, null,
+ /* ~ keyspec_currency */
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
/* morekeys_g */ "\u011F",
};
@@ -3394,19 +3448,19 @@ public final class KeyboardTextsTable {
/* ~ morekeys_c */
/* double_quotes */ "!text/double_9qm_lqm",
/* morekeys_n */ null,
- /* single_quotes */ "!text/single_9qm_lqm",
// Label for "switch to alphabetic" key.
// U+0410: "А" CYRILLIC CAPITAL LETTER A
// U+0411: "Б" CYRILLIC CAPITAL LETTER BE
// U+0412: "В" CYRILLIC CAPITAL LETTER VE
/* keylabel_to_alpha */ "\u0410\u0411\u0412",
+ /* single_quotes */ "!text/single_9qm_lqm",
/* morekeys_s ~ */
- null, null, null, null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ null, null, null, null, null, null,
+ /* ~ morekeys_l */
// U+20B4: "₴" HRYVNIA SIGN
/* keyspec_currency */ "\u20B4",
- /* morekeys_r ~ */
- null, null, null, null, null, null, null,
+ /* morekeys_g ~ */
+ null, null, null, null, null, null, null, null, null, null,
/* ~ morekeys_nordic_row2_10 */
// U+0449: "щ" CYRILLIC SMALL LETTER SHCHA
/* keyspec_east_slavic_row1_9 */ "\u0449",
@@ -3418,7 +3472,7 @@ public final class KeyboardTextsTable {
/* keyspec_east_slavic_row3_5 */ "\u0438",
// U+044A: "ъ" CYRILLIC SMALL LETTER HARD SIGN
/* morekeys_cyrillic_soft_sign */ "\u044A",
- /* morekeys_nordic_row2_11 ~ */
+ /* keyspec_symbols_1 ~ */
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
@@ -3512,8 +3566,8 @@ public final class KeyboardTextsTable {
// U+0111: "đ" LATIN SMALL LETTER D WITH STROKE
/* morekeys_d */ "\u0111",
/* morekeys_z ~ */
- null, null, null, null, null, null,
- /* ~ double_angle_quotes */
+ null, null, null,
+ /* ~ morekeys_l */
// U+20AB: "₫" DONG SIGN
/* keyspec_currency */ "\u20AB",
};
@@ -3530,40 +3584,40 @@ public final class KeyboardTextsTable {
// U+00E5: "å" LATIN SMALL LETTER A WITH RING ABOVE
// U+0101: "ā" LATIN SMALL LETTER A WITH MACRON
/* morekeys_a */ "\u00E0,\u00E1,\u00E2,\u00E4,\u00E6,\u00E3,\u00E5,\u0101",
+ // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
// U+00F4: "ô" LATIN SMALL LETTER O WITH CIRCUMFLEX
// U+00F6: "ö" LATIN SMALL LETTER O WITH DIAERESIS
// U+00F2: "ò" LATIN SMALL LETTER O WITH GRAVE
- // U+00F3: "ó" LATIN SMALL LETTER O WITH ACUTE
// U+0153: "œ" LATIN SMALL LIGATURE OE
// U+00F8: "ø" LATIN SMALL LETTER O WITH STROKE
// U+014D: "ō" LATIN SMALL LETTER O WITH MACRON
// U+00F5: "õ" LATIN SMALL LETTER O WITH TILDE
- /* morekeys_o */ "\u00F4,\u00F6,\u00F2,\u00F3,\u0153,\u00F8,\u014D,\u00F5",
+ /* morekeys_o */ "\u00F3,\u00F4,\u00F6,\u00F2,\u0153,\u00F8,\u014D,\u00F5",
+ // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
// U+00FB: "û" LATIN SMALL LETTER U WITH CIRCUMFLEX
// U+00FC: "ü" LATIN SMALL LETTER U WITH DIAERESIS
// U+00F9: "ù" LATIN SMALL LETTER U WITH GRAVE
- // U+00FA: "ú" LATIN SMALL LETTER U WITH ACUTE
// U+016B: "ū" LATIN SMALL LETTER U WITH MACRON
- /* morekeys_u */ "\u00FB,\u00FC,\u00F9,\u00FA,\u016B",
- // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
+ /* morekeys_u */ "\u00FA,\u00FB,\u00FC,\u00F9,\u016B",
// U+00E9: "é" LATIN SMALL LETTER E WITH ACUTE
+ // U+00E8: "è" LATIN SMALL LETTER E WITH GRAVE
// U+00EA: "ê" LATIN SMALL LETTER E WITH CIRCUMFLEX
// U+00EB: "ë" LATIN SMALL LETTER E WITH DIAERESIS
// U+0113: "ē" LATIN SMALL LETTER E WITH MACRON
- /* morekeys_e */ "\u00E8,\u00E9,\u00EA,\u00EB,\u0113",
+ /* morekeys_e */ "\u00E9,\u00E8,\u00EA,\u00EB,\u0113",
+ // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
// U+00EE: "î" LATIN SMALL LETTER I WITH CIRCUMFLEX
// U+00EF: "ï" LATIN SMALL LETTER I WITH DIAERESIS
- // U+00ED: "í" LATIN SMALL LETTER I WITH ACUTE
// U+012B: "ī" LATIN SMALL LETTER I WITH MACRON
// U+00EC: "ì" LATIN SMALL LETTER I WITH GRAVE
- /* morekeys_i */ "\u00EE,\u00EF,\u00ED,\u012B,\u00EC",
+ /* morekeys_i */ "\u00ED,\u00EE,\u00EF,\u012B,\u00EC",
// U+00E7: "ç" LATIN SMALL LETTER C WITH CEDILLA
/* morekeys_c */ "\u00E7",
/* double_quotes */ null,
// U+00F1: "ñ" LATIN SMALL LETTER N WITH TILDE
/* morekeys_n */ "\u00F1",
- /* single_quotes */ null,
/* keylabel_to_alpha */ null,
+ /* single_quotes */ null,
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
/* morekeys_s */ "\u00DF",
};
@@ -3640,8 +3694,8 @@ public final class KeyboardTextsTable {
// U+0149: "ʼn" LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
// U+014B: "ŋ" LATIN SMALL LETTER ENG
/* morekeys_n */ "\u00F1,\u0144,\u0146,\u0148,\u0149,\u014B",
- /* single_quotes */ null,
/* keylabel_to_alpha */ null,
+ /* single_quotes */ null,
// U+00DF: "ß" LATIN SMALL LETTER SHARP S
// U+015B: "ś" LATIN SMALL LETTER S WITH ACUTE
// U+015D: "ŝ" LATIN SMALL LETTER S WITH CIRCUMFLEX
@@ -3673,14 +3727,14 @@ public final class KeyboardTextsTable {
// U+0140: "ŀ" LATIN SMALL LETTER L WITH MIDDLE DOT
// U+0142: "ł" LATIN SMALL LETTER L WITH STROKE
/* morekeys_l */ "\u013A,\u013C,\u013E,\u0140,\u0142",
+ /* keyspec_currency */ null,
// U+011D: "ĝ" LATIN SMALL LETTER G WITH CIRCUMFLEX
// U+011F: "ğ" LATIN SMALL LETTER G WITH BREVE
// U+0121: "ġ" LATIN SMALL LETTER G WITH DOT ABOVE
// U+0123: "ģ" LATIN SMALL LETTER G WITH CEDILLA
/* morekeys_g */ "\u011D,\u011F,\u0121,\u0123",
- /* single_angle_quotes ~ */
- null, null, null,
- /* ~ keyspec_currency */
+ /* single_angle_quotes */ null,
+ /* double_angle_quotes */ null,
// U+0155: "ŕ" LATIN SMALL LETTER R WITH ACUTE
// U+0157: "ŗ" LATIN SMALL LETTER R WITH CEDILLA
// U+0159: "ř" LATIN SMALL LETTER R WITH CARON
@@ -3711,26 +3765,26 @@ public final class KeyboardTextsTable {
"DEFAULT", TEXTS_DEFAULT, /* 168/168 DEFAULT */
"af" , TEXTS_af, /* 7/ 12 Afrikaans */
"ar" , TEXTS_ar, /* 55/110 Arabic */
- "az_AZ" , TEXTS_az_AZ, /* 8/ 17 Azerbaijani (Azerbaijan) */
+ "az_AZ" , TEXTS_az_AZ, /* 8/ 18 Azerbaijani (Azerbaijan) */
"be_BY" , TEXTS_be_BY, /* 9/ 32 Belarusian (Belarus) */
- "bg" , TEXTS_bg, /* 2/ 10 Bulgarian */
+ "bg" , TEXTS_bg, /* 2/ 9 Bulgarian */
"ca" , TEXTS_ca, /* 11/ 95 Catalan */
"cs" , TEXTS_cs, /* 17/ 21 Czech */
- "da" , TEXTS_da, /* 19/ 33 Danish */
+ "da" , TEXTS_da, /* 19/ 54 Danish */
"de" , TEXTS_de, /* 16/ 62 German */
- "el" , TEXTS_el, /* 1/ 10 Greek */
+ "el" , TEXTS_el, /* 1/ 9 Greek */
"en" , TEXTS_en, /* 8/ 11 English */
"eo" , TEXTS_eo, /* 26/118 Esperanto */
- "es" , TEXTS_es, /* 8/ 34 Spanish */
+ "es" , TEXTS_es, /* 8/ 55 Spanish */
"et_EE" , TEXTS_et_EE, /* 22/ 27 Estonian (Estonia) */
"eu_ES" , TEXTS_eu_ES, /* 7/ 8 Basque (Spain) */
"fa" , TEXTS_fa, /* 58/125 Persian */
- "fi" , TEXTS_fi, /* 10/ 33 Finnish */
+ "fi" , TEXTS_fi, /* 10/ 54 Finnish */
"fr" , TEXTS_fr, /* 13/ 62 French */
"gl_ES" , TEXTS_gl_ES, /* 7/ 8 Gallegan (Spain) */
- "hi" , TEXTS_hi, /* 23/ 55 Hindi */
- "hr" , TEXTS_hr, /* 9/ 19 Croatian */
- "hu" , TEXTS_hu, /* 9/ 19 Hungarian */
+ "hi" , TEXTS_hi, /* 23/ 53 Hindi */
+ "hr" , TEXTS_hr, /* 9/ 20 Croatian */
+ "hu" , TEXTS_hu, /* 9/ 20 Hungarian */
"hy_AM" , TEXTS_hy_AM, /* 8/126 Armenian (Armenia) */
"is" , TEXTS_is, /* 10/ 15 Icelandic */
"it" , TEXTS_it, /* 11/ 62 Italian */
@@ -3739,14 +3793,15 @@ public final class KeyboardTextsTable {
"kk" , TEXTS_kk, /* 15/121 Kazakh */
"km_KH" , TEXTS_km_KH, /* 2/122 Khmer (Cambodia) */
"ky" , TEXTS_ky, /* 10/ 88 Kirghiz */
- "lo_LA" , TEXTS_lo_LA, /* 2/ 20 Lao (Laos) */
+ "lo_LA" , TEXTS_lo_LA, /* 2/ 17 Lao (Laos) */
"lt" , TEXTS_lt, /* 18/ 22 Lithuanian */
"lv" , TEXTS_lv, /* 18/ 22 Latvian */
"mk" , TEXTS_mk, /* 9/ 93 Macedonian */
- "mn_MN" , TEXTS_mn_MN, /* 2/ 20 Mongolian (Mongolia) */
+ "mn_MN" , TEXTS_mn_MN, /* 2/ 17 Mongolian (Mongolia) */
+ "mr_IN" , TEXTS_mr_IN, /* 23/ 53 Marathi (India) */
"my_MM" , TEXTS_my_MM, /* 8/104 Burmese (Myanmar) */
- "nb" , TEXTS_nb, /* 11/ 33 Norwegian Bokmål */
- "ne_NP" , TEXTS_ne_NP, /* 23/ 55 Nepali (Nepal) */
+ "nb" , TEXTS_nb, /* 11/ 54 Norwegian Bokmål */
+ "ne_NP" , TEXTS_ne_NP, /* 23/ 53 Nepali (Nepal) */
"nl" , TEXTS_nl, /* 9/ 12 Dutch */
"pl" , TEXTS_pl, /* 10/ 16 Polish */
"pt" , TEXTS_pt, /* 6/ 6 Portuguese */
@@ -3754,15 +3809,15 @@ public final class KeyboardTextsTable {
"ro" , TEXTS_ro, /* 6/ 15 Romanian */
"ru" , TEXTS_ru, /* 9/ 32 Russian */
"sk" , TEXTS_sk, /* 20/ 22 Slovak */
- "sl" , TEXTS_sl, /* 8/ 19 Slovenian */
+ "sl" , TEXTS_sl, /* 8/ 20 Slovenian */
"sr" , TEXTS_sr, /* 11/ 93 Serbian */
- "sv" , TEXTS_sv, /* 21/ 33 Swedish */
- "sw" , TEXTS_sw, /* 9/ 17 Swahili */
- "th" , TEXTS_th, /* 2/ 20 Thai */
+ "sv" , TEXTS_sv, /* 21/ 54 Swedish */
+ "sw" , TEXTS_sw, /* 9/ 18 Swahili */
+ "th" , TEXTS_th, /* 2/ 17 Thai */
"tl" , TEXTS_tl, /* 7/ 8 Tagalog */
- "tr" , TEXTS_tr, /* 7/ 17 Turkish */
+ "tr" , TEXTS_tr, /* 7/ 18 Turkish */
"uk" , TEXTS_uk, /* 11/ 87 Ukrainian */
- "vi" , TEXTS_vi, /* 8/ 20 Vietnamese */
+ "vi" , TEXTS_vi, /* 8/ 17 Vietnamese */
"zu" , TEXTS_zu, /* 8/ 11 Zulu */
"zz" , TEXTS_zz, /* 19/112 Alphabet */
};
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
index 7c2e3e174..7743d4744 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeysCache.java
@@ -17,12 +17,11 @@
package com.android.inputmethod.keyboard.internal;
import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.HashMap;
public final class KeysCache {
- private final HashMap<Key, Key> mMap = CollectionUtils.newHashMap();
+ private final HashMap<Key, Key> mMap = new HashMap<>();
public void clear() {
mMap.clear();
diff --git a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
index 56ef4767f..e0d5173ac 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/MoreKeySpec.java
@@ -149,7 +149,7 @@ public final class MoreKeySpec {
// Skip empty entry.
if (pos - start > 0) {
if (list == null) {
- list = CollectionUtils.newArrayList();
+ list = new ArrayList<>();
}
list.add(text.substring(start, pos));
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index 5ac34188c..8e89e61ea 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -18,8 +18,6 @@ package com.android.inputmethod.keyboard.internal;
import android.util.Log;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-
import java.util.ArrayList;
public final class PointerTrackerQueue {
@@ -37,7 +35,7 @@ public final class PointerTrackerQueue {
// Note: {@link #mExpandableArrayOfActivePointers} and {@link #mArraySize} are synchronized by
// {@link #mExpandableArrayOfActivePointers}
private final ArrayList<Element> mExpandableArrayOfActivePointers =
- CollectionUtils.newArrayList(INITIAL_CAPACITY);
+ new ArrayList<>(INITIAL_CAPACITY);
private int mArraySize = 0;
public int size() {
diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
index 54bc29559..eb8b34ccd 100644
--- a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
+++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java
@@ -16,14 +16,14 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.latin.settings.SettingsValues;
-
import android.content.Context;
import android.media.AudioManager;
import android.os.Vibrator;
import android.view.HapticFeedbackConstants;
import android.view.View;
+import com.android.inputmethod.latin.settings.SettingsValues;
+
/**
* This class gathers audio feedback and haptic feedback functions.
*
@@ -86,40 +86,41 @@ public final class AudioAndHapticFeedbackManager {
if (mAudioManager == null) {
return;
}
- if (mSoundOn) {
- final int sound;
- switch (code) {
- case Constants.CODE_DELETE:
- sound = AudioManager.FX_KEYPRESS_DELETE;
- break;
- case Constants.CODE_ENTER:
- sound = AudioManager.FX_KEYPRESS_RETURN;
- break;
- case Constants.CODE_SPACE:
- sound = AudioManager.FX_KEYPRESS_SPACEBAR;
- break;
- default:
- sound = AudioManager.FX_KEYPRESS_STANDARD;
- break;
- }
- mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume);
+ if (!mSoundOn) {
+ return;
+ }
+ final int sound;
+ switch (code) {
+ case Constants.CODE_DELETE:
+ sound = AudioManager.FX_KEYPRESS_DELETE;
+ break;
+ case Constants.CODE_ENTER:
+ sound = AudioManager.FX_KEYPRESS_RETURN;
+ break;
+ case Constants.CODE_SPACE:
+ sound = AudioManager.FX_KEYPRESS_SPACEBAR;
+ break;
+ default:
+ sound = AudioManager.FX_KEYPRESS_STANDARD;
+ break;
}
+ mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume);
}
public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) {
if (!mSettingsValues.mVibrateOn) {
return;
}
- if (mSettingsValues.mKeypressVibrationDuration < 0) {
- // Go ahead with the system default
- if (viewToPerformHapticFeedbackOn != null) {
- viewToPerformHapticFeedbackOn.performHapticFeedback(
- HapticFeedbackConstants.KEYBOARD_TAP,
- HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
- }
+ if (mSettingsValues.mKeypressVibrationDuration >= 0) {
+ vibrate(mSettingsValues.mKeypressVibrationDuration);
return;
}
- vibrate(mSettingsValues.mKeypressVibrationDuration);
+ // Go ahead with the system default
+ if (viewToPerformHapticFeedbackOn != null) {
+ viewToPerformHapticFeedbackOn.performHapticFeedback(
+ HapticFeedbackConstants.KEYBOARD_TAP,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ }
}
public void onSettingsChanged(final SettingsValues settingsValues) {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index b88509fde..543f74fc4 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -30,7 +30,6 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.settings.NativeSuggestOptions;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
@@ -104,8 +103,7 @@ public final class BinaryDictionary extends Dictionary {
private final NativeSuggestOptions mNativeSuggestOptions = new NativeSuggestOptions();
- private final SparseArray<DicTraverseSession> mDicTraverseSessions =
- CollectionUtils.newSparseArray();
+ private final SparseArray<DicTraverseSession> mDicTraverseSessions = new SparseArray<>();
// TODO: There should be a way to remove used DicTraverseSession objects from
// {@code mDicTraverseSessions}.
@@ -113,11 +111,8 @@ public final class BinaryDictionary extends Dictionary {
synchronized(mDicTraverseSessions) {
DicTraverseSession traverseSession = mDicTraverseSessions.get(traverseSessionId);
if (traverseSession == null) {
- traverseSession = mDicTraverseSessions.get(traverseSessionId);
- if (traverseSession == null) {
- traverseSession = new DicTraverseSession(mLocale, mNativeDict, mDictSize);
- mDicTraverseSessions.put(traverseSessionId, traverseSession);
- }
+ traverseSession = new DicTraverseSession(mLocale, mNativeDict, mDictSize);
+ mDicTraverseSessions.put(traverseSessionId, traverseSession);
}
return traverseSession;
}
@@ -188,13 +183,15 @@ public final class BinaryDictionary extends Dictionary {
private static native void getHeaderInfoNative(long dict, int[] outHeaderSize,
int[] outFormatVersion, ArrayList<int[]> outAttributeKeys,
ArrayList<int[]> outAttributeValues);
- private static native void flushNative(long dict, String filePath);
+ private static native boolean flushNative(long dict, String filePath);
private static native boolean needsToRunGCNative(long dict, boolean mindsBlockByGC);
- private static native void flushWithGCNative(long dict, String filePath);
+ private static native boolean flushWithGCNative(long dict, String filePath);
private static native void closeNative(long dict);
private static native int getFormatVersionNative(long dict);
private static native int getProbabilityNative(long dict, int[] word);
- private static native int getBigramProbabilityNative(long dict, int[] word0, int[] word1);
+ private static native int getMaxProbabilityOfExactMatchesNative(long dict, int[] word);
+ private static native int getBigramProbabilityNative(long dict, int[] word0,
+ boolean isBeginningOfSentence, int[] word1);
private static native void getWordPropertyNative(long dict, int[] word,
int[] outCodePoints, boolean[] outFlags, int[] outProbabilityInfo,
ArrayList<int[]> outBigramTargets, ArrayList<int[]> outBigramProbabilityInfo,
@@ -203,21 +200,24 @@ public final class BinaryDictionary extends Dictionary {
private static native void getSuggestionsNative(long dict, long proximityInfo,
long traverseSession, int[] xCoordinates, int[] yCoordinates, int[] times,
int[] pointerIds, int[] inputCodePoints, int inputSize, int[] suggestOptions,
- int[] prevWordCodePointArray, int[] outputSuggestionCount, int[] outputCodePoints,
- int[] outputScores, int[] outputIndices, int[] outputTypes,
- int[] outputAutoCommitFirstWordConfidence, float[] inOutLanguageWeight);
- private static native void addUnigramWordNative(long dict, int[] word, int probability,
- int[] shortcutTarget, int shortcutProbability, boolean isNotAWord,
- boolean isBlacklisted, int timestamp);
- private static native void addBigramWordsNative(long dict, int[] word0, int[] word1,
- int probability, int timestamp);
- private static native void removeBigramWordsNative(long dict, int[] word0, int[] word1);
+ int[] prevWordCodePointArray, boolean isBeginningOfSentence,
+ int[] outputSuggestionCount, int[] outputCodePoints, int[] outputScores,
+ int[] outputIndices, int[] outputTypes, int[] outputAutoCommitFirstWordConfidence,
+ float[] inOutLanguageWeight);
+ private static native boolean addUnigramWordNative(long dict, int[] word, int probability,
+ int[] shortcutTarget, int shortcutProbability, boolean isBeginningOfSentence,
+ boolean isNotAWord, boolean isBlacklisted, int timestamp);
+ private static native boolean removeUnigramWordNative(long dict, int[] word);
+ private static native boolean addBigramWordsNative(long dict, int[] word0,
+ boolean isBeginningOfSentence, int[] word1, int probability, int timestamp);
+ private static native boolean removeBigramWordsNative(long dict, int[] word0,
+ boolean isBeginningOfSentence, int[] word1);
private static native int addMultipleDictionaryEntriesNative(long dict,
LanguageModelParam[] languageModelParams, int startIndex);
- private static native int calculateProbabilityNative(long dict, int unigramProbability,
- int bigramProbability);
private static native String getPropertyNative(long dict, String query);
private static native boolean isCorruptedNative(long dict);
+ private static native boolean migrateNative(long dict, String dictFilePath,
+ long newFormatVersion);
// TODO: Move native dict into session
private final void loadDictionary(final String path, final long startOffset,
@@ -248,11 +248,11 @@ public final class BinaryDictionary extends Dictionary {
}
final int[] outHeaderSize = new int[1];
final int[] outFormatVersion = new int[1];
- final ArrayList<int[]> outAttributeKeys = CollectionUtils.newArrayList();
- final ArrayList<int[]> outAttributeValues = CollectionUtils.newArrayList();
+ final ArrayList<int[]> outAttributeKeys = new ArrayList<>();
+ final ArrayList<int[]> outAttributeValues = new ArrayList<>();
getHeaderInfoNative(mNativeDict, outHeaderSize, outFormatVersion, outAttributeKeys,
outAttributeValues);
- final HashMap<String, String> attributes = new HashMap<String, String>();
+ final HashMap<String, String> attributes = new HashMap<>();
for (int i = 0; i < outAttributeKeys.size(); i++) {
final String attributeKey = StringUtils.getStringFromNullTerminatedCodePointArray(
outAttributeKeys.get(i));
@@ -266,19 +266,9 @@ public final class BinaryDictionary extends Dictionary {
new FormatSpec.FormatOptions(outFormatVersion[0], hasHistoricalInfo));
}
-
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
- return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
- additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight);
- }
-
- @Override
- public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) {
if (!isValidDictionary()) {
@@ -287,8 +277,8 @@ public final class BinaryDictionary extends Dictionary {
Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE);
// TODO: toLowerCase in the native code
- final int[] prevWordCodePointArray = (null == prevWord)
- ? null : StringUtils.toCodePointArray(prevWord);
+ final int[] prevWordCodePointArray = (null == prevWordsInfo.mPrevWord)
+ ? null : StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
final InputPointers inputPointers = composer.getInputPointers();
final boolean isGesture = composer.isBatchMode();
final int inputSize;
@@ -303,6 +293,7 @@ public final class BinaryDictionary extends Dictionary {
}
mNativeSuggestOptions.setIsGesture(isGesture);
+ mNativeSuggestOptions.setBlockOffensiveWords(blockOffensiveWords);
mNativeSuggestOptions.setAdditionalFeaturesOptions(additionalFeaturesOptions);
if (inOutLanguageWeight != null) {
mInputOutputLanguageWeight[0] = inOutLanguageWeight[0];
@@ -314,14 +305,15 @@ public final class BinaryDictionary extends Dictionary {
getTraverseSession(sessionId).getSession(), inputPointers.getXCoordinates(),
inputPointers.getYCoordinates(), inputPointers.getTimes(),
inputPointers.getPointerIds(), mInputCodePoints, inputSize,
- mNativeSuggestOptions.getOptions(), prevWordCodePointArray, mOutputSuggestionCount,
+ mNativeSuggestOptions.getOptions(), prevWordCodePointArray,
+ prevWordsInfo.mIsBeginningOfSentence, mOutputSuggestionCount,
mOutputCodePoints, mOutputScores, mSpaceIndices, mOutputTypes,
mOutputAutoCommitFirstWordConfidence, mInputOutputLanguageWeight);
if (inOutLanguageWeight != null) {
inOutLanguageWeight[0] = mInputOutputLanguageWeight[0];
}
final int count = mOutputSuggestionCount[0];
- final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
+ final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
for (int j = 0; j < count; ++j) {
final int start = j * MAX_WORD_LENGTH;
int len = 0;
@@ -329,21 +321,8 @@ public final class BinaryDictionary extends Dictionary {
++len;
}
if (len > 0) {
- final int flags = mOutputTypes[j] & SuggestedWordInfo.KIND_MASK_FLAGS;
- if (blockOffensiveWords
- && 0 != (flags & SuggestedWordInfo.KIND_FLAG_POSSIBLY_OFFENSIVE)
- && 0 == (flags & SuggestedWordInfo.KIND_FLAG_EXACT_MATCH)) {
- // If we block potentially offensive words, and if the word is possibly
- // offensive, then we don't output it unless it's also an exact match.
- continue;
- }
- final int kind = mOutputTypes[j] & SuggestedWordInfo.KIND_MASK_KIND;
- final int score = SuggestedWordInfo.KIND_WHITELIST == kind
- ? SuggestedWordInfo.MAX_SCORE : mOutputScores[j];
- // TODO: check that all users of the `kind' parameter are ready to accept
- // flags too and pass mOutputTypes[j] instead of kind
suggestions.add(new SuggestedWordInfo(new String(mOutputCodePoints, start, len),
- score, kind, this /* sourceDict */,
+ mOutputScores[j], mOutputTypes[j], this /* sourceDict */,
mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */,
mOutputAutoCommitFirstWordConfidence[0]));
}
@@ -360,28 +339,37 @@ public final class BinaryDictionary extends Dictionary {
}
@Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
return getFrequency(word) != NOT_A_PROBABILITY;
}
@Override
public int getFrequency(final String word) {
- if (word == null) return NOT_A_PROBABILITY;
+ if (TextUtils.isEmpty(word)) return NOT_A_PROBABILITY;
int[] codePoints = StringUtils.toCodePointArray(word);
return getProbabilityNative(mNativeDict, codePoints);
}
- // TODO: Add a batch process version (isValidBigramMultiple?) to avoid excessive numbers of jni
- // calls when checking for changes in an entire dictionary.
- public boolean isValidBigram(final String word0, final String word1) {
- return getBigramProbability(word0, word1) != NOT_A_PROBABILITY;
+ @Override
+ public int getMaxFrequencyOfExactMatches(final String word) {
+ if (TextUtils.isEmpty(word)) return NOT_A_PROBABILITY;
+ int[] codePoints = StringUtils.toCodePointArray(word);
+ return getMaxProbabilityOfExactMatchesNative(mNativeDict, codePoints);
}
- public int getBigramProbability(final String word0, final String word1) {
- if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) return NOT_A_PROBABILITY;
- final int[] codePoints0 = StringUtils.toCodePointArray(word0);
- final int[] codePoints1 = StringUtils.toCodePointArray(word1);
- return getBigramProbabilityNative(mNativeDict, codePoints0, codePoints1);
+ @UsedForTesting
+ public boolean isValidNgram(final PrevWordsInfo prevWordsInfo, final String word) {
+ return getNgramProbability(prevWordsInfo, word) != NOT_A_PROBABILITY;
+ }
+
+ public int getNgramProbability(final PrevWordsInfo prevWordsInfo, final String word) {
+ if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) {
+ return NOT_A_PROBABILITY;
+ }
+ final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
+ final int[] codePoints1 = StringUtils.toCodePointArray(word);
+ return getBigramProbabilityNative(mNativeDict, codePoints0,
+ prevWordsInfo.mIsBeginningOfSentence, codePoints1);
}
public WordProperty getWordProperty(final String word) {
@@ -393,10 +381,10 @@ public final class BinaryDictionary extends Dictionary {
final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT];
final int[] outProbabilityInfo =
new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT];
- final ArrayList<int[]> outBigramTargets = CollectionUtils.newArrayList();
- final ArrayList<int[]> outBigramProbabilityInfo = CollectionUtils.newArrayList();
- final ArrayList<int[]> outShortcutTargets = CollectionUtils.newArrayList();
- final ArrayList<Integer> outShortcutProbabilities = CollectionUtils.newArrayList();
+ final ArrayList<int[]> outBigramTargets = new ArrayList<>();
+ final ArrayList<int[]> outBigramProbabilityInfo = new ArrayList<>();
+ final ArrayList<int[]> outShortcutTargets = new ArrayList<>();
+ final ArrayList<Integer> outShortcutProbabilities = new ArrayList<>();
getWordPropertyNative(mNativeDict, codePoints, outCodePoints, outFlags, outProbabilityInfo,
outBigramTargets, outBigramProbabilityInfo, outShortcutTargets,
outShortcutProbabilities);
@@ -413,8 +401,8 @@ public final class BinaryDictionary extends Dictionary {
public WordProperty mWordProperty;
public int mNextToken;
- public GetNextWordPropertyResult(final WordProperty wordPreperty, final int nextToken) {
- mWordProperty = wordPreperty;
+ public GetNextWordPropertyResult(final WordProperty wordProperty, final int nextToken) {
+ mWordProperty = wordProperty;
mNextToken = nextToken;
}
}
@@ -431,41 +419,66 @@ public final class BinaryDictionary extends Dictionary {
}
// Add a unigram entry to binary dictionary with unigram attributes in native code.
- public void addUnigramWord(final String word, final int probability,
- final String shortcutTarget, final int shortcutProbability, final boolean isNotAWord,
+ public boolean addUnigramEntry(final String word, final int probability,
+ final String shortcutTarget, final int shortcutProbability,
+ final boolean isBeginningOfSentence, final boolean isNotAWord,
final boolean isBlacklisted, final int timestamp) {
- if (TextUtils.isEmpty(word)) {
- return;
+ if (word == null || (word.isEmpty() && !isBeginningOfSentence)) {
+ return false;
}
final int[] codePoints = StringUtils.toCodePointArray(word);
final int[] shortcutTargetCodePoints = (shortcutTarget != null) ?
StringUtils.toCodePointArray(shortcutTarget) : null;
- addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints,
- shortcutProbability, isNotAWord, isBlacklisted, timestamp);
+ if (!addUnigramWordNative(mNativeDict, codePoints, probability, shortcutTargetCodePoints,
+ shortcutProbability, isBeginningOfSentence, isNotAWord, isBlacklisted, timestamp)) {
+ return false;
+ }
mHasUpdated = true;
+ return true;
}
- // Add a bigram entry to binary dictionary with timestamp in native code.
- public void addBigramWords(final String word0, final String word1, final int probability,
- final int timestamp) {
- if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) {
- return;
+ // Remove a unigram entry from the binary dictionary in native code.
+ public boolean removeUnigramEntry(final String word) {
+ if (TextUtils.isEmpty(word)) {
+ return false;
+ }
+ final int[] codePoints = StringUtils.toCodePointArray(word);
+ if (!removeUnigramWordNative(mNativeDict, codePoints)) {
+ return false;
}
- final int[] codePoints0 = StringUtils.toCodePointArray(word0);
- final int[] codePoints1 = StringUtils.toCodePointArray(word1);
- addBigramWordsNative(mNativeDict, codePoints0, codePoints1, probability, timestamp);
mHasUpdated = true;
+ return true;
}
- // Remove a bigram entry form binary dictionary in native code.
- public void removeBigramWords(final String word0, final String word1) {
- if (TextUtils.isEmpty(word0) || TextUtils.isEmpty(word1)) {
- return;
+ // Add an n-gram entry to the binary dictionary with timestamp in native code.
+ public boolean addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word,
+ final int probability, final int timestamp) {
+ if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) {
+ return false;
+ }
+ final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
+ final int[] codePoints1 = StringUtils.toCodePointArray(word);
+ if (!addBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence,
+ codePoints1, probability, timestamp)) {
+ return false;
}
- final int[] codePoints0 = StringUtils.toCodePointArray(word0);
- final int[] codePoints1 = StringUtils.toCodePointArray(word1);
- removeBigramWordsNative(mNativeDict, codePoints0, codePoints1);
mHasUpdated = true;
+ return true;
+ }
+
+ // Remove an n-gram entry from the binary dictionary in native code.
+ public boolean removeNgramEntry(final PrevWordsInfo prevWordsInfo, final String word) {
+ if (!prevWordsInfo.isValid() || TextUtils.isEmpty(word)) {
+ return false;
+ }
+ final int[] codePoints0 = StringUtils.toCodePointArray(prevWordsInfo.mPrevWord);
+ final int[] codePoints1 = StringUtils.toCodePointArray(word);
+ if (!removeBigramWordsNative(mNativeDict, codePoints0, prevWordsInfo.mIsBeginningOfSentence,
+ codePoints1)) {
+ return false;
+ }
+ mHasUpdated = true;
+ return true;
}
public void addMultipleDictionaryEntries(final LanguageModelParam[] languageModelParams) {
@@ -495,26 +508,33 @@ public final class BinaryDictionary extends Dictionary {
}
// Flush to dict file if the dictionary has been updated.
- public void flush() {
- if (!isValidDictionary()) return;
+ public boolean flush() {
+ if (!isValidDictionary()) return false;
if (mHasUpdated) {
- flushNative(mNativeDict, mDictFilePath);
+ if (!flushNative(mNativeDict, mDictFilePath)) {
+ return false;
+ }
reopen();
}
+ return true;
}
// Run GC and flush to dict file if the dictionary has been updated.
- public void flushWithGCIfHasUpdated() {
+ public boolean flushWithGCIfHasUpdated() {
if (mHasUpdated) {
- flushWithGC();
+ return flushWithGC();
}
+ return true;
}
// Run GC and flush to dict file.
- public void flushWithGC() {
- if (!isValidDictionary()) return;
- flushWithGCNative(mNativeDict, mDictFilePath);
+ public boolean flushWithGC() {
+ if (!isValidDictionary()) return false;
+ if (!flushWithGCNative(mNativeDict, mDictFilePath)) {
+ return false;
+ }
reopen();
+ return true;
}
/**
@@ -533,11 +553,15 @@ public final class BinaryDictionary extends Dictionary {
return false;
}
final String tmpDictFilePath = mDictFilePath + DICT_FILE_NAME_SUFFIX_FOR_MIGRATION;
- // TODO: Implement migrateNative(tmpDictFilePath, newFormatVersion).
+ if (!migrateNative(mNativeDict, tmpDictFilePath, newFormatVersion)) {
+ return false;
+ }
close();
final File dictFile = new File(mDictFilePath);
final File tmpDictFile = new File(tmpDictFilePath);
- FileUtils.deleteRecursively(dictFile);
+ if (!FileUtils.deleteRecursively(dictFile)) {
+ return false;
+ }
if (!BinaryDictionaryUtils.renameDict(tmpDictFile, dictFile)) {
return false;
}
@@ -547,12 +571,6 @@ public final class BinaryDictionary extends Dictionary {
}
@UsedForTesting
- public int calculateProbability(final int unigramProbability, final int bigramProbability) {
- if (!isValidDictionary()) return NOT_A_PROBABILITY;
- return calculateProbabilityNative(mNativeDict, unigramProbability, bigramProbability);
- }
-
- @UsedForTesting
public String getPropertyForTest(final String query) {
if (!isValidDictionary()) return "";
return getPropertyNative(mNativeDict, query);
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
index e428b1d54..10b1f1b77 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java
@@ -28,7 +28,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
-import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.dictionarypack.MD5Calculator;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils.DictionaryInfo;
import com.android.inputmethod.latin.utils.FileTransforms;
@@ -38,12 +38,13 @@ import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -163,12 +164,13 @@ public final class BinaryDictionaryFileDumper {
if (cursor.getCount() <= 0 || !cursor.moveToFirst()) {
return Collections.<WordListInfo>emptyList();
}
- final ArrayList<WordListInfo> list = CollectionUtils.newArrayList();
+ final ArrayList<WordListInfo> list = new ArrayList<>();
do {
final String wordListId = cursor.getString(0);
final String wordListLocale = cursor.getString(1);
+ final String wordListRawChecksum = cursor.getString(2);
if (TextUtils.isEmpty(wordListId)) continue;
- list.add(new WordListInfo(wordListId, wordListLocale));
+ list.add(new WordListInfo(wordListId, wordListLocale, wordListRawChecksum));
} while (cursor.moveToNext());
return list;
} catch (RemoteException e) {
@@ -217,7 +219,8 @@ public final class BinaryDictionaryFileDumper {
* and creating it (and its containing directory) if necessary.
*/
private static void cacheWordList(final String wordlistId, final String locale,
- final ContentProviderClient providerClient, final Context context) {
+ final String rawChecksum, final ContentProviderClient providerClient,
+ final Context context) {
final int COMPRESSED_CRYPTED_COMPRESSED = 0;
final int CRYPTED_COMPRESSED = 1;
final int COMPRESSED_CRYPTED = 2;
@@ -299,6 +302,13 @@ public final class BinaryDictionaryFileDumper {
checkMagicAndCopyFileTo(bufferedInputStream, bufferedOutputStream);
bufferedOutputStream.flush();
bufferedOutputStream.close();
+ final String actualRawChecksum = MD5Calculator.checksum(
+ new BufferedInputStream(new FileInputStream(outputFile)));
+ Log.i(TAG, "Computed checksum for downloaded dictionary. Expected = " + rawChecksum
+ + " ; actual = " + actualRawChecksum);
+ if (!TextUtils.isEmpty(rawChecksum) && !rawChecksum.equals(actualRawChecksum)) {
+ throw new IOException("Could not decode the file correctly : checksum differs");
+ }
final File finalFile = new File(finalFileName);
finalFile.delete();
if (!outputFile.renameTo(finalFile)) {
@@ -408,7 +418,7 @@ public final class BinaryDictionaryFileDumper {
final List<WordListInfo> idList = getWordListWordListInfos(locale, context,
hasDefaultWordList);
for (WordListInfo id : idList) {
- cacheWordList(id.mId, id.mLocale, providerClient, context);
+ cacheWordList(id.mId, id.mLocale, id.mRawChecksum, providerClient, context);
}
} finally {
providerClient.release();
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
index 4c49cb31c..867c18686 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java
@@ -24,7 +24,6 @@ import android.util.Log;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
@@ -160,7 +159,7 @@ final public class BinaryDictionaryGetter {
public static File[] getCachedWordLists(final String locale, final Context context) {
final File[] directoryList = DictionaryInfoUtils.getCachedDirectoryList(context);
if (null == directoryList) return EMPTY_FILE_ARRAY;
- final HashMap<String, FileAndMatchLevel> cacheFiles = CollectionUtils.newHashMap();
+ final HashMap<String, FileAndMatchLevel> cacheFiles = new HashMap<>();
for (File directory : directoryList) {
if (!directory.isDirectory()) continue;
final String dirLocale =
@@ -273,7 +272,7 @@ final public class BinaryDictionaryGetter {
final DictPackSettings dictPackSettings = new DictPackSettings(context);
boolean foundMainDict = false;
- final ArrayList<AssetFileAddress> fileList = CollectionUtils.newArrayList();
+ final ArrayList<AssetFileAddress> fileList = new ArrayList<>();
// cachedWordLists may not be null, see doc for getCachedDictionaryList
for (final File f : cachedWordLists) {
final String wordListId = DictionaryInfoUtils.getWordListIdFromFileName(f.getName());
diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java
index e71723a15..fa51436de 100644
--- a/java/src/com/android/inputmethod/latin/Constants.java
+++ b/java/src/com/android/inputmethod/latin/Constants.java
@@ -115,6 +115,11 @@ public final class Constants {
*/
public static final String IS_ADDITIONAL_SUBTYPE = "isAdditionalSubtype";
+ /**
+ * The subtype extra value used to specify the combining rules.
+ */
+ public static final String COMBINING_RULES = "CombiningRules";
+
private ExtraValue() {
// This utility class is not publicly instantiable.
}
@@ -153,6 +158,10 @@ public final class Constants {
// A hint on how many characters to cache from the TextView. A good value of this is given by
// how many characters we need to be able to almost always find the caps mode.
public static final int EDITOR_CONTENTS_CACHE_SIZE = 1024;
+ // How many characters we accept for the recapitalization functionality. This needs to be
+ // large enough for all reasonable purposes, but avoid purposeful attacks. 100k sounds about
+ // right for this.
+ public static final int MAX_CHARACTERS_FOR_RECAPITALIZATION = 1024 * 100;
// Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
@@ -164,6 +173,8 @@ public final class Constants {
// How many continuous deletes at which to start deleting at a higher speed.
public static final int DELETE_ACCELERATE_AT = 20;
+ public static final String WORD_SEPARATOR = " ";
+
public static boolean isValidCoordinate(final int coordinate) {
// Detect {@link NOT_A_COORDINATE}, {@link SUGGESTION_STRIP_COORDINATE},
// and {@link SPELL_CHECKER_COORDINATE}.
@@ -185,7 +196,6 @@ public final class Constants {
public static final int CODE_SPACE = ' ';
public static final int CODE_PERIOD = '.';
public static final int CODE_COMMA = ',';
- public static final int CODE_ARMENIAN_PERIOD = 0x0589;
public static final int CODE_DASH = '-';
public static final int CODE_SINGLE_QUOTE = '\'';
public static final int CODE_DOUBLE_QUOTE = '"';
@@ -201,6 +211,11 @@ public final class Constants {
public static final int CODE_CLOSING_SQUARE_BRACKET = ']';
public static final int CODE_CLOSING_CURLY_BRACKET = '}';
public static final int CODE_CLOSING_ANGLE_BRACKET = '>';
+ public static final int CODE_INVERTED_QUESTION_MARK = 0xBF; // ¿
+ public static final int CODE_INVERTED_EXCLAMATION_MARK = 0xA1; // ¡
+
+ public static final String REGEXP_PERIOD = "\\.";
+ public static final String STRING_SPACE = " ";
/**
* Special keys code. Must be negative.
@@ -242,14 +257,16 @@ public final class Constants {
case CODE_LANGUAGE_SWITCH: return "languageSwitch";
case CODE_EMOJI: return "emoji";
case CODE_SHIFT_ENTER: return "shiftEnter";
+ case CODE_ALPHA_FROM_EMOJI: return "alpha";
case CODE_UNSPECIFIED: return "unspec";
case CODE_TAB: return "tab";
case CODE_ENTER: return "enter";
- case CODE_ALPHA_FROM_EMOJI: return "alpha";
+ case CODE_SPACE: return "space";
default:
- if (code < CODE_SPACE) return String.format("'\\u%02x'", code);
- if (code < 0x100) return String.format("'%c'", code);
- return String.format("'\\u%04x'", code);
+ if (code < CODE_SPACE) return String.format("\\u%02x", code);
+ if (code < 0x100) return String.format("%c", code);
+ if (code < 0x10000) return String.format("\\u04x", code);
+ return String.format("\\U%05x", code);
}
}
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index 09d0ea210..96160fa4e 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -29,10 +29,13 @@ import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.personalization.AccountUtils;
+import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import java.io.File;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -59,10 +62,10 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private static final int INDEX_NAME = 1;
/** The number of contacts in the most recent dictionary rebuild. */
- static private int sContactCountAtLastRebuild = 0;
+ private int mContactCountAtLastRebuild = 0;
- /** The locale for this contacts dictionary. Controls name bigram predictions. */
- public final Locale mLocale;
+ /** The hash code of ArrayList of contacts names in the most recent dictionary rebuild. */
+ private int mHashCodeAtLastRebuild = 0;
private ContentObserver mObserver;
@@ -71,25 +74,21 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
*/
private final boolean mUseFirstLastBigrams;
- public ContactsBinaryDictionary(final Context context, final Locale locale) {
- this(context, locale, null /* dictFile */);
- }
-
- public ContactsBinaryDictionary(final Context context, final Locale locale,
- final File dictFile) {
- this(context, locale, dictFile, NAME);
- }
-
protected ContactsBinaryDictionary(final Context context, final Locale locale,
final File dictFile, final String name) {
super(context, getDictName(name, locale, dictFile), locale, Dictionary.TYPE_CONTACTS,
dictFile);
- mLocale = locale;
mUseFirstLastBigrams = useFirstLastBigramsForLocale(locale);
registerObserver(context);
reloadDictionaryIfRequired();
}
+ @UsedForTesting
+ public static ContactsBinaryDictionary getDictionary(final Context context, final Locale locale,
+ final File dictFile, final String dictNamePrefix) {
+ return new ContactsBinaryDictionary(context, locale, dictFile, dictNamePrefix + NAME);
+ }
+
private synchronized void registerObserver(final Context context) {
if (mObserver != null) return;
ContentResolver cres = context.getContentResolver();
@@ -97,7 +96,14 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
new ContentObserver(null) {
@Override
public void onChange(boolean self) {
- setNeedsToReload();
+ ExecutorUtils.getExecutor("Check Contacts").execute(new Runnable() {
+ @Override
+ public void run() {
+ if (haveContentsChanged()) {
+ setNeedsToRecreate();
+ }
+ }
+ });
}
});
}
@@ -130,7 +136,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
Log.d(TAG, "loadAccountVocabulary: " + word);
}
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addWordDynamicallyLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */,
+ addUnigramLocked(word, FREQUENCY_FOR_CONTACTS, null /* shortcut */,
0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */,
BinaryDictionary.NOT_A_VALID_TIMESTAMP);
}
@@ -144,7 +150,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return;
}
if (cursor.moveToFirst()) {
- sContactCountAtLastRebuild = getContactCount();
+ mContactCountAtLastRebuild = getContactCount();
addWordsLocked(cursor);
}
} catch (final SQLiteException e) {
@@ -168,9 +174,11 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
private void addWordsLocked(final Cursor cursor) {
int count = 0;
+ final ArrayList<String> names = new ArrayList<>();
while (!cursor.isAfterLast() && count < MAX_CONTACT_COUNT) {
String name = cursor.getString(INDEX_NAME);
if (isValidName(name)) {
+ names.add(name);
addNameLocked(name);
++count;
} else {
@@ -180,6 +188,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
cursor.moveToNext();
}
+ mHashCodeAtLastRebuild = names.hashCode();
}
private int getContactCount() {
@@ -209,7 +218,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
*/
private void addNameLocked(final String name) {
int len = StringUtils.codePointCount(name);
- String prevWord = null;
+ PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
// TODO: Better tokenization for non-Latin writing systems
for (int i = 0; i < len; i++) {
if (Character.isLetter(name.codePointAt(i))) {
@@ -224,19 +233,19 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
final int wordLen = StringUtils.codePointCount(word);
if (wordLen < MAX_WORD_LENGTH && wordLen > 1) {
if (DEBUG) {
- Log.d(TAG, "addName " + name + ", " + word + ", " + prevWord);
+ Log.d(TAG, "addName " + name + ", " + word + ", "
+ + prevWordsInfo.mPrevWord);
}
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addWordDynamicallyLocked(word, FREQUENCY_FOR_CONTACTS,
+ addUnigramLocked(word, FREQUENCY_FOR_CONTACTS,
null /* shortcut */, 0 /* shortcutFreq */, false /* isNotAWord */,
false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
- if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) {
+ if (!TextUtils.isEmpty(prevWordsInfo.mPrevWord) && mUseFirstLastBigrams) {
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addBigramDynamicallyLocked(prevWord, word,
- FREQUENCY_FOR_CONTACTS_BIGRAM,
+ addNgramEntryLocked(prevWordsInfo, word, FREQUENCY_FOR_CONTACTS_BIGRAM,
BinaryDictionary.NOT_A_VALID_TIMESTAMP);
}
- prevWord = word;
+ prevWordsInfo = new PrevWordsInfo(word);
}
}
}
@@ -259,8 +268,7 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
return end;
}
- @Override
- protected boolean haveContentsChanged() {
+ private boolean haveContentsChanged() {
final long startTime = SystemClock.uptimeMillis();
final int contactCount = getContactCount();
if (contactCount > MAX_CONTACT_COUNT) {
@@ -269,9 +277,9 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
// TODO: Sort and check only the MAX_CONTACT_COUNT most recent contacts?
return false;
}
- if (contactCount != sContactCountAtLastRebuild) {
+ if (contactCount != mContactCountAtLastRebuild) {
if (DEBUG) {
- Log.d(TAG, "Contact count changed: " + sContactCountAtLastRebuild + " to "
+ Log.d(TAG, "Contact count changed: " + mContactCountAtLastRebuild + " to "
+ contactCount);
}
return true;
@@ -284,20 +292,20 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
if (null == cursor) {
return false;
}
+ final ArrayList<String> names = new ArrayList<>();
try {
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
String name = cursor.getString(INDEX_NAME);
- if (isValidName(name) && !isNameInDictionaryLocked(name)) {
- if (DEBUG) {
- Log.d(TAG, "Contact name missing: " + name + " (runtime = "
- + (SystemClock.uptimeMillis() - startTime) + " ms)");
- }
- return true;
+ if (isValidName(name)) {
+ names.add(name);
}
cursor.moveToNext();
}
}
+ if (names.hashCode() != mHashCodeAtLastRebuild) {
+ return true;
+ }
} finally {
cursor.close();
}
@@ -314,33 +322,4 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary {
}
return false;
}
-
- /**
- * Checks if the words in a name are in the current binary dictionary.
- */
- private boolean isNameInDictionaryLocked(final String name) {
- int len = StringUtils.codePointCount(name);
- String prevWord = null;
- for (int i = 0; i < len; i++) {
- if (Character.isLetter(name.codePointAt(i))) {
- int end = getWordEndPosition(name, len, i);
- String word = name.substring(i, end);
- i = end - 1;
- final int wordLen = StringUtils.codePointCount(word);
- if (wordLen < MAX_WORD_LENGTH && wordLen > 1) {
- if (!TextUtils.isEmpty(prevWord) && mUseFirstLastBigrams) {
- if (!isValidBigramLocked(prevWord, word)) {
- return false;
- }
- } else {
- if (!isValidWordLocked(word)) {
- return false;
- }
- }
- prevWord = word;
- }
- }
- }
- return true;
- }
}
diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java
index 0742fbde9..b55ed125f 100644
--- a/java/src/com/android/inputmethod/latin/Dictionary.java
+++ b/java/src/com/android/inputmethod/latin/Dictionary.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -57,6 +58,8 @@ public abstract class Dictionary {
public static final String TYPE_USER_HISTORY = "history";
// Personalization dictionary.
public static final String TYPE_PERSONALIZATION = "personalization";
+ // Contextual dictionary.
+ public static final String TYPE_CONTEXTUAL = "contextual";
public final String mDictType;
public Dictionary(final String dictType) {
@@ -67,43 +70,44 @@ public abstract class Dictionary {
* Searches for suggestions for a given context. For the moment the context is only the
* previous word.
* @param composer the key sequence to match with coordinate info, as a WordComposer
- * @param prevWord the previous word, or null if none
+ * @param prevWordsInfo the information of previous words.
* @param proximityInfo the object for key proximity. May be ignored by some implementations.
* @param blockOffensiveWords whether to block potentially offensive words
* @param additionalFeaturesOptions options about additional features used for the suggestion.
+ * @param sessionId the session id.
* @param inOutLanguageWeight the language weight used for generating suggestions.
* inOutLanguageWeight is a float array that has only one element. This can be updated when the
* different language weight is used.
* @return the list of suggestions (possibly null if none)
*/
- // TODO: pass more context than just the previous word, to enable better suggestions (n-gram
- // and more)
abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight);
+ final int sessionId, final float[] inOutLanguageWeight);
- // The default implementation of this method ignores sessionId.
- // Subclasses that want to use sessionId need to override this method.
- public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final int sessionId, final float[] inOutLanguageWeight) {
- return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords,
- additionalFeaturesOptions, inOutLanguageWeight);
+ /**
+ * Checks if the given word has to be treated as a valid word. Please note that some
+ * dictionaries have entries that should be treated as invalid words.
+ * @param word the word to search for. The search should be case-insensitive.
+ * @return true if the word is valid, false otherwise
+ */
+ public boolean isValidWord(final String word) {
+ return isInDictionary(word);
}
/**
- * Checks if the given word occurs in the dictionary
- * @param word the word to search for. The search should be case-insensitive.
- * @return true if the word exists, false otherwise
+ * Checks if the given word is in the dictionary regardless of it being valid or not.
*/
- abstract public boolean isValidWord(final String word);
+ abstract public boolean isInDictionary(final String word);
public int getFrequency(final String word) {
return NOT_A_PROBABILITY;
}
+ public int getMaxFrequencyOfExactMatches(final String word) {
+ return NOT_A_PROBABILITY;
+ }
+
/**
* Compares the contents of the character array with the typed word and returns true if they
* are the same.
@@ -163,14 +167,14 @@ public abstract class Dictionary {
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
+ final int sessionId, final float[] inOutLanguageWeight) {
return null;
}
@Override
- public boolean isValidWord(String word) {
+ public boolean isInDictionary(String word) {
return false;
}
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
index 16173fffc..89d61ce2a 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java
@@ -20,7 +20,6 @@ import android.util.Log;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList;
import java.util.Collection;
@@ -36,52 +35,52 @@ public final class DictionaryCollection extends Dictionary {
public DictionaryCollection(final String dictType) {
super(dictType);
- mDictionaries = CollectionUtils.newCopyOnWriteArrayList();
+ mDictionaries = new CopyOnWriteArrayList<>();
}
public DictionaryCollection(final String dictType, final Dictionary... dictionaries) {
super(dictType);
if (null == dictionaries) {
- mDictionaries = CollectionUtils.newCopyOnWriteArrayList();
+ mDictionaries = new CopyOnWriteArrayList<>();
} else {
- mDictionaries = CollectionUtils.newCopyOnWriteArrayList(dictionaries);
+ mDictionaries = new CopyOnWriteArrayList<>(dictionaries);
mDictionaries.removeAll(Collections.singleton(null));
}
}
public DictionaryCollection(final String dictType, final Collection<Dictionary> dictionaries) {
super(dictType);
- mDictionaries = CollectionUtils.newCopyOnWriteArrayList(dictionaries);
+ mDictionaries = new CopyOnWriteArrayList<>(dictionaries);
mDictionaries.removeAll(Collections.singleton(null));
}
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
+ final int sessionId, final float[] inOutLanguageWeight) {
final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries;
if (dictionaries.isEmpty()) return null;
// To avoid creating unnecessary objects, we get the list out of the first
// dictionary and add the rest to it if not null, hence the get(0)
ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer,
- prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
- inOutLanguageWeight);
- if (null == suggestions) suggestions = CollectionUtils.newArrayList();
+ prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
+ sessionId, inOutLanguageWeight);
+ if (null == suggestions) suggestions = new ArrayList<>();
final int length = dictionaries.size();
for (int i = 1; i < length; ++ i) {
final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer,
- prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
- inOutLanguageWeight);
+ prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
+ sessionId, inOutLanguageWeight);
if (null != sugg) suggestions.addAll(sugg);
}
return suggestions;
}
@Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
for (int i = mDictionaries.size() - 1; i >= 0; --i)
- if (mDictionaries.get(i).isValidWord(word)) return true;
+ if (mDictionaries.get(i).isInDictionary(word)) return true;
return false;
}
@@ -90,9 +89,17 @@ public final class DictionaryCollection extends Dictionary {
int maxFreq = -1;
for (int i = mDictionaries.size() - 1; i >= 0; --i) {
final int tempFreq = mDictionaries.get(i).getFrequency(word);
- if (tempFreq >= maxFreq) {
- maxFreq = tempFreq;
- }
+ maxFreq = Math.max(tempFreq, maxFreq);
+ }
+ return maxFreq;
+ }
+
+ @Override
+ public int getMaxFrequencyOfExactMatches(final String word) {
+ int maxFreq = -1;
+ for (int i = mDictionaries.size() - 1; i >= 0; --i) {
+ final int tempFreq = mDictionaries.get(i).getMaxFrequencyOfExactMatches(word);
+ maxFreq = Math.max(tempFreq, maxFreq);
}
return maxFreq;
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 5238395a4..e6e2bcbc7 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -19,21 +19,30 @@ package com.android.inputmethod.latin;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
+import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.personalization.ContextualDictionary;
+import com.android.inputmethod.latin.personalization.PersonalizationDataChunk;
import com.android.inputmethod.latin.personalization.PersonalizationDictionary;
-import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
-import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+import com.android.inputmethod.latin.utils.DistracterFilter;
+import com.android.inputmethod.latin.utils.DistracterFilterCheckingIsInDictionary;
import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import com.android.inputmethod.latin.utils.SuggestionResults;
import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -41,80 +50,93 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
// TODO: Consolidate dictionaries in native code.
-public class DictionaryFacilitatorForSuggest {
- public static final String TAG = DictionaryFacilitatorForSuggest.class.getSimpleName();
+public class DictionaryFacilitator {
+ public static final String TAG = DictionaryFacilitator.class.getSimpleName();
// HACK: This threshold is being used when adding a capitalized entry in the User History
// dictionary.
private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140;
private Dictionaries mDictionaries = new Dictionaries();
+ private boolean mIsUserDictEnabled = false;
private volatile CountDownLatch mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
// To synchronize assigning mDictionaries to ensure closing dictionaries.
- private Object mLock = new Object();
+ private final Object mLock = new Object();
+ private final DistracterFilter mDistracterFilter;
- private static final String[] dictTypesOrderedToGetSuggestion =
+ private static final String[] DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS =
new String[] {
Dictionary.TYPE_MAIN,
Dictionary.TYPE_USER_HISTORY,
Dictionary.TYPE_PERSONALIZATION,
Dictionary.TYPE_USER,
- Dictionary.TYPE_CONTACTS
+ Dictionary.TYPE_CONTACTS,
+ Dictionary.TYPE_CONTEXTUAL
};
+ public static final Map<String, Class<? extends ExpandableBinaryDictionary>>
+ DICT_TYPE_TO_CLASS = new HashMap<>();
+
+ static {
+ DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER_HISTORY, UserHistoryDictionary.class);
+ DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_PERSONALIZATION, PersonalizationDictionary.class);
+ DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_USER, UserBinaryDictionary.class);
+ DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTACTS, ContactsBinaryDictionary.class);
+ DICT_TYPE_TO_CLASS.put(Dictionary.TYPE_CONTEXTUAL, ContextualDictionary.class);
+ }
+
+ private static final String DICT_FACTORY_METHOD_NAME = "getDictionary";
+ private static final Class<?>[] DICT_FACTORY_METHOD_ARG_TYPES =
+ new Class[] { Context.class, Locale.class, File.class, String.class };
+
+ private static final String[] SUB_DICT_TYPES =
+ Arrays.copyOfRange(DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS, 1 /* start */,
+ DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS.length);
+
/**
* Class contains dictionaries for a locale.
*/
private static class Dictionaries {
public final Locale mLocale;
- public final ConcurrentHashMap<String, Dictionary> mDictMap =
- CollectionUtils.newConcurrentHashMap();
+ private Dictionary mMainDict;
public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap =
- CollectionUtils.newConcurrentHashMap();
- // TODO: Remove sub dictionary members and use mSubDictMap.
- public final UserBinaryDictionary mUserDictionary;
+ new ConcurrentHashMap<>();
public Dictionaries() {
mLocale = null;
- mUserDictionary = null;
}
public Dictionaries(final Locale locale, final Dictionary mainDict,
- final ExpandableBinaryDictionary contactsDict, final UserBinaryDictionary userDict,
- final ExpandableBinaryDictionary userHistoryDict,
- final ExpandableBinaryDictionary personalizationDict) {
+ final Map<String, ExpandableBinaryDictionary> subDicts) {
mLocale = locale;
// Main dictionary can be asynchronously loaded.
setMainDict(mainDict);
- setSubDict(Dictionary.TYPE_CONTACTS, contactsDict);
- mUserDictionary = userDict;
- setSubDict(Dictionary.TYPE_USER, mUserDictionary);
- setSubDict(Dictionary.TYPE_USER_HISTORY, userHistoryDict);
- setSubDict(Dictionary.TYPE_PERSONALIZATION, personalizationDict);
+ for (final Map.Entry<String, ExpandableBinaryDictionary> entry : subDicts.entrySet()) {
+ setSubDict(entry.getKey(), entry.getValue());
+ }
}
private void setSubDict(final String dictType, final ExpandableBinaryDictionary dict) {
if (dict != null) {
- mDictMap.put(dictType, dict);
mSubDictMap.put(dictType, dict);
}
}
public void setMainDict(final Dictionary mainDict) {
// Close old dictionary if exists. Main dictionary can be assigned multiple times.
- final Dictionary oldDict;
- if (mainDict != null) {
- oldDict = mDictMap.put(Dictionary.TYPE_MAIN, mainDict);
- } else {
- oldDict = mDictMap.remove(Dictionary.TYPE_MAIN);
- }
+ final Dictionary oldDict = mMainDict;
+ mMainDict = mainDict;
if (oldDict != null && mainDict != oldDict) {
oldDict.close();
}
}
- public Dictionary getMainDict() {
- return mDictMap.get(Dictionary.TYPE_MAIN);
+ public Dictionary getDict(final String dictType) {
+ if (Dictionary.TYPE_MAIN.equals(dictType)) {
+ return mMainDict;
+ } else {
+ return getSubDict(dictType);
+ }
}
public ExpandableBinaryDictionary getSubDict(final String dictType) {
@@ -122,12 +144,20 @@ public class DictionaryFacilitatorForSuggest {
}
public boolean hasDict(final String dictType) {
- return mDictMap.containsKey(dictType);
+ if (Dictionary.TYPE_MAIN.equals(dictType)) {
+ return mMainDict != null;
+ } else {
+ return mSubDictMap.containsKey(dictType);
+ }
}
public void closeDict(final String dictType) {
- final Dictionary dict = mDictMap.remove(dictType);
- mSubDictMap.remove(dictType);
+ final Dictionary dict;
+ if (Dictionary.TYPE_MAIN.equals(dictType)) {
+ dict = mMainDict;
+ } else {
+ dict = mSubDictMap.remove(dictType);
+ }
if (dict != null) {
dict.close();
}
@@ -138,80 +168,104 @@ public class DictionaryFacilitatorForSuggest {
public void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
}
- public DictionaryFacilitatorForSuggest() {}
+ public DictionaryFacilitator() {
+ mDistracterFilter = DistracterFilter.EMPTY_DISTRACTER_FILTER;
+ }
+
+ public DictionaryFacilitator(final DistracterFilter distracterFilter) {
+ mDistracterFilter = distracterFilter;
+ }
+
+ public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
+ mDistracterFilter.updateEnabledSubtypes(enabledSubtypes);
+ }
public Locale getLocale() {
return mDictionaries.mLocale;
}
+ private static ExpandableBinaryDictionary getSubDict(final String dictType,
+ final Context context, final Locale locale, final File dictFile,
+ final String dictNamePrefix) {
+ final Class<? extends ExpandableBinaryDictionary> dictClass =
+ DICT_TYPE_TO_CLASS.get(dictType);
+ if (dictClass == null) {
+ return null;
+ }
+ try {
+ final Method factoryMethod = dictClass.getMethod(DICT_FACTORY_METHOD_NAME,
+ DICT_FACTORY_METHOD_ARG_TYPES);
+ final Object dict = factoryMethod.invoke(null /* obj */,
+ new Object[] { context, locale, dictFile, dictNamePrefix });
+ return (ExpandableBinaryDictionary) dict;
+ } catch (final NoSuchMethodException | SecurityException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException e) {
+ Log.e(TAG, "Cannot create dictionary: " + dictType, e);
+ return null;
+ }
+ }
+
public void resetDictionaries(final Context context, final Locale newLocale,
final boolean useContactsDict, final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
final DictionaryInitializationListener listener) {
+ resetDictionariesWithDictNamePrefix(context, newLocale, useContactsDict,
+ usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */);
+ }
+
+ public void resetDictionariesWithDictNamePrefix(final Context context, final Locale newLocale,
+ final boolean useContactsDict, final boolean usePersonalizedDicts,
+ final boolean forceReloadMainDictionary,
+ final DictionaryInitializationListener listener,
+ final String dictNamePrefix) {
final boolean localeHasBeenChanged = !newLocale.equals(mDictionaries.mLocale);
// We always try to have the main dictionary. Other dictionaries can be unused.
final boolean reloadMainDictionary = localeHasBeenChanged || forceReloadMainDictionary;
- final boolean closeContactsDictionary = localeHasBeenChanged || !useContactsDict;
- final boolean closeUserDictionary = localeHasBeenChanged;
- final boolean closeUserHistoryDictionary = localeHasBeenChanged || !usePersonalizedDicts;
- final boolean closePersonalizationDictionary =
- localeHasBeenChanged || !usePersonalizedDicts;
+ // TODO: Make subDictTypesToUse configurable by resource or a static final list.
+ final HashSet<String> subDictTypesToUse = new HashSet<>();
+ if (useContactsDict) {
+ subDictTypesToUse.add(Dictionary.TYPE_CONTACTS);
+ }
+ subDictTypesToUse.add(Dictionary.TYPE_USER);
+ if (usePersonalizedDicts) {
+ subDictTypesToUse.add(Dictionary.TYPE_USER_HISTORY);
+ subDictTypesToUse.add(Dictionary.TYPE_PERSONALIZATION);
+ subDictTypesToUse.add(Dictionary.TYPE_CONTEXTUAL);
+ }
final Dictionary newMainDict;
if (reloadMainDictionary) {
// The main dictionary will be asynchronously loaded.
newMainDict = null;
} else {
- newMainDict = mDictionaries.getMainDict();
- }
-
- // Open or move contacts dictionary.
- final ExpandableBinaryDictionary newContactsDict;
- if (!closeContactsDictionary && mDictionaries.hasDict(Dictionary.TYPE_CONTACTS)) {
- newContactsDict = mDictionaries.getSubDict(Dictionary.TYPE_CONTACTS);
- } else if (useContactsDict) {
- newContactsDict = new ContactsBinaryDictionary(context, newLocale);
- } else {
- newContactsDict = null;
- }
-
- // Open or move user dictionary.
- final UserBinaryDictionary newUserDictionary;
- if (!closeUserDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER)) {
- newUserDictionary = mDictionaries.mUserDictionary;
- } else {
- newUserDictionary = new UserBinaryDictionary(context, newLocale);
- }
-
- // Open or move user history dictionary.
- final ExpandableBinaryDictionary newUserHistoryDict;
- if (!closeUserHistoryDictionary && mDictionaries.hasDict(Dictionary.TYPE_USER_HISTORY)) {
- newUserHistoryDict = mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
- } else if (usePersonalizedDicts) {
- newUserHistoryDict = PersonalizationHelper.getUserHistoryDictionary(context, newLocale);
- } else {
- newUserHistoryDict = null;
+ newMainDict = mDictionaries.getDict(Dictionary.TYPE_MAIN);
}
- // Open or move personalization dictionary.
- final ExpandableBinaryDictionary newPersonalizationDict;
- if (!closePersonalizationDictionary
- && mDictionaries.hasDict(Dictionary.TYPE_PERSONALIZATION)) {
- newPersonalizationDict = mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION);
- } else if (usePersonalizedDicts) {
- newPersonalizationDict =
- PersonalizationHelper.getPersonalizationDictionary(context, newLocale);
- } else {
- newPersonalizationDict = null;
+ final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
+ for (final String dictType : SUB_DICT_TYPES) {
+ if (!subDictTypesToUse.contains(dictType)) {
+ // This dictionary will not be used.
+ continue;
+ }
+ final ExpandableBinaryDictionary dict;
+ if (!localeHasBeenChanged && mDictionaries.hasDict(dictType)) {
+ // Continue to use current dictionary.
+ dict = mDictionaries.getSubDict(dictType);
+ } else {
+ // Start to use new dictionary.
+ dict = getSubDict(dictType, context, newLocale, null /* dictFile */,
+ dictNamePrefix);
+ }
+ subDicts.put(dictType, dict);
}
// Replace Dictionaries.
- final Dictionaries newDictionaries = new Dictionaries(newLocale, newMainDict,
- newContactsDict, newUserDictionary, newUserHistoryDict, newPersonalizationDict);
+ final Dictionaries newDictionaries = new Dictionaries(newLocale, newMainDict, subDicts);
final Dictionaries oldDictionaries;
synchronized (mLock) {
oldDictionaries = mDictionaries;
mDictionaries = newDictionaries;
+ mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context);
if (reloadMainDictionary) {
asyncReloadMainDictionary(context, newLocale, listener);
}
@@ -219,24 +273,15 @@ public class DictionaryFacilitatorForSuggest {
if (listener != null) {
listener.onUpdateMainDictionaryAvailability(hasInitializedMainDictionary());
}
-
// Clean up old dictionaries.
if (reloadMainDictionary) {
oldDictionaries.closeDict(Dictionary.TYPE_MAIN);
}
- if (closeContactsDictionary) {
- oldDictionaries.closeDict(Dictionary.TYPE_CONTACTS);
- }
- if (closeUserDictionary) {
- oldDictionaries.closeDict(Dictionary.TYPE_USER);
- }
- if (closeUserHistoryDictionary) {
- oldDictionaries.closeDict(Dictionary.TYPE_USER_HISTORY);
- }
- if (closePersonalizationDictionary) {
- oldDictionaries.closeDict(Dictionary.TYPE_PERSONALIZATION);
+ for (final String dictType : SUB_DICT_TYPES) {
+ if (localeHasBeenChanged || !subDictTypesToUse.contains(dictType)) {
+ oldDictionaries.closeDict(dictType);
+ }
}
- oldDictionaries.mDictMap.clear();
oldDictionaries.mSubDictMap.clear();
}
@@ -270,52 +315,28 @@ public class DictionaryFacilitatorForSuggest {
final ArrayList<String> dictionaryTypes, final HashMap<String, File> dictionaryFiles,
final Map<String, Map<String, String>> additionalDictAttributes) {
Dictionary mainDictionary = null;
- ContactsBinaryDictionary contactsDictionary = null;
- UserBinaryDictionary userDictionary = null;
- UserHistoryDictionary userHistoryDictionary = null;
- PersonalizationDictionary personalizationDictionary = null;
+ final Map<String, ExpandableBinaryDictionary> subDicts = new HashMap<>();
for (final String dictType : dictionaryTypes) {
if (dictType.equals(Dictionary.TYPE_MAIN)) {
mainDictionary = DictionaryFactory.createMainDictionaryFromManager(context, locale);
- } else if (dictType.equals(Dictionary.TYPE_USER_HISTORY)) {
- userHistoryDictionary =
- PersonalizationHelper.getUserHistoryDictionary(context, locale);
- // Staring with an empty user history dictionary for testing.
- // Testing program may populate this dictionary before actual testing.
- userHistoryDictionary.reloadDictionaryIfRequired();
- userHistoryDictionary.waitAllTasksForTests();
+ } else {
+ final File dictFile = dictionaryFiles.get(dictType);
+ final ExpandableBinaryDictionary dict = getSubDict(
+ dictType, context, locale, dictFile, "" /* dictNamePrefix */);
if (additionalDictAttributes.containsKey(dictType)) {
- userHistoryDictionary.clearAndFlushDictionaryWithAdditionalAttributes(
+ dict.clearAndFlushDictionaryWithAdditionalAttributes(
additionalDictAttributes.get(dictType));
}
- } else if (dictType.equals(Dictionary.TYPE_PERSONALIZATION)) {
- personalizationDictionary =
- PersonalizationHelper.getPersonalizationDictionary(context, locale);
- // Staring with an empty personalization dictionary for testing.
- // Testing program may populate this dictionary before actual testing.
- personalizationDictionary.reloadDictionaryIfRequired();
- personalizationDictionary.waitAllTasksForTests();
- if (additionalDictAttributes.containsKey(dictType)) {
- personalizationDictionary.clearAndFlushDictionaryWithAdditionalAttributes(
- additionalDictAttributes.get(dictType));
+ if (dict == null) {
+ throw new RuntimeException("Unknown dictionary type: " + dictType);
}
- } else if (dictType.equals(Dictionary.TYPE_USER)) {
- final File file = dictionaryFiles.get(dictType);
- userDictionary = new UserBinaryDictionary(context, locale, file);
- userDictionary.reloadDictionaryIfRequired();
- userDictionary.waitAllTasksForTests();
- } else if (dictType.equals(Dictionary.TYPE_CONTACTS)) {
- final File file = dictionaryFiles.get(dictType);
- contactsDictionary = new ContactsBinaryDictionary(context, locale, file);
- contactsDictionary.reloadDictionaryIfRequired();
- contactsDictionary.waitAllTasksForTests();
- } else {
- throw new RuntimeException("Unknown dictionary type: " + dictType);
+ dict.reloadDictionaryIfRequired();
+ dict.waitAllTasksForTests();
+ subDicts.put(dictType, dict);
}
}
- mDictionaries = new Dictionaries(locale, mainDictionary, contactsDictionary,
- userDictionary, userHistoryDictionary, personalizationDictionary);
+ mDictionaries = new Dictionaries(locale, mainDictionary, subDicts);
}
public void closeDictionaries() {
@@ -324,15 +345,16 @@ public class DictionaryFacilitatorForSuggest {
dictionaries = mDictionaries;
mDictionaries = new Dictionaries();
}
- for (final Dictionary dict : dictionaries.mDictMap.values()) {
- dict.close();
+ for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ dictionaries.closeDict(dictType);
}
+ mDistracterFilter.close();
}
// The main dictionary could have been loaded asynchronously. Don't cache the return value
// of this method.
public boolean hasInitializedMainDictionary() {
- final Dictionary mainDict = mDictionaries.getMainDict();
+ final Dictionary mainDict = mDictionaries.getDict(Dictionary.TYPE_MAIN);
return mainDict != null && mainDict.isInitialized();
}
@@ -364,48 +386,59 @@ public class DictionaryFacilitatorForSuggest {
}
public boolean isUserDictionaryEnabled() {
- final UserBinaryDictionary userDictionary = mDictionaries.mUserDictionary;
- if (userDictionary == null) {
- return false;
- }
- return userDictionary.mEnabled;
+ return mIsUserDictEnabled;
}
- public void addWordToUserDictionary(String word) {
- final UserBinaryDictionary userDictionary = mDictionaries.mUserDictionary;
- if (userDictionary == null) {
+ public void addWordToUserDictionary(final Context context, final String word) {
+ final Locale locale = getLocale();
+ if (locale == null) {
return;
}
- userDictionary.addWordToUserDictionary(word);
+ UserBinaryDictionary.addWordToUserDictionary(context, locale, word);
}
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
- final String previousWord, final int timeStampInSeconds) {
+ final PrevWordsInfo prevWordsInfo, final int timeStampInSeconds,
+ final boolean blockPotentiallyOffensive) {
final Dictionaries dictionaries = mDictionaries;
+ final String[] words = suggestion.split(Constants.WORD_SEPARATOR);
+ for (int i = 0; i < words.length; i++) {
+ final String currentWord = words[i];
+ final PrevWordsInfo prevWordsInfoForCurrentWord =
+ (i == 0) ? prevWordsInfo : new PrevWordsInfo(words[i - 1]);
+ final boolean wasCurrentWordAutoCapitalized = (i == 0) ? wasAutoCapitalized : false;
+ addWordToUserHistory(dictionaries, prevWordsInfoForCurrentWord, currentWord,
+ wasCurrentWordAutoCapitalized, timeStampInSeconds, blockPotentiallyOffensive);
+ }
+ }
+
+ private void addWordToUserHistory(final Dictionaries dictionaries,
+ final PrevWordsInfo prevWordsInfo, final String word, final boolean wasAutoCapitalized,
+ final int timeStampInSeconds, final boolean blockPotentiallyOffensive) {
final ExpandableBinaryDictionary userHistoryDictionary =
dictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
if (userHistoryDictionary == null) {
return;
}
- final int maxFreq = getMaxFrequency(suggestion);
- if (maxFreq == 0) {
+ final int maxFreq = getFrequency(word);
+ if (maxFreq == 0 && blockPotentiallyOffensive) {
return;
}
- final String suggestionLowerCase = suggestion.toLowerCase(dictionaries.mLocale);
+ final String lowerCasedWord = word.toLowerCase(dictionaries.mLocale);
final String secondWord;
if (wasAutoCapitalized) {
- if (isValidWord(suggestion, false /* ignoreCase */)
- && !isValidWord(suggestionLowerCase, false /* ignoreCase */)) {
+ if (isValidWord(word, false /* ignoreCase */)
+ && !isValidWord(lowerCasedWord, false /* ignoreCase */)) {
// If the word was auto-capitalized and exists only as a capitalized word in the
// dictionary, then we must not downcase it before registering it. For example,
// the name of the contacts in start-of-sentence position would come here with the
// wasAutoCapitalized flag: if we downcase it, we'd register a lower-case version
// of that contact's name which would end up popping in suggestions.
- secondWord = suggestion;
+ secondWord = word;
} else {
// If however the word is not in the dictionary, or exists as a lower-case word
// only, then we consider that was a lower-case word that had been auto-capitalized.
- secondWord = suggestionLowerCase;
+ secondWord = lowerCasedWord;
}
} else {
// HACK: We'd like to avoid adding the capitalized form of common words to the User
@@ -413,46 +446,46 @@ public class DictionaryFacilitatorForSuggest {
// consolidation is done.
// TODO: Remove this hack when ready.
final int lowerCaseFreqInMainDict = dictionaries.hasDict(Dictionary.TYPE_MAIN) ?
- dictionaries.getMainDict().getFrequency(suggestionLowerCase) :
+ dictionaries.getDict(Dictionary.TYPE_MAIN).getFrequency(lowerCasedWord) :
Dictionary.NOT_A_PROBABILITY;
if (maxFreq < lowerCaseFreqInMainDict
&& lowerCaseFreqInMainDict >= CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT) {
// Use lower cased word as the word can be a distracter of the popular word.
- secondWord = suggestionLowerCase;
+ secondWord = lowerCasedWord;
} else {
- secondWord = suggestion;
+ secondWord = word;
}
}
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
// We don't add words with 0-frequency (assuming they would be profanity etc.).
final boolean isValid = maxFreq > 0;
- UserHistoryDictionary.addToDictionary(userHistoryDictionary, previousWord, secondWord,
- isValid, timeStampInSeconds);
+ UserHistoryDictionary.addToDictionary(userHistoryDictionary, prevWordsInfo, secondWord,
+ isValid, timeStampInSeconds, mDistracterFilter);
}
- public void cancelAddingUserHistory(final String previousWord, final String committedWord) {
+ public void cancelAddingUserHistory(final PrevWordsInfo prevWordsInfo,
+ final String committedWord) {
final ExpandableBinaryDictionary userHistoryDictionary =
mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
if (userHistoryDictionary != null) {
- userHistoryDictionary.removeBigramDynamically(previousWord, committedWord);
+ userHistoryDictionary.removeNgramDynamically(prevWordsInfo, committedWord);
}
}
// TODO: Revise the way to fusion suggestion results.
public SuggestionResults getSuggestionResults(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final ArrayList<SuggestedWordInfo> rawSuggestions) {
final Dictionaries dictionaries = mDictionaries;
- final Map<String, Dictionary> dictMap = dictionaries.mDictMap;
final SuggestionResults suggestionResults =
new SuggestionResults(dictionaries.mLocale, SuggestedWords.MAX_SUGGESTIONS);
final float[] languageWeight = new float[] { Dictionary.NOT_A_LANGUAGE_WEIGHT };
- for (final String dictType : dictTypesOrderedToGetSuggestion) {
- final Dictionary dictionary = dictMap.get(dictType);
+ for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ final Dictionary dictionary = dictionaries.getDict(dictType);
if (null == dictionary) continue;
final ArrayList<SuggestedWordInfo> dictionarySuggestions =
- dictionary.getSuggestionsWithSessionId(composer, prevWord, proximityInfo,
+ dictionary.getSuggestions(composer, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId,
languageWeight);
if (null == dictionarySuggestions) continue;
@@ -465,11 +498,11 @@ public class DictionaryFacilitatorForSuggest {
}
public boolean isValidMainDictWord(final String word) {
- final Dictionaries dictionaries = mDictionaries;
- if (TextUtils.isEmpty(word) || !dictionaries.hasDict(Dictionary.TYPE_MAIN)) {
+ final Dictionary mainDict = mDictionaries.getDict(Dictionary.TYPE_MAIN);
+ if (TextUtils.isEmpty(word) || mainDict == null) {
return false;
}
- return dictionaries.getMainDict().isValidWord(word);
+ return mainDict.isValidWord(word);
}
public boolean isValidWord(final String word, final boolean ignoreCase) {
@@ -481,8 +514,8 @@ public class DictionaryFacilitatorForSuggest {
return false;
}
final String lowerCasedWord = word.toLowerCase(dictionaries.mLocale);
- final Map<String, Dictionary> dictMap = dictionaries.mDictMap;
- for (final Dictionary dictionary : dictMap.values()) {
+ for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ final Dictionary dictionary = dictionaries.getDict(dictType);
// Ideally the passed map would come out of a {@link java.util.concurrent.Future} and
// would be immutable once it's finished initializing, but concretely a null test is
// probably good enough for the time being.
@@ -495,14 +528,22 @@ public class DictionaryFacilitatorForSuggest {
return false;
}
- private int getMaxFrequency(final String word) {
+ private int getFrequencyInternal(final String word,
+ final boolean isGettingMaxFrequencyOfExactMatches) {
if (TextUtils.isEmpty(word)) {
return Dictionary.NOT_A_PROBABILITY;
}
- int maxFreq = -1;
- final Map<String, Dictionary> dictMap = mDictionaries.mDictMap;
- for (final Dictionary dictionary : dictMap.values()) {
- final int tempFreq = dictionary.getFrequency(word);
+ int maxFreq = Dictionary.NOT_A_PROBABILITY;
+ final Dictionaries dictionaries = mDictionaries;
+ for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
+ final Dictionary dictionary = dictionaries.getDict(dictType);
+ if (dictionary == null) continue;
+ final int tempFreq;
+ if (isGettingMaxFrequencyOfExactMatches) {
+ tempFreq = dictionary.getMaxFrequencyOfExactMatches(word);
+ } else {
+ tempFreq = dictionary.getFrequency(word);
+ }
if (tempFreq >= maxFreq) {
maxFreq = tempFreq;
}
@@ -510,6 +551,14 @@ public class DictionaryFacilitatorForSuggest {
return maxFreq;
}
+ public int getFrequency(final String word) {
+ return getFrequencyInternal(word, false /* isGettingMaxFrequencyOfExactMatches */);
+ }
+
+ public int getMaxFrequencyOfExactMatches(final String word) {
+ return getFrequencyInternal(word, true /* isGettingMaxFrequencyOfExactMatches */);
+ }
+
public void clearUserHistoryDictionary() {
final ExpandableBinaryDictionary userHistoryDict =
mDictionaries.getSubDict(Dictionary.TYPE_USER_HISTORY);
@@ -530,13 +579,26 @@ public class DictionaryFacilitatorForSuggest {
personalizationDict.clear();
}
- public void addMultipleDictionaryEntriesToPersonalizationDictionary(
- final ArrayList<LanguageModelParam> languageModelParams,
+ public void addEntriesToPersonalizationDictionary(
+ final PersonalizationDataChunk personalizationDataChunk,
+ final SpacingAndPunctuations spacingAndPunctuations,
final ExpandableBinaryDictionary.AddMultipleDictionaryEntriesCallback callback) {
final ExpandableBinaryDictionary personalizationDict =
mDictionaries.getSubDict(Dictionary.TYPE_PERSONALIZATION);
- if (personalizationDict == null || languageModelParams == null
- || languageModelParams.isEmpty()) {
+ if (personalizationDict == null) {
+ if (callback != null) {
+ callback.onFinished();
+ }
+ return;
+ }
+ final ArrayList<LanguageModelParam> languageModelParams =
+ LanguageModelParam.createLanguageModelParamsFrom(
+ personalizationDataChunk.mTokens,
+ personalizationDataChunk.mTimestampInSeconds,
+ this /* dictionaryFacilitator */, spacingAndPunctuations,
+ new DistracterFilterCheckingIsInDictionary(
+ mDistracterFilter, personalizationDict));
+ if (languageModelParams == null || languageModelParams.isEmpty()) {
if (callback != null) {
callback.onFinished();
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index e09c309ea..59de4f82a 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -23,7 +23,6 @@ import android.content.res.Resources;
import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
import java.io.File;
@@ -55,7 +54,7 @@ public final class DictionaryFactory {
createReadOnlyBinaryDictionary(context, locale));
}
- final LinkedList<Dictionary> dictList = CollectionUtils.newLinkedList();
+ final LinkedList<Dictionary> dictList = new LinkedList<>();
final ArrayList<AssetFileAddress> assetFileList =
BinaryDictionaryGetter.getDictionaryFiles(locale, context);
if (null != assetFileList) {
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 550db4a6c..b1966bffc 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -27,6 +27,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
+import com.android.inputmethod.latin.utils.DistracterFilter;
import com.android.inputmethod.latin.utils.ExecutorUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
@@ -48,12 +49,12 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
* queries in native code. This binary dictionary is written to internal storage.
*/
abstract public class ExpandableBinaryDictionary extends Dictionary {
+ private static final boolean DEBUG = false;
/** Used for Log actions from this class */
private static final String TAG = ExpandableBinaryDictionary.class.getSimpleName();
/** Whether to print debug output to log */
- private static boolean DEBUG = false;
private static final boolean DBG_STRESS_TEST = false;
private static final int TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS = 100;
@@ -92,11 +93,13 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/** Indicates whether a task for reloading the dictionary has been scheduled. */
private final AtomicBoolean mIsReloading;
- /** Indicates whether the current dictionary needs to be reloaded. */
- private boolean mNeedsToReload;
+ /** Indicates whether the current dictionary needs to be recreated. */
+ private boolean mNeedsToRecreate;
private final ReentrantReadWriteLock mLock;
+ private Map<String, String> mAdditionalAttributeMap = null;
+
/* A extension for a binary dictionary file. */
protected static final String DICT_FILE_EXTENSION = ".dict";
@@ -105,26 +108,26 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
*/
protected abstract void loadInitialContentsLocked();
- /**
- * Indicates that the source dictionary contents have changed and a rebuild of the binary file
- * is required. If it returns false, the next reload will only read the current binary
- * dictionary from file.
- */
- protected abstract boolean haveContentsChanged();
-
private boolean matchesExpectedBinaryDictFormatVersionForThisType(final int formatVersion) {
return formatVersion == FormatSpec.VERSION4;
}
private boolean needsToMigrateDictionary(final int formatVersion) {
- // TODO: Check version.
- return false;
+ // When we bump up the dictionary format version, the old version should be added to here
+ // for supporting migration. Note that native code has to support reading such formats.
+ return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING;
}
public boolean isValidDictionaryLocked() {
return mBinaryDictionary.isValidDictionary();
}
+ // TODO: Remove and always enable beginning of sentence prediction. Currently, this is enabled
+ // only for ContextualDictionary.
+ protected boolean enableBeginningOfSentencePrediction() {
+ return false;
+ }
+
/**
* Creates a new expandable binary dictionary.
*
@@ -145,7 +148,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
mDictFile = getDictFile(context, dictName, dictFile);
mBinaryDictionary = null;
mIsReloading = new AtomicBoolean();
- mNeedsToReload = false;
+ mNeedsToRecreate = false;
mLock = new ReentrantReadWriteLock();
}
@@ -195,7 +198,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
protected Map<String, String> getHeaderAttributeMap() {
- HashMap<String, String> attributeMap = new HashMap<String, String>();
+ HashMap<String, String> attributeMap = new HashMap<>();
+ if (mAdditionalAttributeMap != null) {
+ attributeMap.putAll(mAdditionalAttributeMap);
+ }
attributeMap.put(DictionaryHeader.DICTIONARY_ID_KEY, mDictName);
attributeMap.put(DictionaryHeader.DICTIONARY_LOCALE_KEY, mLocale.toString());
attributeMap.put(DictionaryHeader.DICTIONARY_VERSION_KEY,
@@ -270,11 +276,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
- * Dynamically adds a word unigram to the dictionary. May overwrite an existing entry.
+ * Adds unigram information of a word to the dictionary. May overwrite an existing entry.
*/
- public void addWordDynamically(final String word, final int frequency,
+ public void addUnigramEntryWithCheckingDistracter(final String word, final int frequency,
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
- final boolean isBlacklisted, final int timestamp) {
+ final boolean isBlacklisted, final int timestamp,
+ final DistracterFilter distracterFilter) {
reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() {
@Override
@@ -282,24 +289,31 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (mBinaryDictionary == null) {
return;
}
+ if (distracterFilter.isDistracterToWordsInDictionaries(
+ PrevWordsInfo.EMPTY_PREV_WORDS_INFO, word, mLocale)) {
+ // The word is a distracter.
+ return;
+ }
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addWordDynamicallyLocked(word, frequency, shortcutTarget, shortcutFreq,
+ addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq,
isNotAWord, isBlacklisted, timestamp);
}
});
}
- protected void addWordDynamicallyLocked(final String word, final int frequency,
+ protected void addUnigramLocked(final String word, final int frequency,
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
final boolean isBlacklisted, final int timestamp) {
- mBinaryDictionary.addUnigramWord(word, frequency, shortcutTarget, shortcutFreq,
- isNotAWord, isBlacklisted, timestamp);
+ if (!mBinaryDictionary.addUnigramEntry(word, frequency, shortcutTarget, shortcutFreq,
+ false /* isBeginningOfSentence */, isNotAWord, isBlacklisted, timestamp)) {
+ Log.e(TAG, "Cannot add unigram entry. word: " + word);
+ }
}
/**
- * Dynamically adds a word bigram in the dictionary. May overwrite an existing entry.
+ * Adds n-gram information of a word to the dictionary. May overwrite an existing entry.
*/
- public void addBigramDynamically(final String word0, final String word1,
+ public void addNgramEntry(final PrevWordsInfo prevWordsInfo, final String word,
final int frequency, final int timestamp) {
reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() {
@@ -309,20 +323,25 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return;
}
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addBigramDynamicallyLocked(word0, word1, frequency, timestamp);
+ addNgramEntryLocked(prevWordsInfo, word, frequency, timestamp);
}
});
}
- protected void addBigramDynamicallyLocked(final String word0, final String word1,
+ protected void addNgramEntryLocked(final PrevWordsInfo prevWordsInfo, final String word,
final int frequency, final int timestamp) {
- mBinaryDictionary.addBigramWords(word0, word1, frequency, timestamp);
+ if (!mBinaryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp)) {
+ if (DEBUG) {
+ Log.i(TAG, "Cannot add n-gram entry.");
+ Log.i(TAG, " PrevWordsInfo: " + prevWordsInfo + ", word: " + word);
+ }
+ }
}
/**
- * Dynamically remove a word bigram in the dictionary.
+ * Dynamically remove the n-gram entry in the dictionary.
*/
- public void removeBigramDynamically(final String word0, final String word1) {
+ public void removeNgramDynamically(final PrevWordsInfo prevWordsInfo, final String word) {
reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() {
@Override
@@ -331,7 +350,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return;
}
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- mBinaryDictionary.removeBigramWords(word0, word1);
+ if (!mBinaryDictionary.removeNgramEntry(prevWordsInfo, word)) {
+ if (DEBUG) {
+ Log.i(TAG, "Cannot remove n-gram entry.");
+ Log.i(TAG, " PrevWordsInfo: " + prevWordsInfo + ", word: " + word);
+ }
+ }
}
});
}
@@ -367,8 +391,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) {
reloadDictionaryIfRequired();
@@ -380,10 +404,14 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (mBinaryDictionary == null) {
return null;
}
+ if (composer.size() == 0 && prevWordsInfo.mIsBeginningOfSentence
+ && !enableBeginningOfSentencePrediction()) {
+ return null;
+ }
final ArrayList<SuggestedWordInfo> suggestions =
- mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord,
- proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
- sessionId, inOutLanguageWeight);
+ mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, sessionId,
+ inOutLanguageWeight);
if (mBinaryDictionary.isCorrupted()) {
Log.i(TAG, "Dictionary (" + mDictName +") is corrupted. "
+ "Remove and regenerate it.");
@@ -402,16 +430,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
@Override
- public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
- return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
- additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight);
- }
-
- @Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
reloadDictionaryIfRequired();
boolean lockAcquired = false;
try {
@@ -421,10 +440,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
if (mBinaryDictionary == null) {
return false;
}
- return isValidWordLocked(word);
+ return isInDictionaryLocked(word);
}
} catch (final InterruptedException e) {
- Log.e(TAG, "Interrupted tryLock() in isValidWord().", e);
+ Log.e(TAG, "Interrupted tryLock() in isInDictionary().", e);
} finally {
if (lockAcquired) {
mLock.readLock().unlock();
@@ -433,14 +452,38 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return false;
}
- protected boolean isValidWordLocked(final String word) {
+ protected boolean isInDictionaryLocked(final String word) {
if (mBinaryDictionary == null) return false;
- return mBinaryDictionary.isValidWord(word);
+ return mBinaryDictionary.isInDictionary(word);
}
- protected boolean isValidBigramLocked(final String word1, final String word2) {
+ @Override
+ public int getMaxFrequencyOfExactMatches(final String word) {
+ reloadDictionaryIfRequired();
+ boolean lockAcquired = false;
+ try {
+ lockAcquired = mLock.readLock().tryLock(
+ TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
+ if (lockAcquired) {
+ if (mBinaryDictionary == null) {
+ return NOT_A_PROBABILITY;
+ }
+ return mBinaryDictionary.getMaxFrequencyOfExactMatches(word);
+ }
+ } catch (final InterruptedException e) {
+ Log.e(TAG, "Interrupted tryLock() in getMaxFrequencyOfExactMatches().", e);
+ } finally {
+ if (lockAcquired) {
+ mLock.readLock().unlock();
+ }
+ }
+ return NOT_A_PROBABILITY;
+ }
+
+
+ protected boolean isValidNgramLocked(final PrevWordsInfo prevWordsInfo, final String word) {
if (mBinaryDictionary == null) return false;
- return mBinaryDictionary.isValidBigram(word1, word2);
+ return mBinaryDictionary.isValidNgram(prevWordsInfo, word);
}
/**
@@ -465,7 +508,10 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
if (mBinaryDictionary.isValidDictionary()
&& needsToMigrateDictionary(mBinaryDictionary.getFormatVersion())) {
- mBinaryDictionary.migrateTo(DICTIONARY_FORMAT_VERSION);
+ if (!mBinaryDictionary.migrateTo(DICTIONARY_FORMAT_VERSION)) {
+ Log.e(TAG, "Dictionary migration failed: " + mDictName);
+ removeBinaryDictionaryLocked();
+ }
}
}
@@ -481,11 +527,11 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
/**
- * Marks that the dictionary needs to be reloaded.
+ * Marks that the dictionary needs to be recreated.
*
*/
- protected void setNeedsToReload() {
- mNeedsToReload = true;
+ protected void setNeedsToRecreate() {
+ mNeedsToRecreate = true;
}
/**
@@ -503,7 +549,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Returns whether a dictionary reload is required.
*/
private boolean isReloadRequired() {
- return mBinaryDictionary == null || mNeedsToReload;
+ return mBinaryDictionary == null || mNeedsToRecreate;
}
/**
@@ -515,25 +561,24 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
@Override
public void run() {
try {
- // TODO: Quit checking contents in ExpandableBinaryDictionary.
- if (!mDictFile.exists() || (mNeedsToReload && haveContentsChanged())) {
+ if (!mDictFile.exists() || mNeedsToRecreate) {
// If the dictionary file does not exist or contents have been updated,
// generate a new one.
createNewDictionaryLocked();
} else if (mBinaryDictionary == null) {
// Otherwise, load the existing dictionary.
loadBinaryDictionaryLocked();
+ if (mBinaryDictionary != null && !(isValidDictionaryLocked()
+ // TODO: remove the check below
+ && matchesExpectedBinaryDictFormatVersionForThisType(
+ mBinaryDictionary.getFormatVersion()))) {
+ // Binary dictionary or its format version is not valid. Regenerate
+ // the dictionary file. createNewDictionaryLocked will remove the
+ // existing files if appropriate.
+ createNewDictionaryLocked();
+ }
}
- mNeedsToReload = false;
- if (mBinaryDictionary != null && !(isValidDictionaryLocked()
- // TODO: remove the check below
- && matchesExpectedBinaryDictFormatVersionForThisType(
- mBinaryDictionary.getFormatVersion()))) {
- // Binary dictionary or its format version is not valid. Regenerate
- // the dictionary file. writeBinaryDictionary will remove the
- // existing files if appropriate.
- createNewDictionaryLocked();
- }
+ mNeedsToRecreate = false;
} finally {
mIsReloading.set(false);
}
@@ -561,20 +606,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
});
}
- // TODO: Implement BinaryDictionary.isInDictionary().
- @UsedForTesting
- public boolean isInUnderlyingBinaryDictionaryForTests(final String word) {
- mLock.readLock().lock();
- try {
- if (mBinaryDictionary != null && mDictType == Dictionary.TYPE_USER_HISTORY) {
- return mBinaryDictionary.isValidWord(word);
- }
- return false;
- } finally {
- mLock.readLock().unlock();
- }
- }
-
@UsedForTesting
public void waitAllTasksForTests() {
final CountDownLatch countDownLatch = new CountDownLatch(1);
@@ -592,6 +623,12 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
@UsedForTesting
+ public void clearAndFlushDictionaryWithAdditionalAttributes(
+ final Map<String, String> attributeMap) {
+ mAdditionalAttributeMap = attributeMap;
+ clear();
+ }
+
public void dumpAllWordsForDebug() {
reloadDictionaryIfRequired();
asyncExecuteTaskWithLock(mLock.readLock(), new Runnable() {
@@ -600,6 +637,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
Log.d(TAG, "Dump dictionary: " + mDictName);
try {
final DictionaryHeader header = mBinaryDictionary.getHeader();
+ Log.d(TAG, "Format version: " + mBinaryDictionary.getFormatVersion());
Log.d(TAG, CombinedFormatUtils.formatAttributeMap(
header.mDictionaryOptions.mAttributes));
} catch (final UnsupportedFormatException e) {
diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java
index 726b3d141..e1ae3dfe3 100644
--- a/java/src/com/android/inputmethod/latin/InputAttributes.java
+++ b/java/src/com/android/inputmethod/latin/InputAttributes.java
@@ -16,11 +16,13 @@
package com.android.inputmethod.latin;
+import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE;
+import static com.android.inputmethod.latin.Constants.ImeOption.NO_MICROPHONE_COMPAT;
+
import android.text.InputType;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -36,16 +38,23 @@ public final class InputAttributes {
final public String mTargetApplicationPackageName;
final public boolean mInputTypeNoAutoCorrect;
final public boolean mIsPasswordField;
- final public boolean mIsSettingsSuggestionStripOn;
+ final public boolean mShouldShowSuggestions;
final public boolean mApplicationSpecifiedCompletionOn;
final public boolean mShouldInsertSpacesAutomatically;
final private int mInputType;
+ final private EditorInfo mEditorInfo;
+ final private String mPackageNameForPrivateImeOptions;
- public InputAttributes(final EditorInfo editorInfo, final boolean isFullscreenMode) {
+ public InputAttributes(final EditorInfo editorInfo, final boolean isFullscreenMode,
+ final String packageNameForPrivateImeOptions) {
+ mEditorInfo = editorInfo;
+ mPackageNameForPrivateImeOptions = packageNameForPrivateImeOptions;
mTargetApplicationPackageName = null != editorInfo ? editorInfo.packageName : null;
final int inputType = null != editorInfo ? editorInfo.inputType : 0;
final int inputClass = inputType & InputType.TYPE_MASK_CLASS;
mInputType = inputType;
+ mIsPasswordField = InputTypeUtils.isPasswordInputType(inputType)
+ || InputTypeUtils.isVisiblePasswordInputType(inputType);
if (inputClass != InputType.TYPE_CLASS_TEXT) {
// If we are not looking at a TYPE_CLASS_TEXT field, the following strange
// cases may arise, so we do a couple sanity checks for them. If it's a
@@ -61,8 +70,7 @@ public final class InputAttributes {
Log.w(TAG, String.format("Unexpected input class: inputType=0x%08x"
+ " imeOptions=0x%08x", inputType, editorInfo.imeOptions));
}
- mIsPasswordField = false;
- mIsSettingsSuggestionStripOn = false;
+ mShouldShowSuggestions = false;
mInputTypeNoAutoCorrect = false;
mApplicationSpecifiedCompletionOn = false;
mShouldInsertSpacesAutomatically = false;
@@ -79,17 +87,15 @@ public final class InputAttributes {
final boolean flagAutoComplete =
0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
- mIsPasswordField = InputTypeUtils.isPasswordInputType(inputType)
- || InputTypeUtils.isVisiblePasswordInputType(inputType);
// TODO: Have a helper method in InputTypeUtils
// Make sure that passwords are not displayed in {@link SuggestionStripView}.
- final boolean noSuggestionStrip = mIsPasswordField
+ final boolean shouldSuppressSuggestions = mIsPasswordField
|| InputTypeUtils.isEmailVariation(variation)
|| InputType.TYPE_TEXT_VARIATION_URI == variation
|| InputType.TYPE_TEXT_VARIATION_FILTER == variation
|| flagNoSuggestions
|| flagAutoComplete;
- mIsSettingsSuggestionStripOn = !noSuggestionStrip;
+ mShouldShowSuggestions = !shouldSuppressSuggestions;
mShouldInsertSpacesAutomatically = InputTypeUtils.isAutoSpaceFriendlyType(inputType);
@@ -113,6 +119,15 @@ public final class InputAttributes {
return editorInfo.inputType == mInputType;
}
+ public boolean hasNoMicrophoneKeyOption() {
+ @SuppressWarnings("deprecation")
+ final boolean deprecatedNoMicrophone = InputAttributes.inPrivateImeOptions(
+ null, NO_MICROPHONE_COMPAT, mEditorInfo);
+ final boolean noMicrophone = InputAttributes.inPrivateImeOptions(
+ mPackageNameForPrivateImeOptions, NO_MICROPHONE, mEditorInfo);
+ return noMicrophone || deprecatedNoMicrophone;
+ }
+
@SuppressWarnings("unused")
private void dumpFlags(final int inputType) {
final int inputClass = inputType & InputType.TYPE_MASK_CLASS;
@@ -215,7 +230,7 @@ public final class InputAttributes {
}
private static String toFlagsString(final int flags) {
- final ArrayList<String> flagsArray = CollectionUtils.newArrayList();
+ final ArrayList<String> flagsArray = new ArrayList<>();
if (0 != (flags & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS))
flagsArray.add("TYPE_TEXT_FLAG_NO_SUGGESTIONS");
if (0 != (flags & InputType.TYPE_TEXT_FLAG_MULTI_LINE))
@@ -243,7 +258,7 @@ public final class InputAttributes {
mInputType,
(mInputTypeNoAutoCorrect ? " noAutoCorrect" : ""),
(mIsPasswordField ? " password" : ""),
- (mIsSettingsSuggestionStripOn ? " suggestionStrip" : ""),
+ (mShouldShowSuggestions ? " shouldShowSuggestions" : ""),
(mApplicationSpecifiedCompletionOn ? " appSpecified" : ""),
(mShouldInsertSpacesAutomatically ? " insertSpaces" : ""),
mTargetApplicationPackageName);
diff --git a/java/src/com/android/inputmethod/latin/InputView.java b/java/src/com/android/inputmethod/latin/InputView.java
index ea7859e60..0801cfa88 100644
--- a/java/src/com/android/inputmethod/latin/InputView.java
+++ b/java/src/com/android/inputmethod/latin/InputView.java
@@ -23,12 +23,14 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.latin.suggestions.MoreSuggestionsView;
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
public final class InputView extends LinearLayout {
private final Rect mInputViewRect = new Rect();
+ private MainKeyboardView mMainKeyboardView;
private KeyboardTopPaddingForwarder mKeyboardTopPaddingForwarder;
private MoreSuggestionsViewCanceler mMoreSuggestionsViewCanceler;
private MotionEventForwarder<?, ?> mActiveForwarder;
@@ -41,12 +43,11 @@ public final class InputView extends LinearLayout {
protected void onFinishInflate() {
final SuggestionStripView suggestionStripView =
(SuggestionStripView)findViewById(R.id.suggestion_strip_view);
- final MainKeyboardView mainKeyboardView =
- (MainKeyboardView)findViewById(R.id.keyboard_view);
+ mMainKeyboardView = (MainKeyboardView)findViewById(R.id.keyboard_view);
mKeyboardTopPaddingForwarder = new KeyboardTopPaddingForwarder(
- mainKeyboardView, suggestionStripView);
+ mMainKeyboardView, suggestionStripView);
mMoreSuggestionsViewCanceler = new MoreSuggestionsViewCanceler(
- mainKeyboardView, suggestionStripView);
+ mMainKeyboardView, suggestionStripView);
}
public void setKeyboardTopPadding(final int keyboardTopPadding) {
@@ -54,6 +55,17 @@ public final class InputView extends LinearLayout {
}
@Override
+ protected boolean dispatchHoverEvent(final MotionEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()
+ && mMainKeyboardView.isShowingMoreKeysPanel()) {
+ // With accessibility mode on, discard hover events while a more keys keyboard is shown.
+ // The {@link MoreKeysKeyboard} receives hover events directly from the platform.
+ return true;
+ }
+ return super.dispatchHoverEvent(event);
+ }
+
+ @Override
public boolean onInterceptTouchEvent(final MotionEvent me) {
final Rect rect = mInputViewRect;
getGlobalVisibleRect(rect);
diff --git a/java/src/com/android/inputmethod/latin/LastComposedWord.java b/java/src/com/android/inputmethod/latin/LastComposedWord.java
index 232bf7407..8cbf8379b 100644
--- a/java/src/com/android/inputmethod/latin/LastComposedWord.java
+++ b/java/src/com/android/inputmethod/latin/LastComposedWord.java
@@ -48,7 +48,7 @@ public final class LastComposedWord {
public final String mTypedWord;
public final CharSequence mCommittedWord;
public final String mSeparatorString;
- public final String mPrevWord;
+ public final PrevWordsInfo mPrevWordsInfo;
public final int mCapitalizedMode;
public final InputPointers mInputPointers =
new InputPointers(Constants.DICTIONARY_MAX_WORD_LENGTH);
@@ -64,16 +64,16 @@ public final class LastComposedWord {
public LastComposedWord(final ArrayList<Event> events,
final InputPointers inputPointers, final String typedWord,
final CharSequence committedWord, final String separatorString,
- final String prevWord, final int capitalizedMode) {
+ final PrevWordsInfo prevWordsInfo, final int capitalizedMode) {
if (inputPointers != null) {
mInputPointers.copy(inputPointers);
}
mTypedWord = typedWord;
- mEvents = new ArrayList<Event>(events);
+ mEvents = new ArrayList<>(events);
mCommittedWord = committedWord;
mSeparatorString = separatorString;
mActive = true;
- mPrevWord = prevWord;
+ mPrevWordsInfo = prevWordsInfo;
mCapitalizedMode = capitalizedMode;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index f1b1b8db2..8b671a94b 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -28,7 +28,6 @@ import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
@@ -38,7 +37,6 @@ import android.net.ConnectivityManager;
import android.os.Debug;
import android.os.IBinder;
import android.os.Message;
-import android.preference.PreferenceManager;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
@@ -55,7 +53,6 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.accessibility.AccessibilityUtils;
-import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.dictionarypack.DictionaryPackConstants;
@@ -84,18 +81,18 @@ import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.DialogUtils;
-import com.android.inputmethod.latin.utils.DistracterFilter;
+import com.android.inputmethod.latin.utils.DistracterFilterCheckingExactMatches;
import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
import com.android.inputmethod.latin.utils.StatsUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
-import com.android.inputmethod.research.ResearchLogger;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
@@ -104,7 +101,7 @@ import java.util.concurrent.TimeUnit;
*/
public class LatinIME extends InputMethodService implements KeyboardActionListener,
SuggestionStripView.Listener, SuggestionStripViewAccessor,
- DictionaryFacilitatorForSuggest.DictionaryInitializationListener,
+ DictionaryFacilitator.DictionaryInitializationListener,
ImportantNoticeDialog.ImportantNoticeDialogListener {
private static final String TAG = LatinIME.class.getSimpleName();
private static final boolean TRACE = false;
@@ -123,12 +120,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final String SCHEME_PACKAGE = "package";
private final Settings mSettings;
+ private final DictionaryFacilitator mDictionaryFacilitator =
+ new DictionaryFacilitator(new DistracterFilterCheckingExactMatches(this /* context */));
private final InputLogic mInputLogic = new InputLogic(this /* LatinIME */,
- this /* SuggestionStripViewAccessor */);
+ this /* SuggestionStripViewAccessor */, mDictionaryFacilitator);
// We expect to have only one decoder in almost all cases, hence the default capacity of 1.
// If it turns out we need several, it will get grown seamlessly.
- final SparseArray<HardwareEventDecoder> mHardwareEventDecoders
- = new SparseArray<HardwareEventDecoder>(1);
+ final SparseArray<HardwareEventDecoder> mHardwareEventDecoders = new SparseArray<>(1);
private View mExtractArea;
private View mKeyPreviewBackingView;
@@ -140,10 +138,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private final SubtypeState mSubtypeState = new SubtypeState();
// Object for reacting to adding/removing a dictionary pack.
- private BroadcastReceiver mDictionaryPackInstallReceiver =
+ private final BroadcastReceiver mDictionaryPackInstallReceiver =
new DictionaryPackInstallBroadcastReceiver(this);
- private BroadcastReceiver mDictionaryDumpBroadcastReceiver =
+ private final BroadcastReceiver mDictionaryDumpBroadcastReceiver =
new DictionaryDumpBroadcastReceiver(this);
private AlertDialog mOptionsDialog;
@@ -168,6 +166,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
private static final int ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT = 2;
private static final int ARG2_UNUSED = 0;
+ private static final int ARG1_FALSE = 0;
+ private static final int ARG1_TRUE = 1;
private int mDelayUpdateSuggestions;
private int mDelayUpdateShiftState;
@@ -215,7 +215,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_RESUME_SUGGESTIONS:
latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor(
latinIme.mSettings.getCurrent(),
- false /* includeResumedWordInSuggestions */);
+ msg.arg1 == ARG1_TRUE /* shouldIncludeResumedWordInSuggestions */);
break;
case MSG_REOPEN_DICTIONARIES:
latinIme.resetSuggest();
@@ -252,16 +252,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sendMessage(obtainMessage(MSG_REOPEN_DICTIONARIES));
}
- public void postResumeSuggestions() {
+ public void postResumeSuggestions(final boolean shouldIncludeResumedWordInSuggestions) {
final LatinIME latinIme = getOwnerInstance();
if (latinIme == null) {
return;
}
- if (!latinIme.mSettings.getCurrent().isSuggestionStripVisible()) {
+ if (!latinIme.mSettings.getCurrent()
+ .isCurrentOrientationAllowingSuggestionsPerUserSettings()) {
return;
}
removeMessages(MSG_RESUME_SUGGESTIONS);
- sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS), mDelayUpdateSuggestions);
+ sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS,
+ shouldIncludeResumedWordInSuggestions ? ARG1_TRUE : ARG1_FALSE,
+ 0 /* ignored */),
+ mDelayUpdateSuggestions);
}
public void postResetCaches(final boolean tryResumeSuggestions, final int remainingTries) {
@@ -481,6 +485,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
KeyboardSwitcher.init(this);
AudioAndHapticFeedbackManager.init(this);
AccessibilityUtils.init(this);
+ StatsUtils.init(this);
super.onCreate();
@@ -491,12 +496,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
loadSettings();
resetSuggest();
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().init(this, mKeyboardSwitcher);
- ResearchLogger.getInstance().initDictionary(
- mInputLogic.mSuggest.mDictionaryFacilitator);
- }
-
// Register to receive ringer mode change and network state change.
// Also receive installation and removal of a dictionary pack.
final IntentFilter filter = new IntentFilter();
@@ -520,7 +519,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
DictionaryDecayBroadcastReciever.setUpIntervalAlarmForDictionaryDecaying(this);
- StatsUtils.onCreateCompleted(this);
+ StatsUtils.onCreate(mSettings.getCurrent());
}
// Has to be package-visible for unit tests
@@ -528,7 +527,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
void loadSettings() {
final Locale locale = mSubtypeSwitcher.getCurrentSubtypeLocale();
final EditorInfo editorInfo = getCurrentInputEditorInfo();
- final InputAttributes inputAttributes = new InputAttributes(editorInfo, isFullscreenMode());
+ final InputAttributes inputAttributes = new InputAttributes(
+ editorInfo, isFullscreenMode(), getPackageName());
mSettings.loadSettings(this, locale, inputAttributes);
final SettingsValues currentSettingsValues = mSettings.getCurrent();
AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(currentSettingsValues);
@@ -538,24 +538,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (!mHandler.hasPendingReopenDictionaries()) {
resetSuggestForLocale(locale);
}
+ mDictionaryFacilitator.updateEnabledSubtypes(mRichImm.getMyEnabledInputMethodSubtypeList(
+ true /* allowsImplicitlySelectedSubtypes */));
refreshPersonalizationDictionarySession();
- }
-
- private DistracterFilter createDistracterFilter() {
- final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
- // TODO: Create Keyboard when mainKeyboardView is null.
- // TODO: Figure out the most reasonable keyboard for the filter. Refer to the
- // spellchecker's logic.
- final Keyboard keyboard = (mainKeyboardView != null) ?
- mainKeyboardView.getKeyboard() : null;
- final DistracterFilter distracterFilter = new DistracterFilter(mInputLogic.mSuggest,
- keyboard);
- return distracterFilter;
+ StatsUtils.onLoadSettings(currentSettingsValues);
}
private void refreshPersonalizationDictionarySession() {
- final DictionaryFacilitatorForSuggest dictionaryFacilitator =
- mInputLogic.mSuggest.mDictionaryFacilitator;
final boolean shouldKeepUserHistoryDictionaries;
final boolean shouldKeepPersonalizationDictionaries;
if (mSettings.getCurrent().mUsePersonalizedDicts) {
@@ -570,16 +559,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (!shouldKeepUserHistoryDictionaries) {
// Remove user history dictionaries.
PersonalizationHelper.removeAllUserHistoryDictionaries(this);
- dictionaryFacilitator.clearUserHistoryDictionary();
+ mDictionaryFacilitator.clearUserHistoryDictionary();
}
if (!shouldKeepPersonalizationDictionaries) {
// Remove personalization dictionaries.
PersonalizationHelper.removeAllPersonalizationDictionaries(this);
PersonalizationDictionarySessionRegistrar.resetAll(this);
} else {
- final DistracterFilter distracterFilter = createDistracterFilter();
- PersonalizationDictionarySessionRegistrar.init(
- this, dictionaryFacilitator, distracterFilter);
+ PersonalizationDictionarySessionRegistrar.init(this, mDictionaryFacilitator);
}
}
@@ -617,13 +604,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
* @param locale the locale
*/
private void resetSuggestForLocale(final Locale locale) {
- final DictionaryFacilitatorForSuggest dictionaryFacilitator =
- mInputLogic.mSuggest.mDictionaryFacilitator;
final SettingsValues settingsValues = mSettings.getCurrent();
- dictionaryFacilitator.resetDictionaries(this /* context */, locale,
+ mDictionaryFacilitator.resetDictionaries(this /* context */, locale,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */, this);
- if (settingsValues.mCorrectionEnabled) {
+ if (settingsValues.mAutoCorrectionEnabled) {
mInputLogic.mSuggest.setAutoCorrectionThreshold(
settingsValues.mAutoCorrectionThreshold);
}
@@ -633,27 +618,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
* Reset suggest by loading the main dictionary of the current locale.
*/
/* package private */ void resetSuggestMainDict() {
- final DictionaryFacilitatorForSuggest dictionaryFacilitator =
- mInputLogic.mSuggest.mDictionaryFacilitator;
final SettingsValues settingsValues = mSettings.getCurrent();
- dictionaryFacilitator.resetDictionaries(this /* context */,
- dictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict,
+ mDictionaryFacilitator.resetDictionaries(this /* context */,
+ mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict,
settingsValues.mUsePersonalizedDicts, true /* forceReloadMainDictionary */, this);
}
@Override
public void onDestroy() {
- mInputLogic.mSuggest.mDictionaryFacilitator.closeDictionaries();
+ mDictionaryFacilitator.closeDictionaries();
mSettings.onDestroy();
unregisterReceiver(mConnectivityAndRingerModeChangeReceiver);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().onDestroy();
- }
unregisterReceiver(mDictionaryPackInstallReceiver);
unregisterReceiver(mDictionaryDumpBroadcastReceiver);
PersonalizationDictionarySessionRegistrar.close(this);
- LatinImeLogger.commit();
- LatinImeLogger.onDestroy();
StatsUtils.onDestroy();
super.onDestroy();
}
@@ -668,18 +646,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onConfigurationChanged(final Configuration conf) {
- // If orientation changed while predicting, commit the change
final SettingsValues settingsValues = mSettings.getCurrent();
if (settingsValues.mDisplayOrientation != conf.orientation) {
mHandler.startOrientationChanging();
- mInputLogic.mConnection.beginBatchEdit();
- mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
- mInputLogic.mConnection.finishComposingText();
- mInputLogic.mConnection.endBatchEdit();
+ // If !isComposingWord, #commitTyped() is a no-op, but still, it's better to avoid
+ // the useless IPC of {begin,end}BatchEdit.
+ if (mInputLogic.mWordComposer.isComposingWord()) {
+ mInputLogic.mConnection.beginBatchEdit();
+ // If we had a composition in progress, we need to commit the word so that the
+ // suggestionsSpan will be added. This will allow resuming on the same suggestions
+ // after rotation is finished.
+ mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
+ mInputLogic.mConnection.endBatchEdit();
+ }
}
- final DistracterFilter distracterFilter = createDistracterFilter();
PersonalizationDictionarySessionRegistrar.onConfigurationChanged(this, conf,
- mInputLogic.mSuggest.mDictionaryFacilitator, distracterFilter);
+ mDictionaryFacilitator);
super.onConfigurationChanged(conf);
}
@@ -698,9 +680,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (hasSuggestionStripView()) {
mSuggestionStripView.setListener(this, view);
}
- if (LatinImeLogger.sVISUALDEBUG) {
- mKeyPreviewBackingView.setBackgroundColor(0x10FF0000);
- }
}
@Override
@@ -734,6 +713,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
// is not guaranteed. It may even be called at the same time on a different thread.
mSubtypeSwitcher.onSubtypeChanged(subtype);
+ mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype));
loadKeyboard();
}
@@ -772,10 +752,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
Log.i(TAG, "Starting input. Cursor position = "
+ editorInfo.initialSelStart + "," + editorInfo.initialSelEnd);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- ResearchLogger.latinIME_onStartInputViewInternal(editorInfo, prefs);
- }
+ // TODO: Consolidate these checks with {@link InputAttributes}.
if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) {
Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions);
Log.w(TAG, "Use " + getPackageName() + "." + NO_MICROPHONE + " instead");
@@ -785,7 +762,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead");
}
- LatinImeLogger.onStartInputView(editorInfo);
// In landscape mode, this method gets called without the input view being created.
if (mainKeyboardView == null) {
return;
@@ -809,7 +785,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// The app calling setText() has the effect of clearing the composing
// span, so we should reset our state unconditionally, even if restarting is true.
- mInputLogic.startInput(restarting, editorInfo);
+ // We also tell the input logic about the combining rules for the current subtype, so
+ // it can adjust its combiners if needed.
+ mInputLogic.startInput(restarting, editorInfo,
+ mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype());
// Note: the following does a round-trip IPC on the main thread: be careful
final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
@@ -835,7 +814,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best
// effort to work around this bug.
mInputLogic.mConnection.tryFixLyingCursorPosition();
- mHandler.postResumeSuggestions();
+ mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */);
canReachInputConnection = true;
}
@@ -847,8 +826,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mainKeyboardView.closing();
currentSettingsValues = mSettings.getCurrent();
- if (currentSettingsValues.mCorrectionEnabled) {
- suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold);
+ if (currentSettingsValues.mAutoCorrectionEnabled) {
+ suggest.setAutoCorrectionThreshold(
+ currentSettingsValues.mAutoCorrectionThreshold);
}
switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(),
@@ -877,7 +857,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.cancelUpdateSuggestionStrip();
mainKeyboardView.setMainDictionaryAvailability(
- suggest.mDictionaryFacilitator.hasInitializedMainDictionary());
+ mDictionaryFacilitator.hasInitializedMainDictionary());
mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn,
currentSettingsValues.mKeyPreviewPopupDismissDelay);
mainKeyboardView.setSlidingKeyInputPreviewEnabled(
@@ -902,7 +882,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void onFinishInputInternal() {
super.onFinishInput();
- LatinImeLogger.commit();
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.closing();
@@ -911,16 +890,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void onFinishInputViewInternal(final boolean finishingInput) {
super.onFinishInputView(finishingInput);
- mKeyboardSwitcher.onFinishInputView();
mKeyboardSwitcher.deallocateMemory();
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestionStrip();
// Should do the following in onFinishInputInternal but until JB MR2 it's not called :(
mInputLogic.finishInput();
- // Notify ResearchLogger
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onFinishInputViewInternal(finishingInput);
- }
}
@Override
@@ -934,11 +908,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
+ ", nss=" + newSelStart + ", nse=" + newSelEnd
+ ", cs=" + composingSpanStart + ", ce=" + composingSpanEnd);
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onUpdateSelection(oldSelStart, oldSelEnd,
- oldSelStart, oldSelEnd, newSelStart, newSelEnd, composingSpanStart,
- composingSpanEnd, mInputLogic.mConnection);
- }
// If the keyboard is not visible, we don't need to do all the housekeeping work, as it
// will be reset when the keyboard shows up anyway.
@@ -999,13 +968,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void hideWindow() {
- LatinImeLogger.commit();
mKeyboardSwitcher.onHideWindow();
- if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
- AccessibleKeyboardViewProxy.getInstance().onHideWindow();
- }
-
if (TRACE) Debug.stopMethodTracing();
if (isShowingOptionDialog()) {
mOptionsDialog.dismiss();
@@ -1029,9 +993,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
if (applicationSpecifiedCompletions == null) {
setNeutralSuggestionStrip();
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onDisplayCompletions(null);
- }
return;
}
@@ -1042,10 +1003,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
null /* rawSuggestions */, false /* typedWordValid */, false /* willAutoCorrect */,
false /* isObsoleteSuggestions */, false /* isPrediction */);
// When in fullscreen mode, show completions generated by the application forcibly
- setSuggestedWords(suggestedWords, true /* isSuggestionStripVisible */);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
- }
+ setSuggestedWords(suggestedWords);
}
private int getAdjustedBackingViewHeight() {
@@ -1179,7 +1137,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
wordToEdit = word;
}
- mInputLogic.mSuggest.mDictionaryFacilitator.addWordToUserDictionary(wordToEdit);
+ mDictionaryFacilitator.addWordToUserDictionary(this /* context */, wordToEdit);
}
// Callback for the {@link SuggestionStripView}, to call when the important notice strip is
@@ -1348,30 +1306,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Nothing to do so far.
}
- private boolean isSuggestionStripVisible() {
- if (!hasSuggestionStripView()) {
- return false;
- }
- if (mSuggestionStripView.isShowingAddToDictionaryHint()) {
- return true;
- }
- final SettingsValues currentSettings = mSettings.getCurrent();
- if (null == currentSettings) {
- return false;
- }
- if (ImportantNoticeUtils.shouldShowImportantNotice(this,
- currentSettings.mInputAttributes)) {
- return true;
- }
- if (!currentSettings.isSuggestionStripVisible()) {
- return false;
- }
- if (currentSettings.isApplicationSpecifiedCompletionsOn()) {
- return true;
- }
- return currentSettings.isSuggestionsRequested();
- }
-
public boolean hasSuggestionStripView() {
return null != mSuggestionStripView;
}
@@ -1389,34 +1323,49 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSuggestionStripView.dismissAddToDictionaryHint();
}
- // TODO[IL]: Define a clear interface for this
- public void setSuggestedWords(final SuggestedWords suggestedWords,
- final boolean isSuggestionStripVisible) {
+ private void setSuggestedWords(final SuggestedWords suggestedWords) {
mInputLogic.setSuggestedWords(suggestedWords);
// TODO: Modify this when we support suggestions with hard keyboard
if (!hasSuggestionStripView()) {
return;
}
- mKeyboardSwitcher.onAutoCorrectionStateChanged(suggestedWords.mWillAutoCorrect);
if (!onEvaluateInputViewShown()) {
return;
}
- if (!isSuggestionStripVisible) {
- mSuggestionStripView.setVisibility(isFullscreenMode() ? View.GONE : View.INVISIBLE);
+
+ final SettingsValues currentSettingsValues = mSettings.getCurrent();
+ final boolean shouldShowImportantNotice =
+ ImportantNoticeUtils.shouldShowImportantNotice(this);
+ final boolean shouldShowSuggestionCandidates =
+ currentSettingsValues.mInputAttributes.mShouldShowSuggestions
+ && currentSettingsValues.isCurrentOrientationAllowingSuggestionsPerUserSettings();
+ final boolean shouldShowSuggestionsStripUnlessPassword = shouldShowImportantNotice
+ || currentSettingsValues.mShowsVoiceInputKey
+ || shouldShowSuggestionCandidates
+ || currentSettingsValues.isApplicationSpecifiedCompletionsOn();
+ final boolean shouldShowSuggestionsStrip = shouldShowSuggestionsStripUnlessPassword
+ && !currentSettingsValues.mInputAttributes.mIsPasswordField;
+ mSuggestionStripView.updateVisibility(shouldShowSuggestionsStrip, isFullscreenMode());
+ if (!shouldShowSuggestionsStrip) {
return;
}
- mSuggestionStripView.setVisibility(View.VISIBLE);
- final SettingsValues currentSettings = mSettings.getCurrent();
- final boolean showSuggestions;
- if (SuggestedWords.EMPTY == suggestedWords || suggestedWords.isPunctuationSuggestions()
- || !currentSettings.isSuggestionsRequested()) {
- showSuggestions = !mSuggestionStripView.maybeShowImportantNoticeTitle(
- currentSettings.mInputAttributes);
- } else {
- showSuggestions = true;
+ final boolean isEmptyApplicationSpecifiedCompletions =
+ currentSettingsValues.isApplicationSpecifiedCompletionsOn()
+ && suggestedWords.isEmpty();
+ final boolean noSuggestionsToShow = (SuggestedWords.EMPTY == suggestedWords)
+ || suggestedWords.isPunctuationSuggestions()
+ || isEmptyApplicationSpecifiedCompletions;
+ if (shouldShowImportantNotice && noSuggestionsToShow) {
+ if (mSuggestionStripView.maybeShowImportantNoticeTitle()) {
+ return;
+ }
}
- if (showSuggestions) {
+
+ if (currentSettingsValues.isCurrentOrientationAllowingSuggestionsPerUserSettings()
+ // We should clear suggestions if there is no suggestion to show.
+ || noSuggestionsToShow
+ || currentSettingsValues.isApplicationSpecifiedCompletionsOn()) {
mSuggestionStripView.setSuggestions(suggestedWords,
SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype()));
}
@@ -1430,35 +1379,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
callback.onGetSuggestedWords(SuggestedWords.EMPTY);
return;
}
- // Get the word on which we should search the bigrams. If we are composing a word, it's
- // whatever is *before* the half-committed word in the buffer, hence 2; if we aren't, we
- // should just skip whitespace if any, so 1.
final SettingsValues currentSettings = mSettings.getCurrent();
final int[] additionalFeaturesOptions = currentSettings.mAdditionalFeaturesSettingValues;
-
- if (DEBUG) {
- if (mInputLogic.mWordComposer.isComposingWord()
- || mInputLogic.mWordComposer.isBatchMode()) {
- final String previousWord
- = mInputLogic.mWordComposer.getPreviousWordForSuggestion();
- // TODO: this is for checking consistency with older versions. Remove this when
- // we are confident this is stable.
- // We're checking the previous word in the text field against the memorized previous
- // word. If we are composing a word we should have the second word before the cursor
- // memorized, otherwise we should have the first.
- final CharSequence rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion(
- currentSettings.mSpacingAndPunctuations,
- mInputLogic.mWordComposer.isComposingWord() ? 2 : 1);
- if (!TextUtils.equals(previousWord, rereadPrevWord)) {
- throw new RuntimeException("Unexpected previous word: "
- + previousWord + " <> " + rereadPrevWord);
- }
- }
- }
mInputLogic.mSuggest.getSuggestedWords(mInputLogic.mWordComposer,
- mInputLogic.mWordComposer.getPreviousWordForSuggestion(),
+ mInputLogic.getPrevWordsInfoFromNthPreviousWordForSuggestion(
+ currentSettings.mSpacingAndPunctuations,
+ // Get the word on which we should search the bigrams. If we are composing
+ // a word, it's whatever is *before* the half-committed word in the buffer,
+ // hence 2; if we aren't, we should just skip whitespace if any, so 1.
+ mInputLogic.mWordComposer.isComposingWord() ? 2 : 1),
keyboard.getProximityInfo(), currentSettings.mBlockPotentiallyOffensive,
- currentSettings.mCorrectionEnabled, additionalFeaturesOptions, sessionId,
+ currentSettings.mAutoCorrectionEnabled, additionalFeaturesOptions, sessionId,
sequenceNumber, callback);
}
@@ -1478,7 +1409,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setNeutralSuggestionStrip();
} else {
mInputLogic.mWordComposer.setAutoCorrection(autoCorrection);
- setSuggestedWords(suggestedWords, isSuggestionStripVisible());
+ setSuggestedWords(suggestedWords);
}
// Cache the auto-correction in accessibility code so we can speak it if the user
// touches a key that will insert it.
@@ -1511,7 +1442,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final SettingsValues currentSettings = mSettings.getCurrent();
final SuggestedWords neutralSuggestions = currentSettings.mBigramPredictionEnabled
? SuggestedWords.EMPTY : currentSettings.mSpacingAndPunctuations.mSuggestPuncList;
- setSuggestedWords(neutralSuggestions, isSuggestionStripVisible());
+ setSuggestedWords(neutralSuggestions);
}
// TODO: Make this private
@@ -1596,18 +1527,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void onReleaseKey(final int primaryCode, final boolean withSliding) {
mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding, getCurrentAutoCapsState(),
getCurrentRecapitalizeState());
-
- // If accessibility is on, ensure the user receives keyboard state updates.
- if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- switch (primaryCode) {
- case Constants.CODE_SHIFT:
- AccessibleKeyboardViewProxy.getInstance().notifyShiftState();
- break;
- case Constants.CODE_SWITCH_ALPHA_SYMBOL:
- AccessibleKeyboardViewProxy.getInstance().notifySymbolsState();
- break;
- }
- }
}
private HardwareEventDecoder getHardwareKeyEventDecoder(final int deviceId) {
@@ -1652,7 +1571,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event);
// receive ringer mode change and network state change.
- private BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mConnectivityAndRingerModeChangeReceiver =
+ new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
@@ -1747,15 +1667,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@UsedForTesting
/* package for test */ void waitForLoadingDictionaries(final long timeout, final TimeUnit unit)
throws InterruptedException {
- mInputLogic.mSuggest.mDictionaryFacilitator.waitForLoadingDictionariesForTesting(
- timeout, unit);
+ mDictionaryFacilitator.waitForLoadingDictionariesForTesting(timeout, unit);
}
// DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly.
@UsedForTesting
/* package for test */ void replaceDictionariesForTest(final Locale locale) {
final SettingsValues settingsValues = mSettings.getCurrent();
- mInputLogic.mSuggest.mDictionaryFacilitator.resetDictionaries(this, locale,
+ mDictionaryFacilitator.resetDictionaries(this, locale,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */, this /* listener */);
}
@@ -1763,17 +1682,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// DO NOT USE THIS for any other purpose than testing.
@UsedForTesting
/* package for test */ void clearPersonalizedDictionariesForTest() {
- mInputLogic.mSuggest.mDictionaryFacilitator.clearUserHistoryDictionary();
- mInputLogic.mSuggest.mDictionaryFacilitator.clearPersonalizationDictionary();
+ mDictionaryFacilitator.clearUserHistoryDictionary();
+ mDictionaryFacilitator.clearPersonalizationDictionary();
+ }
+
+ @UsedForTesting
+ /* package for test */ List<InputMethodSubtype> getEnabledSubtypesForTest() {
+ return (mRichImm != null) ? mRichImm.getMyEnabledInputMethodSubtypeList(
+ true /* allowsImplicitlySelectedSubtypes */) : new ArrayList<InputMethodSubtype>();
}
public void dumpDictionaryForDebug(final String dictName) {
- final DictionaryFacilitatorForSuggest dictionaryFacilitator =
- mInputLogic.mSuggest.mDictionaryFacilitator;
- if (dictionaryFacilitator.getLocale() == null) {
+ if (mDictionaryFacilitator.getLocale() == null) {
resetSuggest();
}
- mInputLogic.mSuggest.mDictionaryFacilitator.dumpDictionaryForDebug(dictName);
+ mDictionaryFacilitator.dumpDictionaryForDebug(dictName);
}
public void debugDumpStateAndCrashWithException(final String context) {
diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
index 3f2b0a3f4..8fd36b937 100644
--- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java
+++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java
@@ -16,76 +16,12 @@
package com.android.inputmethod.latin;
-import android.content.SharedPreferences;
-import android.view.inputmethod.EditorInfo;
+import android.content.Context;
-import com.android.inputmethod.keyboard.Keyboard;
+// TODO: Rename this class name to make it more relevant.
+public final class LatinImeLogger {
+ public static final boolean sDBG = false;
-public final class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener {
-
- public static boolean sDBG = false;
- public static boolean sVISUALDEBUG = false;
- public static boolean sUsabilityStudy = false;
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- }
-
- public static void init(LatinIME context) {
- }
-
- public static void commit() {
- }
-
- public static boolean getUsabilityStudyMode(final SharedPreferences prefs) {
- return false;
- }
-
- public static void onDestroy() {
- }
-
- public static void logOnManualSuggestion(
- String before, String after, int position, SuggestedWords suggestedWords) {
- }
-
- public static void logOnAutoCorrectionForTyping(
- String before, String after, int separatorCode) {
- }
-
- public static void logOnAutoCorrectionForGeometric(String before, String after,
- int separatorCode, InputPointers inputPointers) {
- }
-
- public static void logOnAutoCorrectionCancelled() {
- }
-
- public static void logOnDelete(int x, int y) {
- }
-
- public static void logOnInputChar() {
- }
-
- public static void logOnInputSeparator() {
- }
-
- public static void logOnException(String metaData, Throwable e) {
- }
-
- public static void logOnWarning(String warning) {
- }
-
- public static void onStartInputView(EditorInfo editorInfo) {
- }
-
- public static void onStartSuggestion(CharSequence previousWords) {
- }
-
- public static void onAddSuggestedWord(String word, String sourceDictionaryId) {
- }
-
- public static void onSetKeyboard(Keyboard kb) {
- }
-
- public static void onPrintAllUsabilityStudyLogs() {
+ public static void init(Context context) {
}
}
diff --git a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java
new file mode 100644
index 000000000..42b311c69
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin;
+
+/**
+ * Class to represent information of previous words. This class is used to add n-gram entries
+ * into binary dictionaries, to get predictions, and to get suggestions.
+ */
+// TODO: Support multiple previous words for n-gram.
+public class PrevWordsInfo {
+ public static final PrevWordsInfo EMPTY_PREV_WORDS_INFO = new PrevWordsInfo(null);
+ public static final PrevWordsInfo BEGINNING_OF_SENTENCE = new PrevWordsInfo();
+
+ // The word immediately before the considered word. null means we don't have any context
+ // including the "beginning of sentence context" - we just don't know what to predict.
+ // An example of that is after a comma.
+ // For simplicity of implementation, this may also be null transiently after the WordComposer
+ // was reset and before starting a new composing word, but we should never be calling
+ // getSuggetions* in this situation.
+ // This is an empty string when mIsBeginningOfSentence is true.
+ public final String mPrevWord;
+
+ // TODO: Have sentence separator.
+ // Whether the current context is beginning of sentence or not. This is true when composing at
+ // the beginning of an input field or composing a word after a sentence separator.
+ public final boolean mIsBeginningOfSentence;
+
+ // Beginning of sentence.
+ public PrevWordsInfo() {
+ mPrevWord = "";
+ mIsBeginningOfSentence = true;
+ }
+
+ public PrevWordsInfo(final String prevWord) {
+ mPrevWord = prevWord;
+ mIsBeginningOfSentence = false;
+ }
+
+ public boolean isValid() {
+ return mPrevWord != null;
+ }
+
+ @Override
+ public String toString() {
+ return "PrevWord: " + mPrevWord + ", isBeginningOfSentence: "
+ + mIsBeginningOfSentence + ".";
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
index 4911bcdf6..0fba37c8a 100644
--- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
@@ -17,8 +17,6 @@
package com.android.inputmethod.latin;
import com.android.inputmethod.keyboard.internal.KeySpecParser;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayList;
@@ -49,7 +47,7 @@ public final class PunctuationSuggestions extends SuggestedWords {
*/
public static PunctuationSuggestions newPunctuationSuggestions(
final String[] punctuationSpecs) {
- final ArrayList<SuggestedWordInfo> puncuationsList = CollectionUtils.newArrayList();
+ final ArrayList<SuggestedWordInfo> puncuationsList = new ArrayList<>();
for (final String puncSpec : punctuationSpecs) {
puncuationsList.add(newHardCodedWordInfo(puncSpec));
}
diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
index 9f61d6c37..e59ef7563 100644
--- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java
@@ -50,22 +50,14 @@ public final class ReadOnlyBinaryDictionary extends Dictionary {
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
- return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords,
- additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight);
- }
-
- @Override
- public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final float[] inOutLanguageWeight) {
if (mLock.readLock().tryLock()) {
try {
- return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo,
- blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight);
+ return mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, sessionId,
+ inOutLanguageWeight);
} finally {
mLock.readLock().unlock();
}
@@ -74,10 +66,10 @@ public final class ReadOnlyBinaryDictionary extends Dictionary {
}
@Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
if (mLock.readLock().tryLock()) {
try {
- return mBinaryDictionary.isValidWord(word);
+ return mBinaryDictionary.isInDictionary(word);
} finally {
mLock.readLock().unlock();
}
@@ -110,6 +102,18 @@ public final class ReadOnlyBinaryDictionary extends Dictionary {
}
@Override
+ public int getMaxFrequencyOfExactMatches(final String word) {
+ if (mLock.readLock().tryLock()) {
+ try {
+ return mBinaryDictionary.getMaxFrequencyOfExactMatches(word);
+ } finally {
+ mLock.readLock().unlock();
+ }
+ }
+ return NOT_A_PROBABILITY;
+ }
+
+ @Override
public void close() {
mLock.writeLock().lock();
try {
diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java
index 606bb775e..96476b2ee 100644
--- a/java/src/com/android/inputmethod/latin/RichInputConnection.java
+++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java
@@ -26,14 +26,12 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.CapsModeUtils;
import com.android.inputmethod.latin.utils.DebugLogUtils;
import com.android.inputmethod.latin.utils.SpannableStringUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.latin.utils.TextRange;
-import com.android.inputmethod.research.ResearchLogger;
import java.util.Arrays;
import java.util.regex.Pattern;
@@ -174,9 +172,6 @@ public final class RichInputConnection {
}
if (null != mIC && shouldFinishComposition) {
mIC.finishComposingText();
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_finishComposingText();
- }
}
return true;
}
@@ -223,9 +218,6 @@ public final class RichInputConnection {
mComposingText.setLength(0);
if (null != mIC) {
mIC.finishComposingText();
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_finishComposingText();
- }
}
}
@@ -363,9 +355,6 @@ public final class RichInputConnection {
}
if (null != mIC) {
mIC.deleteSurroundingText(beforeLength, afterLength);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_deleteSurroundingText(beforeLength, afterLength);
- }
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
@@ -374,9 +363,6 @@ public final class RichInputConnection {
mIC = mParent.getCurrentInputConnection();
if (null != mIC) {
mIC.performEditorAction(actionId);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_performEditorAction(actionId);
- }
}
}
@@ -429,9 +415,6 @@ public final class RichInputConnection {
}
if (null != mIC) {
mIC.sendKeyEvent(keyEvent);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_sendKeyEvent(keyEvent);
- }
}
}
@@ -469,9 +452,6 @@ public final class RichInputConnection {
// newCursorPosition != 1.
if (null != mIC) {
mIC.setComposingText(text, newCursorPosition);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_setComposingText(text, newCursorPosition);
- }
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
@@ -500,9 +480,6 @@ public final class RichInputConnection {
if (!isIcValid) {
return false;
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_setSelection(start, end);
- }
}
return reloadTextCache();
}
@@ -530,18 +507,17 @@ public final class RichInputConnection {
mComposingText.setLength(0);
if (null != mIC) {
mIC.commitCompletion(completionInfo);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_commitCompletion(completionInfo);
- }
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
@SuppressWarnings("unused")
- public String getNthPreviousWord(final SpacingAndPunctuations spacingAndPunctuations,
- final int n) {
+ public PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(
+ final SpacingAndPunctuations spacingAndPunctuations, final int n) {
mIC = mParent.getCurrentInputConnection();
- if (null == mIC) return null;
+ if (null == mIC) {
+ return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
+ }
final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
if (DEBUG_PREVIOUS_TEXT && null != prev) {
final int checkLength = LOOKBACK_CHARACTER_NUM - 1;
@@ -561,46 +537,73 @@ public final class RichInputConnection {
}
}
}
- return getNthPreviousWord(prev, spacingAndPunctuations, n);
+ return getPrevWordsInfoFromNthPreviousWord(prev, spacingAndPunctuations, n);
}
private static boolean isSeparator(final int code, final int[] sortedSeparators) {
return Arrays.binarySearch(sortedSeparators, code) >= 0;
}
- // Get the nth word before cursor. n = 1 retrieves the word immediately before the cursor,
- // n = 2 retrieves the word before that, and so on. This splits on whitespace only.
+ // Get information of the nth word before cursor. n = 1 retrieves the word immediately before
+ // the cursor, n = 2 retrieves the word before that, and so on. This splits on whitespace only.
// Also, it won't return words that end in a separator (if the nth word before the cursor
- // ends in a separator, it returns null).
+ // ends in a separator, it returns information representing beginning-of-sentence).
// Example :
// (n = 1) "abc def|" -> def
// (n = 1) "abc def |" -> def
- // (n = 1) "abc def. |" -> null
- // (n = 1) "abc def . |" -> null
+ // (n = 1) "abc 'def|" -> 'def
+ // (n = 1) "abc def. |" -> beginning-of-sentence
+ // (n = 1) "abc def . |" -> beginning-of-sentence
// (n = 2) "abc def|" -> abc
// (n = 2) "abc def |" -> abc
+ // (n = 2) "abc 'def|" -> empty. The context is different from "abc def", but we cannot
+ // represent this situation using PrevWordsInfo. See TODO in the method.
// (n = 2) "abc def. |" -> abc
// (n = 2) "abc def . |" -> def
- // (n = 2) "abc|" -> null
- // (n = 2) "abc |" -> null
- // (n = 2) "abc. def|" -> null
- public static String getNthPreviousWord(final CharSequence prev,
+ // (n = 2) "abc|" -> beginning-of-sentence
+ // (n = 2) "abc |" -> beginning-of-sentence
+ // (n = 2) "abc. def|" -> beginning-of-sentence
+ public static PrevWordsInfo getPrevWordsInfoFromNthPreviousWord(final CharSequence prev,
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
- if (prev == null) return null;
+ if (prev == null) return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
final String[] w = spaceRegex.split(prev);
- // If we can't find n words, or we found an empty word, return null.
- if (w.length < n) return null;
+ // Referring to the word after the nth word.
+ if ((n - 1) > 0 && (n - 1) <= w.length) {
+ final String wordFollowingTheNthPrevWord = w[w.length - n + 1];
+ if (!wordFollowingTheNthPrevWord.isEmpty()) {
+ final char firstChar = wordFollowingTheNthPrevWord.charAt(0);
+ if (spacingAndPunctuations.isWordConnector(firstChar)) {
+ // The word following the n-th prev word is starting with a word connector.
+ // TODO: Return meaningful context for this case.
+ return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
+ }
+ }
+ }
+
+ // If we can't find n words, or we found an empty word, the context is
+ // beginning-of-sentence.
+ if (w.length < n) {
+ return PrevWordsInfo.BEGINNING_OF_SENTENCE;
+ }
final String nthPrevWord = w[w.length - n];
final int length = nthPrevWord.length();
- if (length <= 0) return null;
+ if (length <= 0) {
+ return PrevWordsInfo.BEGINNING_OF_SENTENCE;
+ }
- // If ends in a separator, return null
+ // If ends in a sentence separator, the context is beginning-of-sentence.
final char lastChar = nthPrevWord.charAt(length - 1);
+ if (spacingAndPunctuations.isSentenceSeparator(lastChar)) {
+ return PrevWordsInfo.BEGINNING_OF_SENTENCE;
+ }
+ // If ends in a word separator or connector, the context is unclear.
+ // TODO: Return meaningful context for this case.
if (spacingAndPunctuations.isWordSeparator(lastChar)
- || spacingAndPunctuations.isWordConnector(lastChar)) return null;
-
- return nthPrevWord;
+ || spacingAndPunctuations.isWordConnector(lastChar)) {
+ return PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
+ }
+ return new PrevWordsInfo(nthPrevWord);
}
/**
@@ -752,9 +755,6 @@ public final class RichInputConnection {
deleteSurroundingText(2, 0);
final String singleSpace = " ";
commitText(singleSpace, 1);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_revertDoubleSpacePeriod();
- }
return true;
}
@@ -777,9 +777,6 @@ public final class RichInputConnection {
deleteSurroundingText(2, 0);
final String text = " " + textBeforeCursor.subSequence(0, 1);
commitText(text, 1);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.richInputConnection_revertSwapPunctuation();
- }
return true;
}
@@ -894,4 +891,8 @@ public final class RichInputConnection {
public boolean hasSelection() {
return mExpectedSelEnd != mExpectedSelStart;
}
+
+ public boolean isCursorPositionKnown() {
+ return INVALID_CURSOR_POSITION != mExpectedSelStart;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 2b0be545e..7758ac78e 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -31,7 +31,6 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.util.Collections;
@@ -53,9 +52,9 @@ public final class RichInputMethodManager {
private InputMethodManagerCompatWrapper mImmWrapper;
private InputMethodInfoCache mInputMethodInfoCache;
final HashMap<InputMethodInfo, List<InputMethodSubtype>>
- mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap();
+ mSubtypeListCacheWithImplicitlySelectedSubtypes = new HashMap<>();
final HashMap<InputMethodInfo, List<InputMethodSubtype>>
- mSubtypeListCacheWithoutImplicitlySelectedSubtypes = CollectionUtils.newHashMap();
+ mSubtypeListCacheWithoutImplicitlySelectedSubtypes = new HashMap<>();
private static final int INDEX_NOT_FOUND = -1;
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 021133945..a3d09565c 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -52,7 +52,6 @@ public final class SubtypeSwitcher {
private /* final */ RichInputMethodManager mRichImm;
private /* final */ Resources mResources;
- private /* final */ ConnectivityManager mConnectivityManager;
private final LanguageOnSpacebarHelper mLanguageOnSpacebarHelper =
new LanguageOnSpacebarHelper();
@@ -111,10 +110,10 @@ public final class SubtypeSwitcher {
}
mResources = context.getResources();
mRichImm = RichInputMethodManager.getInstance();
- mConnectivityManager = (ConnectivityManager) context.getSystemService(
+ ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(
Context.CONNECTIVITY_SERVICE);
- final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
+ final NetworkInfo info = connectivityManager.getActiveNetworkInfo();
mIsNetworkConnected = (info != null && info.isConnected());
onSubtypeChanged(getCurrentSubtype());
@@ -256,8 +255,7 @@ public final class SubtypeSwitcher {
public boolean isSystemLocaleSameAsLocaleOfAllEnabledSubtypesOfEnabledImes() {
final Locale systemLocale = mResources.getConfiguration().locale;
- final Set<InputMethodSubtype> enabledSubtypesOfEnabledImes =
- new HashSet<InputMethodSubtype>();
+ final Set<InputMethodSubtype> enabledSubtypesOfEnabledImes = new HashSet<>();
final InputMethodManager inputMethodManager = mRichImm.getInputMethodManager();
final List<InputMethodInfo> enabledInputMethodInfoList =
inputMethodManager.getEnabledInputMethodList();
@@ -327,4 +325,8 @@ public final class SubtypeSwitcher {
+ DUMMY_EMOJI_SUBTYPE);
return DUMMY_EMOJI_SUBTYPE;
}
+
+ public String getCombiningRulesExtraValueOfCurrentSubtype() {
+ return SubtypeLocaleUtils.getCombiningRulesExtraValue(getCurrentSubtype());
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index db0a8a81c..1ba5d5ea6 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -18,13 +18,11 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
-import com.android.inputmethod.event.Event;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.latin.utils.SuggestionResults;
@@ -53,11 +51,14 @@ public final class Suggest {
private static final int SUPPRESS_SUGGEST_THRESHOLD = -2000000000;
private static final boolean DBG = LatinImeLogger.sDBG;
- public final DictionaryFacilitatorForSuggest mDictionaryFacilitator =
- new DictionaryFacilitatorForSuggest();
+ private final DictionaryFacilitator mDictionaryFacilitator;
private float mAutoCorrectionThreshold;
+ public Suggest(final DictionaryFacilitator dictionaryFacilitator) {
+ mDictionaryFacilitator = dictionaryFacilitator;
+ }
+
public Locale getLocale() {
return mDictionaryFacilitator.getLocale();
}
@@ -71,17 +72,16 @@ public final class Suggest {
}
public void getSuggestedWords(final WordComposer wordComposer,
- final String prevWordForBigram, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
final int[] additionalFeaturesOptions, final int sessionId, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
- LatinImeLogger.onStartSuggestion(prevWordForBigram);
if (wordComposer.isBatchMode()) {
- getSuggestedWordsForBatchInput(wordComposer, prevWordForBigram, proximityInfo,
+ getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo,
blockOffensiveWords, additionalFeaturesOptions, sessionId, sequenceNumber,
callback);
} else {
- getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo,
+ getSuggestedWordsForTypingInput(wordComposer, prevWordsInfo, proximityInfo,
blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions,
sequenceNumber, callback);
}
@@ -90,29 +90,31 @@ public final class Suggest {
// Retrieves suggestions for the typing input
// and calls the callback function with the suggestions.
private void getSuggestedWordsForTypingInput(final WordComposer wordComposer,
- final String prevWordForBigram, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
final int[] additionalFeaturesOptions, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
- final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
final String typedWord = wordComposer.getTypedWord();
+ final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWord);
final String consideredWord = trailingSingleQuotesCount > 0
? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount)
: typedWord;
- LatinImeLogger.onAddSuggestedWord(typedWord, Dictionary.TYPE_USER_TYPED);
final ArrayList<SuggestedWordInfo> rawSuggestions;
if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) {
- rawSuggestions = CollectionUtils.newArrayList();
+ rawSuggestions = new ArrayList<>();
} else {
rawSuggestions = null;
}
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
- wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords,
+ wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords,
additionalFeaturesOptions, SESSION_TYPING, rawSuggestions);
- final boolean isFirstCharCapitalized = wordComposer.isFirstCharCapitalized();
- final boolean isAllUpperCase = wordComposer.isAllUpperCase();
+ final boolean isOnlyFirstCharCapitalized = wordComposer.isOnlyFirstCharCapitalized();
+ // If resumed, then we don't want to upcase everything: resuming on a fully-capitalized
+ // words is rarely done to switch to another fully-capitalized word, but usually to a
+ // normal, non-capitalized suggestion.
+ final boolean isAllUpperCase = wordComposer.isAllUpperCase() && !wordComposer.isResumed();
final String firstSuggestion;
final String whitelistedWord;
if (suggestionResults.isEmpty()) {
@@ -120,9 +122,9 @@ public final class Suggest {
} else {
final SuggestedWordInfo firstSuggestedWordInfo = getTransformedSuggestedWordInfo(
suggestionResults.first(), suggestionResults.mLocale, isAllUpperCase,
- isFirstCharCapitalized, trailingSingleQuotesCount);
+ isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
firstSuggestion = firstSuggestedWordInfo.mWord;
- if (SuggestedWordInfo.KIND_WHITELIST != firstSuggestedWordInfo.mKind) {
+ if (!firstSuggestedWordInfo.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
whitelistedWord = null;
} else {
whitelistedWord = firstSuggestion;
@@ -140,7 +142,7 @@ public final class Suggest {
final boolean allowsToBeAutoCorrected = (null != whitelistedWord
&& !whitelistedWord.equals(typedWord))
|| (consideredWord.length() > 1 && !mDictionaryFacilitator.isValidWord(
- consideredWord, wordComposer.isFirstCharCapitalized())
+ consideredWord, isOnlyFirstCharCapitalized)
&& !typedWord.equals(firstSuggestion));
final boolean hasAutoCorrection;
@@ -153,7 +155,7 @@ public final class Suggest {
|| suggestionResults.isEmpty() || wordComposer.hasDigits()
|| wordComposer.isMostlyCaps() || wordComposer.isResumed()
|| !mDictionaryFacilitator.hasInitializedMainDictionary()
- || SuggestedWordInfo.KIND_SHORTCUT == suggestionResults.first().mKind) {
+ || suggestionResults.first().isKindOf(SuggestedWordInfo.KIND_SHORTCUT)) {
// If we don't have a main dictionary, we never want to auto-correct. The reason for
// this is, the user may have a contact whose name happens to match a valid word in
// their language, and it will unexpectedly auto-correct. For example, if the user
@@ -169,24 +171,18 @@ public final class Suggest {
}
final ArrayList<SuggestedWordInfo> suggestionsContainer =
- CollectionUtils.newArrayList(suggestionResults);
+ new ArrayList<>(suggestionResults);
final int suggestionsCount = suggestionsContainer.size();
- if (isFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) {
+ if (isOnlyFirstCharCapitalized || isAllUpperCase || 0 != trailingSingleQuotesCount) {
for (int i = 0; i < suggestionsCount; ++i) {
final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
final SuggestedWordInfo transformedWordInfo = getTransformedSuggestedWordInfo(
- wordInfo, suggestionResults.mLocale, isAllUpperCase, isFirstCharCapitalized,
- trailingSingleQuotesCount);
+ wordInfo, suggestionResults.mLocale, isAllUpperCase,
+ isOnlyFirstCharCapitalized, trailingSingleQuotesCount);
suggestionsContainer.set(i, transformedWordInfo);
}
}
- for (int i = 0; i < suggestionsCount; ++i) {
- final SuggestedWordInfo wordInfo = suggestionsContainer.get(i);
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord.toString(),
- wordInfo.mSourceDict.mDictType);
- }
-
if (!TextUtils.isEmpty(typedWord)) {
suggestionsContainer.add(0, new SuggestedWordInfo(typedWord,
SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
@@ -215,25 +211,21 @@ public final class Suggest {
// Retrieves suggestions for the batch input
// and calls the callback function with the suggestions.
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
- final String prevWordForBigram, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
final int sessionId, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
final ArrayList<SuggestedWordInfo> rawSuggestions;
if (ProductionFlag.INCLUDE_RAW_SUGGESTIONS) {
- rawSuggestions = CollectionUtils.newArrayList();
+ rawSuggestions = new ArrayList<>();
} else {
rawSuggestions = null;
}
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
- wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords,
+ wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords,
additionalFeaturesOptions, sessionId, rawSuggestions);
- for (SuggestedWordInfo wordInfo : suggestionResults) {
- LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict.mDictType);
- }
-
final ArrayList<SuggestedWordInfo> suggestionsContainer =
- CollectionUtils.newArrayList(suggestionResults);
+ new ArrayList<>(suggestionResults);
final int suggestionsCount = suggestionsContainer.size();
final boolean isFirstCharCapitalized = wordComposer.wasShiftedNoLock();
final boolean isAllUpperCase = wordComposer.isAllUpperCase();
@@ -276,8 +268,7 @@ public final class Suggest {
final SuggestedWordInfo typedWordInfo = suggestions.get(0);
typedWordInfo.setDebugString("+");
final int suggestionsSize = suggestions.size();
- final ArrayList<SuggestedWordInfo> suggestionsList =
- CollectionUtils.newArrayList(suggestionsSize);
+ final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>(suggestionsSize);
suggestionsList.add(typedWordInfo);
// Note: i here is the index in mScores[], but the index in mSuggestions is one more
// than i because we added the typed word to mSuggestions without touching mScores.
@@ -301,11 +292,11 @@ public final class Suggest {
/* package for test */ static SuggestedWordInfo getTransformedSuggestedWordInfo(
final SuggestedWordInfo wordInfo, final Locale locale, final boolean isAllUpperCase,
- final boolean isFirstCharCapitalized, final int trailingSingleQuotesCount) {
+ final boolean isOnlyFirstCharCapitalized, final int trailingSingleQuotesCount) {
final StringBuilder sb = new StringBuilder(wordInfo.mWord.length());
if (isAllUpperCase) {
sb.append(wordInfo.mWord.toUpperCase(locale));
- } else if (isFirstCharCapitalized) {
+ } else if (isOnlyFirstCharCapitalized) {
sb.append(StringUtils.capitalizeFirstCodePoint(wordInfo.mWord, locale));
} else {
sb.append(wordInfo.mWord);
@@ -318,7 +309,7 @@ public final class Suggest {
for (int i = quotesToAppend - 1; i >= 0; --i) {
sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
}
- return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKind,
+ return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKindAndFlags,
wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord,
wordInfo.mAutoCommitFirstWordConfidence);
}
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index dc2c9fd0e..72461e17a 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -19,7 +19,6 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
import android.view.inputmethod.CompletionInfo;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.StringUtils;
import java.util.ArrayList;
@@ -34,8 +33,7 @@ public class SuggestedWords {
// The maximum number of suggestions available.
public static final int MAX_SUGGESTIONS = 18;
- private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST =
- CollectionUtils.newArrayList(0);
+ private static final ArrayList<SuggestedWordInfo> EMPTY_WORD_INFO_LIST = new ArrayList<>(0);
public static final SuggestedWords EMPTY = new SuggestedWords(
EMPTY_WORD_INFO_LIST, null /* rawSuggestions */, false, false, false, false);
@@ -165,7 +163,7 @@ public class SuggestedWords {
public static ArrayList<SuggestedWordInfo> getFromApplicationSpecifiedCompletions(
final CompletionInfo[] infos) {
- final ArrayList<SuggestedWordInfo> result = CollectionUtils.newArrayList();
+ final ArrayList<SuggestedWordInfo> result = new ArrayList<>();
for (final CompletionInfo info : infos) {
if (null == info || null == info.getText()) {
continue;
@@ -179,8 +177,8 @@ public class SuggestedWords {
// and replace it with what the user currently typed.
public static ArrayList<SuggestedWordInfo> getTypedWordAndPreviousSuggestions(
final String typedWord, final SuggestedWords previousSuggestions) {
- final ArrayList<SuggestedWordInfo> suggestionsList = CollectionUtils.newArrayList();
- final HashSet<String> alreadySeen = CollectionUtils.newHashSet();
+ final ArrayList<SuggestedWordInfo> suggestionsList = new ArrayList<>();
+ final HashSet<String> alreadySeen = new HashSet<>();
suggestionsList.add(new SuggestedWordInfo(typedWord, SuggestedWordInfo.MAX_SCORE,
SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
@@ -209,7 +207,8 @@ public class SuggestedWords {
public static final int NOT_AN_INDEX = -1;
public static final int NOT_A_CONFIDENCE = -1;
public static final int MAX_SCORE = Integer.MAX_VALUE;
- public static final int KIND_MASK_KIND = 0xFF; // Mask to get only the kind
+
+ private static final int KIND_MASK_KIND = 0xFF; // Mask to get only the kind
public static final int KIND_TYPED = 0; // What user typed
public static final int KIND_CORRECTION = 1; // Simple correction/suggestion
public static final int KIND_COMPLETION = 2; // Completion (suggestion with appended chars)
@@ -224,16 +223,16 @@ public class SuggestedWords {
public static final int KIND_RESUMED = 9;
public static final int KIND_OOV_CORRECTION = 10; // Most probable string correction
- public static final int KIND_MASK_FLAGS = 0xFFFFFF00; // Mask to get the flags
public static final int KIND_FLAG_POSSIBLY_OFFENSIVE = 0x80000000;
public static final int KIND_FLAG_EXACT_MATCH = 0x40000000;
+ public static final int KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION = 0x20000000;
public final String mWord;
// The completion info from the application. Null for suggestions that don't come from
// the application (including keyboard-computed ones, so this is almost always null)
public final CompletionInfo mApplicationSpecifiedCompletionInfo;
public final int mScore;
- public final int mKind; // one of the KIND_* constants above
+ public final int mKindAndFlags;
public final int mCodePointCount;
public final Dictionary mSourceDict;
// For auto-commit. This keeps track of the index inside the touch coordinates array
@@ -249,18 +248,19 @@ public class SuggestedWords {
* Create a new suggested word info.
* @param word The string to suggest.
* @param score A measure of how likely this suggestion is.
- * @param kind The kind of suggestion, as one of the above KIND_* constants.
+ * @param kindAndFlags The kind of suggestion, as one of the above KIND_* constants with
+ * flags.
* @param sourceDict What instance of Dictionary produced this suggestion.
* @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord.
* @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence.
*/
- public SuggestedWordInfo(final String word, final int score, final int kind,
+ public SuggestedWordInfo(final String word, final int score, final int kindAndFlags,
final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord,
final int autoCommitFirstWordConfidence) {
mWord = word;
mApplicationSpecifiedCompletionInfo = null;
mScore = score;
- mKind = kind;
+ mKindAndFlags = kindAndFlags;
mSourceDict = sourceDict;
mCodePointCount = StringUtils.codePointCount(mWord);
mIndexOfTouchPointOfSecondWord = indexOfTouchPointOfSecondWord;
@@ -276,7 +276,7 @@ public class SuggestedWords {
mWord = applicationSpecifiedCompletion.getText().toString();
mApplicationSpecifiedCompletionInfo = applicationSpecifiedCompletion;
mScore = SuggestedWordInfo.MAX_SCORE;
- mKind = SuggestedWordInfo.KIND_APP_DEFINED;
+ mKindAndFlags = SuggestedWordInfo.KIND_APP_DEFINED;
mSourceDict = Dictionary.DICTIONARY_APPLICATION_DEFINED;
mCodePointCount = StringUtils.codePointCount(mWord);
mIndexOfTouchPointOfSecondWord = SuggestedWordInfo.NOT_AN_INDEX;
@@ -284,7 +284,27 @@ public class SuggestedWords {
}
public boolean isEligibleForAutoCommit() {
- return (KIND_CORRECTION == mKind && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord);
+ return (isKindOf(KIND_CORRECTION) && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord);
+ }
+
+ public int getKind() {
+ return (mKindAndFlags & KIND_MASK_KIND);
+ }
+
+ public boolean isKindOf(final int kind) {
+ return getKind() == kind;
+ }
+
+ public boolean isPossiblyOffensive() {
+ return (mKindAndFlags & KIND_FLAG_POSSIBLY_OFFENSIVE) != 0;
+ }
+
+ public boolean isExactMatch() {
+ return (mKindAndFlags & KIND_FLAG_EXACT_MATCH) != 0;
+ }
+
+ public boolean isExactMatchWithIntentionalOmission() {
+ return (mKindAndFlags & KIND_FLAG_EXACT_MATCH_WITH_INTENTIONAL_OMISSION) != 0;
}
public void setDebugString(final String str) {
@@ -337,11 +357,11 @@ public class SuggestedWords {
// SuggestedWords is an immutable object, as much as possible. We must not just remove
// words from the member ArrayList as some other parties may expect the object to never change.
public SuggestedWords getSuggestedWordsExcludingTypedWord() {
- final ArrayList<SuggestedWordInfo> newSuggestions = CollectionUtils.newArrayList();
+ final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
String typedWord = null;
for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
- if (SuggestedWordInfo.KIND_TYPED != info.mKind) {
+ if (!info.isKindOf(SuggestedWordInfo.KIND_TYPED)) {
newSuggestions.add(info);
} else {
assert(null == typedWord);
@@ -361,12 +381,12 @@ public class SuggestedWords {
// we should only suggest replacements for this last word.
// TODO: make this work with languages without spaces.
public SuggestedWords getSuggestedWordsForLastWordOfPhraseGesture() {
- final ArrayList<SuggestedWordInfo> newSuggestions = CollectionUtils.newArrayList();
+ final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1;
final String lastWord = info.mWord.substring(indexOfLastSpace);
- newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKind,
+ newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKindAndFlags,
info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX,
SuggestedWordInfo.NOT_A_CONFIDENCE));
}
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 9d9ce0138..debaad13e 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -28,8 +28,8 @@ import android.provider.UserDictionary.Words;
import android.text.TextUtils;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.UserDictionaryCompatUtils;
-import com.android.inputmethod.latin.utils.LocaleUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
import java.io.File;
@@ -51,43 +51,21 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// to auto-correct, so we set this to the highest frequency that won't, i.e. 14.
private static final int USER_DICT_SHORTCUT_FREQUENCY = 14;
- // TODO: use Words.SHORTCUT when we target JellyBean or above
- final static String SHORTCUT = "shortcut";
- private static final String[] PROJECTION_QUERY;
- static {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- PROJECTION_QUERY = new String[] {
- Words.WORD,
- SHORTCUT,
- Words.FREQUENCY,
- };
- } else {
- PROJECTION_QUERY = new String[] {
- Words.WORD,
- Words.FREQUENCY,
- };
- }
- }
+ private static final String[] PROJECTION_QUERY_WITH_SHORTCUT = new String[] {
+ Words.WORD,
+ Words.SHORTCUT,
+ Words.FREQUENCY,
+ };
+ private static final String[] PROJECTION_QUERY_WITHOUT_SHORTCUT = new String[] {
+ Words.WORD,
+ Words.FREQUENCY,
+ };
private static final String NAME = "userunigram";
private ContentObserver mObserver;
final private String mLocale;
final private boolean mAlsoUseMoreRestrictiveLocales;
- final public boolean mEnabled;
-
- public UserBinaryDictionary(final Context context, final Locale locale) {
- this(context, locale, false /* alsoUseMoreRestrictiveLocales */, null /* dictFile */);
- }
-
- public UserBinaryDictionary(final Context context, final Locale locale, final File dictFile) {
- this(context, locale, false /* alsoUseMoreRestrictiveLocales */, dictFile);
- }
-
- public UserBinaryDictionary(final Context context, final Locale locale,
- final boolean alsoUseMoreRestrictiveLocales, final File dictFile) {
- this(context, locale, alsoUseMoreRestrictiveLocales, dictFile, NAME);
- }
protected UserBinaryDictionary(final Context context, final Locale locale,
final boolean alsoUseMoreRestrictiveLocales, final File dictFile, final String name) {
@@ -116,14 +94,20 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// devices. On older versions of the platform, the hook above will be called instead.
@Override
public void onChange(final boolean self, final Uri uri) {
- setNeedsToReload();
+ setNeedsToRecreate();
}
};
cres.registerContentObserver(Words.CONTENT_URI, true, mObserver);
- mEnabled = readIsEnabled();
reloadDictionaryIfRequired();
}
+ @UsedForTesting
+ public static UserBinaryDictionary getDictionary(final Context context, final Locale locale,
+ final File dictFile, final String dictNamePrefix) {
+ return new UserBinaryDictionary(context, locale, false /* alsoUseMoreRestrictiveLocales */,
+ dictFile, dictNamePrefix + NAME);
+ }
+
@Override
public synchronized void close() {
if (mObserver != null) {
@@ -182,10 +166,29 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
} else {
requestArguments = localeElements;
}
+ final String requestString = request.toString();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ try {
+ addWordsFromProjectionLocked(PROJECTION_QUERY_WITH_SHORTCUT, requestString,
+ requestArguments);
+ } catch (IllegalArgumentException e) {
+ // This may happen on some non-compliant devices where the declared API is JB+ but
+ // the SHORTCUT column is not present for some reason.
+ addWordsFromProjectionLocked(PROJECTION_QUERY_WITHOUT_SHORTCUT, requestString,
+ requestArguments);
+ }
+ } else {
+ addWordsFromProjectionLocked(PROJECTION_QUERY_WITHOUT_SHORTCUT, requestString,
+ requestArguments);
+ }
+ }
+
+ private void addWordsFromProjectionLocked(final String[] query, String request,
+ final String[] requestArguments) throws IllegalArgumentException {
Cursor cursor = null;
try {
cursor = mContext.getContentResolver().query(
- Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
+ Words.CONTENT_URI, query, request, requestArguments, null);
addWordsLocked(cursor);
} catch (final SQLiteException e) {
Log.e(TAG, "SQLiteException in the remote User dictionary process.", e);
@@ -198,8 +201,8 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
}
- private boolean readIsEnabled() {
- final ContentResolver cr = mContext.getContentResolver();
+ public static boolean isEnabled(final Context context) {
+ final ContentResolver cr = context.getContentResolver();
final ContentProviderClient client = cr.acquireContentProviderClient(Words.CONTENT_URI);
if (client != null) {
client.release();
@@ -212,18 +215,15 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
/**
* Adds a word to the user dictionary and makes it persistent.
*
+ * @param context the context
+ * @param locale the locale
* @param word the word to add. If the word is capitalized, then the dictionary will
* recognize it as a capitalized word when searched.
*/
- public synchronized void addWordToUserDictionary(final String word) {
+ public static void addWordToUserDictionary(final Context context, final Locale locale,
+ final String word) {
// Update the user dictionary provider
- final Locale locale;
- if (USER_DICTIONARY_ALL_LANGUAGES == mLocale) {
- locale = null;
- } else {
- locale = LocaleUtils.constructLocaleFromString(mLocale);
- }
- UserDictionaryCompatUtils.addWord(mContext, word,
+ UserDictionaryCompatUtils.addWord(context, word,
HISTORICAL_DEFAULT_USER_DICTIONARY_FREQUENCY, null, locale);
}
@@ -245,7 +245,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
if (cursor == null) return;
if (cursor.moveToFirst()) {
final int indexWord = cursor.getColumnIndex(Words.WORD);
- final int indexShortcut = hasShortcutColumn ? cursor.getColumnIndex(SHORTCUT) : 0;
+ final int indexShortcut = hasShortcutColumn ? cursor.getColumnIndex(Words.SHORTCUT) : 0;
final int indexFrequency = cursor.getColumnIndex(Words.FREQUENCY);
while (!cursor.isAfterLast()) {
final String word = cursor.getString(indexWord);
@@ -255,12 +255,12 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// Safeguard against adding really long words.
if (word.length() < MAX_WORD_LENGTH) {
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addWordDynamicallyLocked(word, adjustedFrequency, null /* shortcutTarget */,
+ addUnigramLocked(word, adjustedFrequency, null /* shortcutTarget */,
0 /* shortcutFreq */, false /* isNotAWord */,
false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
if (null != shortcut && shortcut.length() < MAX_WORD_LENGTH) {
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addWordDynamicallyLocked(shortcut, adjustedFrequency, word,
+ addUnigramLocked(shortcut, adjustedFrequency, word,
USER_DICT_SHORTCUT_FREQUENCY, true /* isNotAWord */,
false /* isBlacklisted */, BinaryDictionary.NOT_A_VALID_TIMESTAMP);
}
@@ -269,9 +269,4 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
}
}
-
- @Override
- protected boolean haveContentsChanged() {
- return true;
- }
}
diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java
index d755195f2..6ce1f85c5 100644
--- a/java/src/com/android/inputmethod/latin/WordComposer.java
+++ b/java/src/com/android/inputmethod/latin/WordComposer.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.latin;
import com.android.inputmethod.event.CombinerChain;
import com.android.inputmethod.event.Event;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -41,15 +40,11 @@ public final class WordComposer {
public static final int CAPS_MODE_AUTO_SHIFT_LOCKED = 0x7;
private CombinerChain mCombinerChain;
+ private String mCombiningSpec; // Memory so that we don't uselessly recreate the combiner chain
// The list of events that served to compose this string.
private final ArrayList<Event> mEvents;
private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH);
- // The previous word (before the composing word). Used as context for suggestions. May be null
- // after resetting and before starting a new composing word, or when there is no context like
- // at the start of text for example. It can also be set to null externally when the user
- // enters a separator that does not let bigrams across, like a period or a comma.
- private String mPreviousWordForSuggestion;
private String mAutoCorrection;
private boolean mIsResumed;
private boolean mIsBatchMode;
@@ -74,23 +69,36 @@ public final class WordComposer {
private int mCursorPositionWithinWord;
/**
- * Whether the user chose to capitalize the first char of the word.
+ * Whether the composing word has the only first char capitalized.
*/
- private boolean mIsFirstCharCapitalized;
+ private boolean mIsOnlyFirstCharCapitalized;
public WordComposer() {
- mCombinerChain = new CombinerChain();
- mEvents = CollectionUtils.newArrayList();
+ mCombinerChain = new CombinerChain("");
+ mEvents = new ArrayList<>();
mAutoCorrection = null;
mIsResumed = false;
mIsBatchMode = false;
mCursorPositionWithinWord = 0;
mRejectedBatchModeSuggestion = null;
- mPreviousWordForSuggestion = null;
refreshTypedWordCache();
}
/**
+ * Restart the combiners, possibly with a new spec.
+ * @param combiningSpec The spec string for combining. This is found in the extra value.
+ */
+ public void restartCombining(final String combiningSpec) {
+ final String nonNullCombiningSpec = null == combiningSpec ? "" : combiningSpec;
+ if (!nonNullCombiningSpec.equals(mCombiningSpec)) {
+ mCombinerChain = new CombinerChain(
+ mCombinerChain.getComposingWordWithCombiningFeedback().toString(),
+ CombinerChain.createCombiners(nonNullCombiningSpec));
+ mCombiningSpec = nonNullCombiningSpec;
+ }
+ }
+
+ /**
* Clear out the keys registered so far.
*/
public void reset() {
@@ -99,12 +107,11 @@ public final class WordComposer {
mAutoCorrection = null;
mCapsCount = 0;
mDigitsCount = 0;
- mIsFirstCharCapitalized = false;
+ mIsOnlyFirstCharCapitalized = false;
mIsResumed = false;
mIsBatchMode = false;
mCursorPositionWithinWord = 0;
mRejectedBatchModeSuggestion = null;
- mPreviousWordForSuggestion = null;
refreshTypedWordCache();
}
@@ -133,8 +140,12 @@ public final class WordComposer {
*/
public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
final int[] destination) {
+ // This method can be called on a separate thread and mTypedWordCache can change while we
+ // are executing this method.
+ final String typedWord = mTypedWordCache.toString();
// lastIndex is exclusive
- final int lastIndex = mTypedWordCache.length() - trailingSingleQuotesCount();
+ final int lastIndex = typedWord.length()
+ - StringUtils.getTrailingSingleQuotesCount(typedWord);
if (lastIndex <= 0) {
// The string is empty or contains only single quotes.
return 0;
@@ -142,11 +153,11 @@ public final class WordComposer {
// The following function counts the number of code points in the text range which begins
// at index 0 and extends to the character at lastIndex.
- final int codePointSize = Character.codePointCount(mTypedWordCache, 0, lastIndex);
+ final int codePointSize = Character.codePointCount(typedWord, 0, lastIndex);
if (codePointSize > destination.length) {
return -1;
}
- return StringUtils.copyCodePointsAndReturnCodePointCount(destination, mTypedWordCache, 0,
+ return StringUtils.copyCodePointsAndReturnCodePointCount(destination, typedWord, 0,
lastIndex, true /* downCase */);
}
@@ -162,12 +173,6 @@ public final class WordComposer {
return mInputPointers;
}
- private static boolean isFirstCharCapitalized(final int index, final int codePoint,
- final boolean previous) {
- if (index == 0) return Character.isUpperCase(codePoint);
- return previous && !Character.isUpperCase(codePoint);
- }
-
/**
* Process an input event.
*
@@ -187,7 +192,7 @@ public final class WordComposer {
mCursorPositionWithinWord = mCodePointSize;
// We may have deleted the last one.
if (0 == mCodePointSize) {
- mIsFirstCharCapitalized = false;
+ mIsOnlyFirstCharCapitalized = false;
}
if (Constants.CODE_DELETE != event.mKeyCode) {
if (newIndex < MAX_WORD_LENGTH) {
@@ -199,8 +204,12 @@ public final class WordComposer {
mInputPointers.addPointerAt(newIndex, keyX, keyY, 0, 0);
}
}
- mIsFirstCharCapitalized = isFirstCharCapitalized(
- newIndex, primaryCode, mIsFirstCharCapitalized);
+ if (0 == newIndex) {
+ mIsOnlyFirstCharCapitalized = Character.isUpperCase(primaryCode);
+ } else {
+ mIsOnlyFirstCharCapitalized = mIsOnlyFirstCharCapitalized
+ && !Character.isUpperCase(primaryCode);
+ }
if (Character.isUpperCase(primaryCode)) mCapsCount++;
if (Character.isDigit(primaryCode)) mDigitsCount++;
}
@@ -280,11 +289,8 @@ public final class WordComposer {
* This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity.
* @param codePoints the code points to set as the composing word.
* @param coordinates the x, y coordinates of the key in the CoordinateUtils format
- * @param previousWord the previous word, to use as context for suggestions. Can be null if
- * the context is nil (typically, at start of text).
*/
- public void setComposingWord(final int[] codePoints, final int[] coordinates,
- final CharSequence previousWord) {
+ public void setComposingWord(final int[] codePoints, final int[] coordinates) {
reset();
final int length = codePoints.length;
for (int i = 0; i < length; ++i) {
@@ -293,7 +299,6 @@ public final class WordComposer {
CoordinateUtils.yFromArray(coordinates, i)));
}
mIsResumed = true;
- mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString();
}
/**
@@ -304,25 +309,13 @@ public final class WordComposer {
return mTypedWordCache.toString();
}
- public String getPreviousWordForSuggestion() {
- return mPreviousWordForSuggestion;
- }
-
/**
- * Whether or not the user typed a capital letter as the first letter in the word
+ * Whether or not the user typed a capital letter as the first letter in the word, and no
+ * other letter is capitalized
* @return capitalization preference
*/
- public boolean isFirstCharCapitalized() {
- return mIsFirstCharCapitalized;
- }
-
- public int trailingSingleQuotesCount() {
- final int lastIndex = mTypedWordCache.length() - 1;
- int i = lastIndex;
- while (i >= 0 && mTypedWordCache.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
- --i;
- }
- return lastIndex - i;
+ public boolean isOnlyFirstCharCapitalized() {
+ return mIsOnlyFirstCharCapitalized;
}
/**
@@ -358,7 +351,7 @@ public final class WordComposer {
}
/**
- * Saves the caps mode and the previous word at the start of composing.
+ * Saves the caps mode at the start of composing.
*
* WordComposer needs to know about the caps mode for several reasons. The first is, we need
* to know after the fact what the reason was, to register the correct form into the user
@@ -367,12 +360,9 @@ public final class WordComposer {
* Also, batch input needs to know about the current caps mode to display correctly
* capitalized suggestions.
* @param mode the mode at the time of start
- * @param previousWord the previous word as context for suggestions. May be null if none.
*/
- public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode,
- final CharSequence previousWord) {
+ public void setCapitalizedModeAtStartComposingTime(final int mode) {
mCapitalizedMode = mode;
- mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString();
}
/**
@@ -408,13 +398,13 @@ public final class WordComposer {
// `type' should be one of the LastComposedWord.COMMIT_TYPE_* constants above.
// committedWord should contain suggestion spans if applicable.
public LastComposedWord commitWord(final int type, final CharSequence committedWord,
- final String separatorString, final String prevWord) {
+ final String separatorString, final PrevWordsInfo prevWordsInfo) {
// Note: currently, we come here whenever we commit a word. If it's a MANUAL_PICK
// or a DECIDED_WORD we may cancel the commit later; otherwise, we should deactivate
// the last composed word to ensure this does not happen.
final LastComposedWord lastComposedWord = new LastComposedWord(mEvents,
mInputPointers, mTypedWordCache.toString(), committedWord, separatorString,
- prevWord, mCapitalizedMode);
+ prevWordsInfo, mCapitalizedMode);
mInputPointers.reset();
if (type != LastComposedWord.COMMIT_TYPE_DECIDED_WORD
&& type != LastComposedWord.COMMIT_TYPE_MANUAL_PICK) {
@@ -423,11 +413,10 @@ public final class WordComposer {
mCapsCount = 0;
mDigitsCount = 0;
mIsBatchMode = false;
- mPreviousWordForSuggestion = committedWord.toString();
mCombinerChain.reset();
mEvents.clear();
mCodePointSize = 0;
- mIsFirstCharCapitalized = false;
+ mIsOnlyFirstCharCapitalized = false;
mCapitalizedMode = CAPS_MODE_OFF;
refreshTypedWordCache();
mAutoCorrection = null;
@@ -437,15 +426,7 @@ public final class WordComposer {
return lastComposedWord;
}
- // Call this when the recorded previous word should be discarded. This is typically called
- // when the user inputs a separator that's not whitespace (including the case of the
- // double-space-to-period feature).
- public void discardPreviousWordForSuggestion() {
- mPreviousWordForSuggestion = null;
- }
-
- public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord,
- final String previousWord) {
+ public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord) {
mEvents.clear();
Collections.copy(mEvents, lastComposedWord.mEvents);
mInputPointers.set(lastComposedWord.mInputPointers);
@@ -456,7 +437,6 @@ public final class WordComposer {
mCursorPositionWithinWord = mCodePointSize;
mRejectedBatchModeSuggestion = null;
mIsResumed = true;
- mPreviousWordForSuggestion = previousWord;
}
public boolean isBatchMode() {
diff --git a/java/src/com/android/inputmethod/latin/WordListInfo.java b/java/src/com/android/inputmethod/latin/WordListInfo.java
index 5ac806a0c..268fe9818 100644
--- a/java/src/com/android/inputmethod/latin/WordListInfo.java
+++ b/java/src/com/android/inputmethod/latin/WordListInfo.java
@@ -22,8 +22,10 @@ package com.android.inputmethod.latin;
public final class WordListInfo {
public final String mId;
public final String mLocale;
- public WordListInfo(final String id, final String locale) {
+ public final String mRawChecksum;
+ public WordListInfo(final String id, final String locale, final String rawChecksum) {
mId = id;
mLocale = locale;
+ mRawChecksum = rawChecksum;
}
}
diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
index 139e73aa4..7071d8689 100644
--- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
+++ b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
@@ -27,7 +27,6 @@ import com.android.inputmethod.latin.BinaryDictionaryFileDumper;
import com.android.inputmethod.latin.BinaryDictionaryGetter;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.DialogUtils;
import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
@@ -50,7 +49,7 @@ public class ExternalDictionaryGetterForDebug {
private static String[] findDictionariesInTheDownloadedFolder() {
final File[] files = new File(SOURCE_FOLDER).listFiles();
- final ArrayList<String> eligibleList = CollectionUtils.newArrayList();
+ final ArrayList<String> eligibleList = new ArrayList<>();
for (File f : files) {
final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f);
if (null == header) continue;
diff --git a/java/src/com/android/inputmethod/latin/define/ProductionFlag.java b/java/src/com/android/inputmethod/latin/define/ProductionFlag.java
index af899c040..972580298 100644
--- a/java/src/com/android/inputmethod/latin/define/ProductionFlag.java
+++ b/java/src/com/android/inputmethod/latin/define/ProductionFlag.java
@@ -21,13 +21,6 @@ public final class ProductionFlag {
// This class is not publicly instantiable.
}
- public static final boolean USES_DEVELOPMENT_ONLY_DIAGNOSTICS = false;
-
- // When false, USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG suggests that all guarded
- // class-private DEBUG flags should be false, and any privacy controls should be enforced.
- // USES_DEVELOPMENT_ONLY_DIAGNOSTICS must be false for any production build.
- public static final boolean USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG = false;
-
public static final boolean IS_HARDWARE_KEYBOARD_SUPPORTED = false;
// When true, enable {@link InputMethodService#onUpdateCursor} callback with
@@ -38,4 +31,7 @@ public final class ProductionFlag {
// Include all suggestions from all dictionaries in {@link SuggestedWords#mRawSuggestions}.
public static final boolean INCLUDE_RAW_SUGGESTIONS = false;
+
+ // When false, the metrics logging is not yet ready to be enabled.
+ public static final boolean IS_METRICS_LOGGING_SUPPORTED = false;
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index d2100d415..24cc1ef0d 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -32,29 +32,26 @@ import com.android.inputmethod.event.InputTransaction;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest;
+import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LastComposedWord;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.RichInputConnection;
import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
-import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.InputTypeUtils;
-import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.latin.utils.TextRange;
-import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList;
import java.util.TreeSet;
@@ -78,7 +75,8 @@ public final class InputLogic {
private int mSpaceState;
// Never null
public SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
- public final Suggest mSuggest = new Suggest();
+ public final Suggest mSuggest;
+ private final DictionaryFacilitator mDictionaryFacilitator;
public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
public final WordComposer mWordComposer;
@@ -87,7 +85,7 @@ public final class InputLogic {
private int mDeleteCount;
private long mLastKeyTime;
- public final TreeSet<Long> mCurrentlyPressedHardwareKeys = CollectionUtils.newTreeSet();
+ public final TreeSet<Long> mCurrentlyPressedHardwareKeys = new TreeSet<>();
// Keeps track of most recently inserted text (multi-character key) for reverting
private String mEnteredText;
@@ -97,13 +95,23 @@ public final class InputLogic {
private boolean mIsAutoCorrectionIndicatorOn;
private long mDoubleSpacePeriodCountdownStart;
+ /**
+ * Create a new instance of the input logic.
+ * @param latinIME the instance of the parent LatinIME. We should remove this when we can.
+ * @param suggestionStripViewAccessor an object to access the suggestion strip view.
+ * @param dictionaryFacilitator facilitator for getting suggestions and updating user history
+ * dictionary.
+ */
public InputLogic(final LatinIME latinIME,
- final SuggestionStripViewAccessor suggestionStripViewAccessor) {
+ final SuggestionStripViewAccessor suggestionStripViewAccessor,
+ final DictionaryFacilitator dictionaryFacilitator) {
mLatinIME = latinIME;
mSuggestionStripViewAccessor = suggestionStripViewAccessor;
mWordComposer = new WordComposer();
mConnection = new RichInputConnection(latinIME);
mInputLogicHandler = InputLogicHandler.NULL_HANDLER;
+ mSuggest = new Suggest(dictionaryFacilitator);
+ mDictionaryFacilitator = dictionaryFacilitator;
}
/**
@@ -117,13 +125,16 @@ public final class InputLogic {
*
* @param restarting whether input is starting in the same field as before. Unused for now.
* @param editorInfo the editorInfo associated with the editor.
+ * @param combiningSpec the combining spec string for this subtype
*/
- public void startInput(final boolean restarting, final EditorInfo editorInfo) {
+ public void startInput(final boolean restarting, final EditorInfo editorInfo,
+ final String combiningSpec) {
mEnteredText = null;
+ mWordComposer.restartCombining(combiningSpec);
resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SpaceState.NONE;
- mRecapitalizeStatus.deactivate();
+ mRecapitalizeStatus.disable(); // Do not perform recapitalize until the cursor is moved once
mCurrentlyPressedHardwareKeys.clear();
mSuggestedWords = SuggestedWords.EMPTY;
// In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying
@@ -138,6 +149,14 @@ public final class InputLogic {
}
/**
+ * Call this when the subtype changes.
+ * @param combiningSpec the spec string for the combining rules
+ */
+ public void onSubtypeChanged(final String combiningSpec) {
+ mWordComposer.restartCombining(combiningSpec);
+ }
+
+ /**
* Clean up the input logic after input is finished.
*/
public void finishInput() {
@@ -156,7 +175,7 @@ public final class InputLogic {
final InputLogicHandler inputLogicHandler = mInputLogicHandler;
mInputLogicHandler = InputLogicHandler.NULL_HANDLER;
inputLogicHandler.destroy();
- mSuggest.mDictionaryFacilitator.closeDictionaries();
+ mDictionaryFacilitator.closeDictionaries();
}
/**
@@ -179,19 +198,11 @@ public final class InputLogic {
resetComposingState(true /* alsoResetLastComposedWord */);
}
handler.postUpdateSuggestionStrip();
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS
- && ResearchLogger.RESEARCH_KEY_OUTPUT_TEXT.equals(rawText)) {
- ResearchLogger.getInstance().onResearchKeySelected(mLatinIME);
- return;
- }
final String text = performSpecificTldProcessingOnTextInput(rawText);
if (SpaceState.PHANTOM == mSpaceState) {
promotePhantomSpace(settingsValues);
}
mConnection.commitText(text, 1);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onTextInput(text, false /* isBatchMode */);
- }
mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
mSpaceState = SpaceState.NONE;
@@ -218,14 +229,8 @@ public final class InputLogic {
// If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
if (suggestion.length() == 1 && suggestedWords.isPunctuationSuggestions()) {
// Word separators are suggested before the user inputs something.
- // So, LatinImeLogger logs "" as a user's input.
- LatinImeLogger.logOnManualSuggestion("", suggestion, index, suggestedWords);
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
final Event event = Event.createPunctuationSuggestionPickedEvent(suggestionInfo);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_punctuationSuggestion(index, suggestion,
- false /* isBatchMode */, suggestedWords.mIsPrediction);
- }
return onCodeInput(settingsValues, event, keyboardShiftState, handler);
}
@@ -248,7 +253,7 @@ public final class InputLogic {
// code path as for other kinds, use commitChosenWord, and do everything normally. We will
// however need to reset the suggestion strip right away, because we know we can't take
// the risk of calling commitCompletion twice because we don't know how the app will react.
- if (SuggestedWordInfo.KIND_APP_DEFINED == suggestionInfo.mKind) {
+ if (suggestionInfo.isKindOf(SuggestedWordInfo.KIND_APP_DEFINED)) {
mSuggestedWords = SuggestedWords.EMPTY;
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
@@ -261,14 +266,8 @@ public final class InputLogic {
// We need to log before we commit, because the word composer will store away the user
// typed word.
final String replacedWord = mWordComposer.getTypedWord();
- LatinImeLogger.logOnManualSuggestion(replacedWord, suggestion, index, suggestedWords);
commitChosenWord(settingsValues, suggestion,
LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion,
- mWordComposer.isBatchMode(), suggestionInfo.mScore,
- suggestionInfo.mKind, suggestionInfo.mSourceDict.mDictType);
- }
mConnection.endBatchEdit();
// Don't allow cancellation of manual pick
mLastComposedWord.deactivate();
@@ -278,18 +277,12 @@ public final class InputLogic {
// We should show the "Touch again to save" hint if the user pressed the first entry
// AND it's in none of our current dictionaries (main, user or otherwise).
- final DictionaryFacilitatorForSuggest dictionaryFacilitator =
- mSuggest.mDictionaryFacilitator;
final boolean showingAddToDictionaryHint =
- (SuggestedWordInfo.KIND_TYPED == suggestionInfo.mKind
- || SuggestedWordInfo.KIND_OOV_CORRECTION == suggestionInfo.mKind)
- && !dictionaryFacilitator.isValidWord(suggestion, true /* ignoreCase */);
+ (suggestionInfo.isKindOf(SuggestedWordInfo.KIND_TYPED)
+ || suggestionInfo.isKindOf(SuggestedWordInfo.KIND_OOV_CORRECTION))
+ && !mDictionaryFacilitator.isValidWord(suggestion, true /* ignoreCase */);
- if (settingsValues.mIsInternal) {
- LatinImeLoggerUtils.onSeparator((char)Constants.CODE_SPACE,
- Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
- }
- if (showingAddToDictionaryHint && dictionaryFacilitator.isUserDictionaryEnabled()) {
+ if (showingAddToDictionaryHint && mDictionaryFacilitator.isUserDictionaryEnabled()) {
mSuggestionStripViewAccessor.showAddToDictionaryHint(suggestion);
} else {
// If we're not showing the "Touch again to save", then update the suggestion strip.
@@ -326,8 +319,16 @@ public final class InputLogic {
|| !mWordComposer.isComposingWord(); // safe to reset
final boolean hasOrHadSelection = (oldSelStart != oldSelEnd || newSelStart != newSelEnd);
final int moveAmount = newSelStart - oldSelStart;
- if (selectionChangedOrSafeToReset && (hasOrHadSelection
- || !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) {
+ // As an added small gift from the framework, it happens upon rotation when there
+ // is a selection that we get a wrong cursor position delivered to startInput() that
+ // does not get reflected in the oldSel{Start,End} parameters to the next call to
+ // onUpdateSelection. In this case, we may have set a composition, and when we're here
+ // we realize we shouldn't have. In theory, in this case, selectionChangedOrSafeToReset
+ // should be true, but that is if the framework had taken that wrong cursor position
+ // into account, which means we have to reset the entire composing state whenever there
+ // is or was a selection regardless of whether it changed or not.
+ if (hasOrHadSelection || (selectionChangedOrSafeToReset
+ && !mWordComposer.moveCursorByAndReturnIfInsideComposingWord(moveAmount))) {
// If we are composing a word and moving the cursor, we would want to set a
// suggestion span for recorrection to work correctly. Unfortunately, that
// would involve the keyboard committing some new text, which would move the
@@ -352,10 +353,12 @@ public final class InputLogic {
newSelStart, newSelEnd, false /* shouldFinishComposition */);
}
+ // The cursor has been moved : we now accept to perform recapitalization
+ mRecapitalizeStatus.enable();
// We moved the cursor. If we are touching a word, we need to resume suggestion.
- mLatinIME.mHandler.postResumeSuggestions();
- // Reset the last recapitalization.
- mRecapitalizeStatus.deactivate();
+ mLatinIME.mHandler.postResumeSuggestions(false /* shouldIncludeResumedWordInSuggestions */);
+ // Stop the last recapitalization, if started.
+ mRecapitalizeStatus.stop();
return true;
}
@@ -376,16 +379,9 @@ public final class InputLogic {
final int keyboardShiftMode,
// TODO: remove this argument
final LatinIME.UIHandler handler) {
- // TODO: rework the following to not squash the keycode and the code point into the same
- // var because it's confusing. Instead the switch() should handle this in a readable manner.
- final int code =
- Event.NOT_A_CODE_POINT == event.mCodePoint ? event.mKeyCode : event.mCodePoint;
final InputTransaction inputTransaction = new InputTransaction(settingsValues, event,
SystemClock.uptimeMillis(), mSpaceState,
getActualCapsMode(settingsValues, keyboardShiftMode));
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onCodeInput(code, event.mX, event.mY);
- }
if (event.mKeyCode != Constants.CODE_DELETE
|| inputTransaction.mTimestamp > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
mDeleteCount = 0;
@@ -407,7 +403,6 @@ public final class InputLogic {
switch (event.mKeyCode) {
case Constants.CODE_DELETE:
handleBackspace(inputTransaction);
- LatinImeLogger.logOnDelete(event.mX, event.mY);
break;
case Constants.CODE_SHIFT:
performRecapitalization(inputTransaction.mSettingsValues);
@@ -513,12 +508,6 @@ public final class InputLogic {
++mAutoCommitSequenceNumber;
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
- if (settingsValues.mIsInternal) {
- if (mWordComposer.isBatchMode()) {
- LatinImeLoggerUtils.onAutoCorrection("", mWordComposer.getTypedWord(), " ",
- mWordComposer);
- }
- }
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the batch input at the current cursor position.
@@ -555,11 +544,8 @@ public final class InputLogic {
}
}
mConnection.endBatchEdit();
- mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
- getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()),
- // Prev word is 1st word before cursor
- getNthPreviousWordForSuggestion(
- settingsValues.mSpacingAndPunctuations, 1 /* nthPreviousWord */));
+ mWordComposer.setCapitalizedModeAtStartComposingTime(
+ getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()));
}
/* The sequence number member is only used in onUpdateBatchInput. It is increased each time
@@ -588,16 +574,15 @@ public final class InputLogic {
if (null != candidate
&& mSuggestedWords.mSequenceNumber >= mAutoCommitSequenceNumber) {
if (candidate.mSourceDict.shouldAutoCommit(candidate)) {
- final String[] commitParts = candidate.mWord.split(" ", 2);
+ final String[] commitParts = candidate.mWord.split(Constants.WORD_SEPARATOR, 2);
batchPointers.shift(candidate.mIndexOfTouchPointOfSecondWord);
promotePhantomSpace(settingsValues);
mConnection.commitText(commitParts[0], 0);
mSpaceState = SpaceState.PHANTOM;
keyboardSwitcher.requestUpdatingShiftState(
getCurrentAutoCapsState(settingsValues), getCurrentRecapitalizeState());
- mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
- getActualCapsMode(settingsValues,
- keyboardSwitcher.getKeyboardShiftMode()), commitParts[0]);
+ mWordComposer.setCapitalizedModeAtStartComposingTime(getActualCapsMode(
+ settingsValues, keyboardSwitcher.getKeyboardShiftMode()));
++mAutoCommitSequenceNumber;
}
}
@@ -657,19 +642,9 @@ public final class InputLogic {
|| Character.getType(codePoint) == Character.OTHER_SYMBOL) {
didAutoCorrect = handleSeparator(inputTransaction,
inputTransaction.mEvent.isSuggestionStripPress(), handler);
- if (inputTransaction.mSettingsValues.mIsInternal) {
- LatinImeLoggerUtils.onSeparator((char)codePoint,
- inputTransaction.mEvent.mX, inputTransaction.mEvent.mY);
- }
} else {
didAutoCorrect = false;
if (SpaceState.PHANTOM == inputTransaction.mSpaceState) {
- if (inputTransaction.mSettingsValues.mIsInternal) {
- if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) {
- LatinImeLoggerUtils.onAutoCorrection("", mWordComposer.getTypedWord(), " ",
- mWordComposer);
- }
- }
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the character at the current cursor position.
@@ -730,11 +705,10 @@ public final class InputLogic {
(!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)
|| !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces)) {
// Reset entirely the composing state anyway, then start composing a new word unless
- // the character is a single quote or a dash. The idea here is, single quote and dash
- // are not separators and they should be treated as normal characters, except in the
- // first position where they should not start composing a word.
- isComposingWord = (Constants.CODE_SINGLE_QUOTE != codePoint
- && Constants.CODE_DASH != codePoint);
+ // the character is a word connector. The idea here is, word connectors are not
+ // separators and they should be treated as normal characters, except in the first
+ // position where they should not start composing a word.
+ isComposingWord = !settingsValues.mSpacingAndPunctuations.isWordConnector(codePoint);
// Here we don't need to reset the last composed word. It will be reset
// when we commit this one, if we ever do; if on the other hand we backspace
// it entirely and resume suggestions on the previous word, we'd like to still
@@ -745,11 +719,7 @@ public final class InputLogic {
mWordComposer.processEvent(inputTransaction.mEvent);
// If it's the first letter, make note of auto-caps state
if (mWordComposer.isSingleLetter()) {
- // We pass 1 to getPreviousWordForSuggestion because we were not composing a word
- // yet, so the word we want is the 1st word before the cursor.
- mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
- inputTransaction.mShiftState, getNthPreviousWordForSuggestion(
- settingsValues.mSpacingAndPunctuations, 1 /* nthPreviousWord */));
+ mWordComposer.setCapitalizedModeAtStartComposingTime(inputTransaction.mShiftState);
}
mConnection.setComposingText(getTextWithUnderline(
mWordComposer.getTypedWord()), 1);
@@ -767,10 +737,6 @@ public final class InputLogic {
mSuggestionStripViewAccessor.dismissAddToDictionaryHint();
}
inputTransaction.setRequiresUpdateSuggestions();
- if (settingsValues.mIsInternal) {
- LatinImeLoggerUtils.onNonSeparator((char)codePoint, inputTransaction.mEvent.mX,
- inputTransaction.mEvent.mY);
- }
}
/**
@@ -784,12 +750,13 @@ public final class InputLogic {
// TODO: remove this argument
final LatinIME.UIHandler handler) {
final int codePoint = inputTransaction.mEvent.mCodePoint;
+ final SettingsValues settingsValues = inputTransaction.mSettingsValues;
boolean didAutoCorrect = false;
+ final boolean wasComposingWord = mWordComposer.isComposingWord();
// We avoid sending spaces in languages without spaces if we were composing.
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
- && !inputTransaction.mSettingsValues.mSpacingAndPunctuations
- .mCurrentLanguageHasSpaces
- && mWordComposer.isComposingWord();
+ && !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
+ && wasComposingWord;
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the separator at the current cursor position.
@@ -798,13 +765,13 @@ public final class InputLogic {
}
// isComposingWord() may have changed since we stored wasComposing
if (mWordComposer.isComposingWord()) {
- if (inputTransaction.mSettingsValues.mCorrectionEnabled) {
+ if (settingsValues.mAutoCorrectionEnabled) {
final String separator = shouldAvoidSendingCode ? LastComposedWord.NOT_A_SEPARATOR
: StringUtils.newSingleCodePointString(codePoint);
- commitCurrentAutoCorrection(inputTransaction.mSettingsValues, separator, handler);
+ commitCurrentAutoCorrection(settingsValues, separator, handler);
didAutoCorrect = true;
} else {
- commitTyped(inputTransaction.mSettingsValues,
+ commitTyped(settingsValues,
StringUtils.newSingleCodePointString(codePoint));
}
}
@@ -821,38 +788,41 @@ public final class InputLogic {
// Double quotes behave like they are usually preceded by space iff we are
// not inside a double quote or after a digit.
needsPrecedingSpace = !isInsideDoubleQuoteOrAfterDigit;
+ } else if (settingsValues.mSpacingAndPunctuations.isClusteringSymbol(codePoint)
+ && settingsValues.mSpacingAndPunctuations.isClusteringSymbol(
+ mConnection.getCodePointBeforeCursor())) {
+ needsPrecedingSpace = false;
} else {
- needsPrecedingSpace = inputTransaction.mSettingsValues.isUsuallyPrecededBySpace(
- codePoint);
+ needsPrecedingSpace = settingsValues.isUsuallyPrecededBySpace(codePoint);
}
if (needsPrecedingSpace) {
- promotePhantomSpace(inputTransaction.mSettingsValues);
- }
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleSeparator(codePoint, mWordComposer.isComposingWord());
+ promotePhantomSpace(settingsValues);
}
if (!shouldAvoidSendingCode) {
- sendKeyCodePoint(inputTransaction.mSettingsValues, codePoint);
+ sendKeyCodePoint(settingsValues, codePoint);
}
if (Constants.CODE_SPACE == codePoint) {
if (maybeDoubleSpacePeriod(inputTransaction)) {
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
+ inputTransaction.setRequiresUpdateSuggestions();
mSpaceState = SpaceState.DOUBLE;
} else if (!mSuggestedWords.isPunctuationSuggestions()) {
mSpaceState = SpaceState.WEAK;
}
startDoubleSpacePeriodCountdown(inputTransaction);
- inputTransaction.setRequiresUpdateSuggestions();
+ if (wasComposingWord) {
+ inputTransaction.setRequiresUpdateSuggestions();
+ }
} else {
if (swapWeakSpace) {
swapSwapperAndSpace(inputTransaction);
mSpaceState = SpaceState.SWAP_PUNCTUATION;
} else if ((SpaceState.PHANTOM == inputTransaction.mSpaceState
- && inputTransaction.mSettingsValues.isUsuallyFollowedBySpace(codePoint))
+ && settingsValues.isUsuallyFollowedBySpace(codePoint))
|| (Constants.CODE_DOUBLE_QUOTE == codePoint
&& isInsideDoubleQuoteOrAfterDigit)) {
// If we are in phantom space state, and the user presses a separator, we want to
@@ -907,23 +877,20 @@ public final class InputLogic {
}
if (mWordComposer.isComposingWord()) {
if (mWordComposer.isBatchMode()) {
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- final String word = mWordComposer.getTypedWord();
- ResearchLogger.latinIME_handleBackspace_batch(word, 1);
- }
final String rejectedSuggestion = mWordComposer.getTypedWord();
mWordComposer.reset();
mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion);
} else {
mWordComposer.processEvent(inputTransaction.mEvent);
}
- mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
+ if (mWordComposer.isComposingWord()) {
+ mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
+ } else {
+ mConnection.commitText("", 1);
+ }
inputTransaction.setRequiresUpdateSuggestions();
} else {
if (mLastComposedWord.canRevertCommit()) {
- if (inputTransaction.mSettingsValues.mIsInternal) {
- LatinImeLoggerUtils.onAutoCorrectionCancellation();
- }
revertCommit(inputTransaction);
return;
}
@@ -932,9 +899,6 @@ public final class InputLogic {
// This is triggered on backspace after a key that inputs multiple characters,
// like the smiley key or the .com key.
mConnection.deleteSurroundingText(mEnteredText.length(), 0);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleBackspace_cancelTextInput(mEnteredText);
- }
mEnteredText = null;
// If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
// In addition we know that spaceState is false, and that we should not be
@@ -946,6 +910,9 @@ public final class InputLogic {
if (mConnection.revertDoubleSpacePeriod()) {
// No need to reset mSpaceState, it has already be done (that's why we
// receive it as a parameter)
+ inputTransaction.setRequiresUpdateSuggestions();
+ mWordComposer.setCapitalizedModeAtStartComposingTime(
+ WordComposer.CAPS_MODE_OFF);
return;
}
} else if (SpaceState.SWAP_PUNCTUATION == inputTransaction.mSpaceState) {
@@ -964,10 +931,6 @@ public final class InputLogic {
mConnection.setSelection(mConnection.getExpectedSelectionEnd(),
mConnection.getExpectedSelectionEnd());
mConnection.deleteSurroundingText(numCharsDeleted, 0);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleBackspace(numCharsDeleted,
- false /* shouldUncommitLogUnit */);
- }
} else {
// There is no selection, just delete one character.
if (Constants.NOT_A_CURSOR_POSITION == mConnection.getExpectedSelectionEnd()) {
@@ -1002,10 +965,6 @@ public final class InputLogic {
final int lengthToDelete =
Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1;
mConnection.deleteSurroundingText(lengthToDelete, 0);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleBackspace(lengthToDelete,
- true /* shouldUncommitLogUnit */);
- }
if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) {
final int codePointBeforeCursorToDeleteAgain =
mConnection.getCodePointBeforeCursor();
@@ -1013,21 +972,18 @@ public final class InputLogic {
final int lengthToDeleteAgain = Character.isSupplementaryCodePoint(
codePointBeforeCursorToDeleteAgain) ? 2 : 1;
mConnection.deleteSurroundingText(lengthToDeleteAgain, 0);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_handleBackspace(lengthToDeleteAgain,
- true /* shouldUncommitLogUnit */);
- }
}
}
}
}
- if (inputTransaction.mSettingsValues.isSuggestionStripVisible()
+ if (inputTransaction.mSettingsValues
+ .isCurrentOrientationAllowingSuggestionsPerUserSettings()
&& inputTransaction.mSettingsValues.mSpacingAndPunctuations
.mCurrentLanguageHasSpaces
&& !mConnection.isCursorFollowedByWordCharacter(
inputTransaction.mSettingsValues.mSpacingAndPunctuations)) {
restartSuggestionsOnWordTouchedByCursor(inputTransaction.mSettingsValues,
- true /* includeResumedWordInSuggestions */);
+ true /* shouldIncludeResumedWordInSuggestions */);
}
}
}
@@ -1053,9 +1009,6 @@ public final class InputLogic {
mConnection.deleteSurroundingText(2, 0);
final String text = lastTwo.charAt(1) + " ";
mConnection.commitText(text, 1);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_swapSwapperAndSpace(lastTwo, text);
- }
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
}
}
@@ -1139,11 +1092,6 @@ public final class InputLogic {
final String textToInsert = inputTransaction.mSettingsValues.mSpacingAndPunctuations
.mSentenceSeparatorAndSpace;
mConnection.commitText(textToInsert, 1);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert,
- false /* isBatchMode */);
- }
- mWordComposer.discardPreviousWordForSuggestion();
return true;
}
return false;
@@ -1180,18 +1128,24 @@ public final class InputLogic {
* @param settingsValues The current settings values.
*/
private void performRecapitalization(final SettingsValues settingsValues) {
- if (!mConnection.hasSelection()) {
- return; // No selection
+ if (!mConnection.hasSelection() || !mRecapitalizeStatus.mIsEnabled()) {
+ return; // No selection or recapitalize is disabled for now
+ }
+ final int selectionStart = mConnection.getExpectedSelectionStart();
+ final int selectionEnd = mConnection.getExpectedSelectionEnd();
+ final int numCharsSelected = selectionEnd - selectionStart;
+ if (numCharsSelected > Constants.MAX_CHARACTERS_FOR_RECAPITALIZATION) {
+ // We bail out if we have too many characters for performance reasons. We don't want
+ // to suck possibly multiple-megabyte data.
+ return;
}
- // If we have a recapitalize in progress, use it; otherwise, create a new one.
- if (!mRecapitalizeStatus.isActive()
- || !mRecapitalizeStatus.isSetAt(mConnection.getExpectedSelectionStart(),
- mConnection.getExpectedSelectionEnd())) {
+ // If we have a recapitalize in progress, use it; otherwise, start a new one.
+ if (!mRecapitalizeStatus.isStarted()
+ || !mRecapitalizeStatus.isSetAt(selectionStart, selectionEnd)) {
final CharSequence selectedText =
mConnection.getSelectedText(0 /* flags, 0 for no styles */);
if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
- mRecapitalizeStatus.initialize(mConnection.getExpectedSelectionStart(),
- mConnection.getExpectedSelectionEnd(), selectedText.toString(),
+ mRecapitalizeStatus.start(selectionStart, selectionEnd, selectedText.toString(),
settingsValues.mLocale,
settingsValues.mSpacingAndPunctuations.mSortedWordSeparators);
// We trim leading and trailing whitespace.
@@ -1199,30 +1153,27 @@ public final class InputLogic {
}
mConnection.finishComposingText();
mRecapitalizeStatus.rotate();
- final int numCharsDeleted = mConnection.getExpectedSelectionEnd()
- - mConnection.getExpectedSelectionStart();
- mConnection.setSelection(mConnection.getExpectedSelectionEnd(),
- mConnection.getExpectedSelectionEnd());
- mConnection.deleteSurroundingText(numCharsDeleted, 0);
+ mConnection.setSelection(selectionEnd, selectionEnd);
+ mConnection.deleteSurroundingText(numCharsSelected, 0);
mConnection.commitText(mRecapitalizeStatus.getRecapitalizedString(), 0);
mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(),
mRecapitalizeStatus.getNewCursorEnd());
}
private void performAdditionToUserHistoryDictionary(final SettingsValues settingsValues,
- final String suggestion, final String prevWord) {
+ final String suggestion, final PrevWordsInfo prevWordsInfo) {
// If correction is not enabled, we don't add words to the user history dictionary.
// That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words.
- if (!settingsValues.mCorrectionEnabled) return;
+ if (!settingsValues.mAutoCorrectionEnabled) return;
if (TextUtils.isEmpty(suggestion)) return;
final boolean wasAutoCapitalized =
mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps();
final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds(
System.currentTimeMillis());
- mSuggest.mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized, prevWord,
- timeStampInSeconds);
+ mDictionaryFacilitator.addToUserHistory(suggestion, wasAutoCapitalized,
+ prevWordsInfo, timeStampInSeconds, settingsValues.mBlockPotentiallyOffensive);
}
public void performUpdateSuggestionStripSync(final SettingsValues settingsValues) {
@@ -1240,7 +1191,7 @@ public final class InputLogic {
return;
}
- final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<SuggestedWords>();
+ final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<>();
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
@Override
@@ -1271,12 +1222,12 @@ public final class InputLogic {
* do nothing.
*
* @param settingsValues the current values of the settings.
- * @param includeResumedWordInSuggestions whether to include the word on which we resume
+ * @param shouldIncludeResumedWordInSuggestions whether to include the word on which we resume
* suggestions in the suggestion list.
*/
// TODO: make this private.
public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
- final boolean includeResumedWordInSuggestions) {
+ final boolean shouldIncludeResumedWordInSuggestions) {
// HACK: We may want to special-case some apps that exhibit bad behavior in case of
// recorrection. This is a temporary, stopgap measure that will be removed later.
// TODO: remove this.
@@ -1300,9 +1251,7 @@ public final class InputLogic {
final int expectedCursorPosition = mConnection.getExpectedSelectionStart();
if (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)) {
// Show predictions.
- mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
- WordComposer.CAPS_MODE_OFF,
- getNthPreviousWordForSuggestion(settingsValues.mSpacingAndPunctuations, 1));
+ mWordComposer.setCapitalizedModeAtStartComposingTime(WordComposer.CAPS_MODE_OFF);
mLatinIME.mHandler.postUpdateSuggestionStrip();
return;
}
@@ -1319,9 +1268,9 @@ public final class InputLogic {
// we just do not resume because it's safer.
final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor();
if (numberOfCharsInWordBeforeCursor > expectedCursorPosition) return;
- final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList();
+ final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
final String typedWord = range.mWord.toString();
- if (includeResumedWordInSuggestions) {
+ if (shouldIncludeResumedWordInSuggestions) {
suggestions.add(new SuggestedWordInfo(typedWord,
SuggestedWords.MAX_SUGGESTIONS + 1,
SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
@@ -1347,20 +1296,22 @@ public final class InputLogic {
}
}
final int[] codePoints = StringUtils.toCodePointArray(typedWord);
+ // We want the previous word for suggestion. If we have chars in the word
+ // before the cursor, then we want the word before that, hence 2; otherwise,
+ // we want the word immediately before the cursor, hence 1.
+ final PrevWordsInfo prevWordsInfo = getPrevWordsInfoFromNthPreviousWordForSuggestion(
+ settingsValues.mSpacingAndPunctuations,
+ 0 == numberOfCharsInWordBeforeCursor ? 1 : 2);
mWordComposer.setComposingWord(codePoints,
- mLatinIME.getCoordinatesForCurrentKeyboard(codePoints),
- getNthPreviousWordForSuggestion(settingsValues.mSpacingAndPunctuations,
- // We want the previous word for suggestion. If we have chars in the word
- // before the cursor, then we want the word before that, hence 2; otherwise,
- // we want the word immediately before the cursor, hence 1.
- 0 == numberOfCharsInWordBeforeCursor ? 1 : 2));
+ mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
mWordComposer.setCursorPositionWithinWord(
typedWord.codePointCount(0, numberOfCharsInWordBeforeCursor));
mConnection.setComposingRegion(expectedCursorPosition - numberOfCharsInWordBeforeCursor,
expectedCursorPosition + range.getNumberOfCharsInWordAfterCursor());
- if (suggestions.isEmpty()) {
- // We come here if there weren't any suggestion spans on this word. We will try to
- // compute suggestions for it instead.
+ if (suggestions.size() <= (shouldIncludeResumedWordInSuggestions ? 1 : 0)) {
+ // If there weren't any suggestion spans on this word, suggestions#size() will be 1
+ // if shouldIncludeResumedWordInSuggestions is true, 0 otherwise. In this case, we
+ // have no useful suggestions, so we will try to compute some for it instead.
mInputLogicHandler.getSuggestedWords(Suggest.SESSION_TYPING,
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
@Override
@@ -1368,7 +1319,7 @@ public final class InputLogic {
final SuggestedWords suggestedWordsIncludingTypedWord) {
final SuggestedWords suggestedWords;
if (suggestedWordsIncludingTypedWord.size() > 1
- && !includeResumedWordInSuggestions) {
+ && !shouldIncludeResumedWordInSuggestions) {
// We were able to compute new suggestions for this word.
// Remove the typed word, since we don't want to display it in this
// case. The #getSuggestedWordsExcludingTypedWord() method sets
@@ -1408,7 +1359,7 @@ public final class InputLogic {
* @param inputTransaction The transaction in progress.
*/
private void revertCommit(final InputTransaction inputTransaction) {
- final String previousWord = mLastComposedWord.mPrevWord;
+ final PrevWordsInfo prevWordsInfo = mLastComposedWord.mPrevWordsInfo;
final CharSequence originallyTypedWord = mLastComposedWord.mTypedWord;
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
final String committedWordString = committedWord.toString();
@@ -1430,9 +1381,8 @@ public final class InputLogic {
}
}
mConnection.deleteSurroundingText(deleteLength, 0);
- if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
- mSuggest.mDictionaryFacilitator.cancelAddingUserHistory(
- previousWord, committedWordString);
+ if (!TextUtils.isEmpty(prevWordsInfo.mPrevWord) && !TextUtils.isEmpty(committedWord)) {
+ mDictionaryFacilitator.cancelAddingUserHistory(prevWordsInfo, committedWordString);
}
final String stringToCommit = originallyTypedWord + mLastComposedWord.mSeparatorString;
final SpannableString textToCommit = new SpannableString(stringToCommit);
@@ -1442,7 +1392,7 @@ public final class InputLogic {
committedWord.length(), Object.class);
final int lastCharIndex = textToCommit.length() - 1;
// We will collect all suggestions in the following array.
- final ArrayList<String> suggestions = CollectionUtils.newArrayList();
+ final ArrayList<String> suggestions = new ArrayList<>();
// First, add the committed word to the list of suggestions.
suggestions.add(committedWordString);
for (final Object span : spans) {
@@ -1481,20 +1431,10 @@ public final class InputLogic {
// with the typed word, so we need to resume suggestions right away.
final int[] codePoints = StringUtils.toCodePointArray(stringToCommit);
mWordComposer.setComposingWord(codePoints,
- mLatinIME.getCoordinatesForCurrentKeyboard(codePoints), previousWord);
+ mLatinIME.getCoordinatesForCurrentKeyboard(codePoints));
mConnection.setComposingText(textToCommit, 1);
}
- if (inputTransaction.mSettingsValues.mIsInternal) {
- LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString,
- Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
- }
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_revertCommit(committedWord.toString(),
- originallyTypedWord.toString(),
- mWordComposer.isBatchMode(), mLastComposedWord.mSeparatorString);
- }
- // Don't restart suggestion yet. We'll restart if the user deletes the
- // separator.
+ // Don't restart suggestion yet. We'll restart if the user deletes the separator.
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
// We have a separator between the word and the cursor: we should show predictions.
inputTransaction.setRequiresUpdateSuggestions();
@@ -1546,7 +1486,7 @@ public final class InputLogic {
}
public int getCurrentRecapitalizeState() {
- if (!mRecapitalizeStatus.isActive()
+ if (!mRecapitalizeStatus.isStarted()
|| !mRecapitalizeStatus.isSetAt(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd())) {
// Not recapitalizing at the moment
@@ -1563,21 +1503,24 @@ public final class InputLogic {
}
/**
- * Get the nth previous word before the cursor as context for the suggestion process.
+ * Get information fo previous words from the nth previous word before the cursor as context
+ * for the suggestion process.
* @param spacingAndPunctuations the current spacing and punctuations settings.
* @param nthPreviousWord reverse index of the word to get (1-indexed)
- * @return the nth previous word before the cursor.
+ * @return the information of previous words
*/
// TODO: Make this private
- public CharSequence getNthPreviousWordForSuggestion(
+ public PrevWordsInfo getPrevWordsInfoFromNthPreviousWordForSuggestion(
final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) {
if (spacingAndPunctuations.mCurrentLanguageHasSpaces) {
// If we are typing in a language with spaces we can just look up the previous
- // word from textview.
- return mConnection.getNthPreviousWord(spacingAndPunctuations, nthPreviousWord);
+ // word information from textview.
+ return mConnection.getPrevWordsInfoFromNthPreviousWord(
+ spacingAndPunctuations, nthPreviousWord);
} else {
- return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ? null
- : mLastComposedWord.mCommittedWord;
+ return LastComposedWord.NOT_A_COMPOSED_WORD == mLastComposedWord ?
+ PrevWordsInfo.BEGINNING_OF_SENTENCE :
+ new PrevWordsInfo(mLastComposedWord.mCommittedWord.toString());
}
}
@@ -1755,9 +1698,6 @@ public final class InputLogic {
*/
// TODO: replace these two parameters with an InputTransaction
private void sendKeyCodePoint(final SettingsValues settingsValues, final int codePoint) {
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_sendKeyCodePoint(codePoint);
- }
// TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (codePoint >= '0' && codePoint <= '9') {
@@ -1789,9 +1729,6 @@ public final class InputLogic {
if (settingsValues.shouldInsertSpacesAutomatically()
&& settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
&& !mConnection.textBeforeCursorLooksLikeURL()) {
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_promotePhantomSpace();
- }
sendKeyCodePoint(settingsValues, Constants.CODE_SPACE);
}
}
@@ -1833,9 +1770,6 @@ public final class InputLogic {
mConnection.setComposingText(batchInputText, 1);
}
mConnection.endBatchEdit();
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.latinIME_onEndBatchInput(batchInputText, 0, suggestedWords);
- }
// Space state must be updated before calling updateShiftState
mSpaceState = SpaceState.PHANTOM;
keyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(settingsValues),
@@ -1862,9 +1796,6 @@ public final class InputLogic {
if (!mWordComposer.isComposingWord()) return;
final String typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) {
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.getInstance().onWordFinished(typedWord, mWordComposer.isBatchMode());
- }
commitChosenWord(settingsValues, typedWord,
LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, separatorString);
}
@@ -1904,15 +1835,6 @@ public final class InputLogic {
throw new RuntimeException("We have an auto-correction but the typed word "
+ "is empty? Impossible! I must commit suicide.");
}
- if (settingsValues.mIsInternal) {
- LatinImeLoggerUtils.onAutoCorrection(
- typedWord, autoCorrection, separator, mWordComposer);
- }
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- final SuggestedWords suggestedWords = mSuggestedWords;
- ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection,
- separator, mWordComposer.isBatchMode(), suggestedWords);
- }
commitChosenWord(settingsValues, autoCorrection,
LastComposedWord.COMMIT_TYPE_DECIDED_WORD, separator);
if (!typedWord.equals(autoCorrection)) {
@@ -1943,33 +1865,19 @@ public final class InputLogic {
final CharSequence chosenWordWithSuggestions =
SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord,
suggestedWords);
- mConnection.commitText(chosenWordWithSuggestions, 1);
- // TODO: we pass 2 here, but would it be better to move this above and pass 1 instead?
- final String prevWord = mConnection.getNthPreviousWord(
+ // Use the 2nd previous word as the previous word because the 1st previous word is the word
+ // to be committed.
+ final PrevWordsInfo prevWordsInfo = mConnection.getPrevWordsInfoFromNthPreviousWord(
settingsValues.mSpacingAndPunctuations, 2);
+ mConnection.commitText(chosenWordWithSuggestions, 1);
// Add the word to the user history dictionary
- performAdditionToUserHistoryDictionary(settingsValues, chosenWord, prevWord);
+ performAdditionToUserHistoryDictionary(settingsValues, chosenWord, prevWordsInfo);
// TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in
// LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings.
mLastComposedWord = mWordComposer.commitWord(commitType,
- chosenWordWithSuggestions, separatorString, prevWord);
- final boolean shouldDiscardPreviousWordForSuggestion;
- if (0 == StringUtils.codePointCount(separatorString)) {
- // Separator is 0-length, we can keep the previous word for suggestion. Either this
- // was a manual pick or the language has no spaces in which case we want to keep the
- // previous word, or it was the keyboard closing or the cursor moving in which case it
- // will be reset anyway.
- shouldDiscardPreviousWordForSuggestion = false;
- } else {
- // Otherwise, we discard if the separator contains any non-whitespace.
- shouldDiscardPreviousWordForSuggestion =
- !StringUtils.containsOnlyWhitespace(separatorString);
- }
- if (shouldDiscardPreviousWordForSuggestion) {
- mWordComposer.discardPreviousWordForSuggestion();
- }
+ chosenWordWithSuggestions, separatorString, prevWordsInfo);
}
/**
@@ -1989,9 +1897,11 @@ public final class InputLogic {
final boolean tryResumeSuggestions, final int remainingTries,
// TODO: remove these arguments
final LatinIME.UIHandler handler) {
+ final boolean shouldFinishComposition = mConnection.hasSelection()
+ || !mConnection.isCursorPositionKnown();
if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(
mConnection.getExpectedSelectionStart(), mConnection.getExpectedSelectionEnd(),
- false /* shouldFinishComposition */)) {
+ shouldFinishComposition)) {
if (0 < remainingTries) {
handler.postResetCaches(tryResumeSuggestions, remainingTries - 1);
return false;
@@ -2001,7 +1911,9 @@ public final class InputLogic {
}
mConnection.tryFixLyingCursorPosition();
if (tryResumeSuggestions) {
- handler.postResumeSuggestions();
+ // This is triggered when starting input anew, so we want to include the resumed
+ // word in suggestions.
+ handler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */);
}
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index f25503488..a2ae74b20 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -186,10 +186,17 @@ public final class FormatSpec {
// From version 4 on, we use version * 100 + revision as a version number. That allows
// us to change the format during development while having testing devices remove
// older files with each upgrade, while still having a readable versioning scheme.
+ // When we bump up the dictionary format version, we should update
+ // ExpandableDictionary.needsToMigrateDictionary() and
+ // ExpandableDictionary.matchesExpectedBinaryDictFormatVersionForThisType().
public static final int VERSION2 = 2;
- public static final int VERSION4 = 401;
+ // Dictionary version used for testing.
+ public static final int VERSION4_ONLY_FOR_TESTING = 399;
+ public static final int VERSION401 = 401;
+ public static final int VERSION4 = 402;
+ public static final int VERSION4_DEV = 403;
static final int MINIMUM_SUPPORTED_VERSION = VERSION2;
- static final int MAXIMUM_SUPPORTED_VERSION = VERSION4;
+ static final int MAXIMUM_SUPPORTED_VERSION = VERSION4_DEV;
// TODO: Make this value adaptative to content data, store it in the header, and
// use it in the reading code.
diff --git a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
index 853392200..31cb59756 100644
--- a/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
+++ b/java/src/com/android/inputmethod/latin/makedict/WordProperty.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.latin.makedict;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.BinaryDictionary;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CombinedFormatUtils;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -35,6 +34,8 @@ public final class WordProperty implements Comparable<WordProperty> {
public final ProbabilityInfo mProbabilityInfo;
public final ArrayList<WeightedString> mShortcutTargets;
public final ArrayList<WeightedString> mBigrams;
+ // TODO: Support mIsBeginningOfSentence.
+ public final boolean mIsBeginningOfSentence;
public final boolean mIsNotAWord;
public final boolean mIsBlacklistEntry;
public final boolean mHasShortcuts;
@@ -51,6 +52,7 @@ public final class WordProperty implements Comparable<WordProperty> {
mProbabilityInfo = probabilityInfo;
mShortcutTargets = shortcutTargets;
mBigrams = bigrams;
+ mIsBeginningOfSentence = false;
mIsNotAWord = isNotAWord;
mIsBlacklistEntry = isBlacklistEntry;
mHasBigrams = bigrams != null && !bigrams.isEmpty();
@@ -75,8 +77,9 @@ public final class WordProperty implements Comparable<WordProperty> {
final ArrayList<Integer> shortcutProbabilities) {
mWord = StringUtils.getStringFromNullTerminatedCodePointArray(codePoints);
mProbabilityInfo = createProbabilityInfoFromArray(probabilityInfo);
- mShortcutTargets = CollectionUtils.newArrayList();
- mBigrams = CollectionUtils.newArrayList();
+ mShortcutTargets = new ArrayList<>();
+ mBigrams = new ArrayList<>();
+ mIsBeginningOfSentence = false;
mIsNotAWord = isNotAWord;
mIsBlacklistEntry = isBlacklisted;
mHasShortcuts = hasShortcuts;
diff --git a/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java b/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java
index a446672cb..ab3ef964e 100644
--- a/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java
+++ b/java/src/com/android/inputmethod/latin/personalization/AccountUtils.java
@@ -35,7 +35,7 @@ public class AccountUtils {
}
public static List<String> getDeviceAccountsEmailAddresses(final Context context) {
- final ArrayList<String> retval = new ArrayList<String>();
+ final ArrayList<String> retval = new ArrayList<>();
for (final Account account : getAccounts(context)) {
final String name = account.name;
if (Patterns.EMAIL_ADDRESS.matcher(name).matches()) {
@@ -54,7 +54,7 @@ public class AccountUtils {
*/
public static List<String> getDeviceAccountsWithDomain(
final Context context, final String domain) {
- final ArrayList<String> retval = new ArrayList<String>();
+ final ArrayList<String> retval = new ArrayList<>();
final String atDomain = "@" + domain.toLowerCase(Locale.ROOT);
for (final Account account : getAccounts(context)) {
if (account.name.toLowerCase(Locale.ROOT).endsWith(atDomain)) {
diff --git a/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java b/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java
new file mode 100644
index 000000000..a96018fe9
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/personalization/ContextualDictionary.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.personalization;
+
+import android.content.Context;
+
+import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.ExpandableBinaryDictionary;
+
+import java.io.File;
+import java.util.Locale;
+
+public class ContextualDictionary extends ExpandableBinaryDictionary {
+ /* package */ static final String NAME = ContextualDictionary.class.getSimpleName();
+
+ private ContextualDictionary(final Context context, final Locale locale,
+ final File dictFile) {
+ super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_CONTEXTUAL,
+ dictFile);
+ // Always reset the contents.
+ clear();
+ }
+
+ @UsedForTesting
+ public static ContextualDictionary getDictionary(final Context context, final Locale locale,
+ final File dictFile, final String dictNamePrefix) {
+ return new ContextualDictionary(context, locale, dictFile);
+ }
+
+ @Override
+ protected boolean enableBeginningOfSentencePrediction() {
+ return true;
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ // Strings out of this dictionary should not be considered existing words.
+ return false;
+ }
+
+ @Override
+ protected void loadInitialContentsLocked() {
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
index 352288f8b..1ba7b366f 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
@@ -18,15 +18,11 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context;
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
-import com.android.inputmethod.latin.utils.LanguageModelParam;
import java.io.File;
-import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
@@ -35,7 +31,6 @@ import java.util.Map;
* model.
*/
public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableBinaryDictionary {
- private static final String TAG = DecayingExpandableBinaryDictionaryBase.class.getSimpleName();
private static final boolean DBG_DUMP_ON_CLOSE = false;
/** Any pair being typed or picked */
@@ -47,8 +42,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
/** The locale for this dictionary. */
public final Locale mLocale;
- private Map<String, String> mAdditionalAttributeMap = null;
-
protected DecayingExpandableBinaryDictionaryBase(final Context context,
final String dictName, final Locale locale, final String dictionaryType,
final File dictFile) {
@@ -72,9 +65,6 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
@Override
protected Map<String, String> getHeaderAttributeMap() {
final Map<String, String> attributeMap = super.getHeaderAttributeMap();
- if (mAdditionalAttributeMap != null) {
- attributeMap.putAll(mAdditionalAttributeMap);
- }
attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
@@ -83,23 +73,17 @@ public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableB
}
@Override
- protected boolean haveContentsChanged() {
- return false;
- }
-
- @Override
protected void loadInitialContentsLocked() {
// No initial contents.
}
- @UsedForTesting
- public void clearAndFlushDictionaryWithAdditionalAttributes(
- final Map<String, String> attributeMap) {
- mAdditionalAttributeMap = attributeMap;
- clear();
- }
-
/* package */ void runGCIfRequired() {
runGCIfRequired(false /* mindsBlockByGC */);
}
+
+ @Override
+ public boolean isValidWord(final String word) {
+ // Strings out of this dictionary should not be considered existing words.
+ return false;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
index de2744f29..221bb9a8f 100644
--- a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
+++ b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
@@ -61,6 +61,7 @@ public class DictionaryDecayBroadcastReciever extends BroadcastReceiver {
final String action = intent.getAction();
if (action.equals(DICTIONARY_DECAY_INTENT_ACTION)) {
PersonalizationHelper.runGCOnAllOpenedUserHistoryDictionaries();
+ PersonalizationHelper.runGCOnAllOpenedPersonalizationDictionaries();
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java
new file mode 100644
index 000000000..9d72de8c5
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDataChunk.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.personalization;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+public class PersonalizationDataChunk {
+ public final boolean mInputByUser;
+ public final List<String> mTokens;
+ public final int mTimestampInSeconds;
+ public final String mPackageName;
+ public final Locale mlocale = null;
+
+ public PersonalizationDataChunk(boolean inputByUser, final List<String> tokens,
+ final int timestampInSeconds, final String packageName) {
+ mInputByUser = inputByUser;
+ mTokens = Collections.unmodifiableList(tokens);
+ mTimestampInSeconds = timestampInSeconds;
+ mPackageName = packageName;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
index 4afd5b4c9..f2ad22ac7 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionary.java
@@ -18,6 +18,7 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Dictionary;
import java.io.File;
@@ -26,19 +27,15 @@ import java.util.Locale;
public class PersonalizationDictionary extends DecayingExpandableBinaryDictionaryBase {
/* package */ static final String NAME = PersonalizationDictionary.class.getSimpleName();
+ // TODO: Make this constructor private
/* package */ PersonalizationDictionary(final Context context, final Locale locale) {
- this(context, locale, null /* dictFile */);
+ super(context, getDictName(NAME, locale, null /* dictFile */), locale,
+ Dictionary.TYPE_PERSONALIZATION, null /* dictFile */);
}
- public PersonalizationDictionary(final Context context, final Locale locale,
- final File dictFile) {
- super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_PERSONALIZATION,
- dictFile);
- }
-
- @Override
- public boolean isValidWord(final String word) {
- // Strings out of this dictionary should not be considered existing words.
- return false;
+ @UsedForTesting
+ public static PersonalizationDictionary getDictionary(final Context context,
+ final Locale locale, final File dictFile, final String dictNamePrefix) {
+ return PersonalizationHelper.getPersonalizationDictionary(context, locale);
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java
index 9bef7a198..450644032 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationDictionarySessionRegistrar.java
@@ -19,18 +19,15 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context;
import android.content.res.Configuration;
-import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest;
-import com.android.inputmethod.latin.utils.DistracterFilter;
+import com.android.inputmethod.latin.DictionaryFacilitator;
public class PersonalizationDictionarySessionRegistrar {
public static void init(final Context context,
- final DictionaryFacilitatorForSuggest dictionaryFacilitator,
- final DistracterFilter distracterFilter) {
+ final DictionaryFacilitator dictionaryFacilitator) {
}
public static void onConfigurationChanged(final Context context, final Configuration conf,
- final DictionaryFacilitatorForSuggest dictionaryFacilitator,
- final DistracterFilter distracterFilter) {
+ final DictionaryFacilitator dictionaryFacilitator) {
}
public static void onUpdateData(final Context context, final String type) {
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index 7c43182bc..aac40940b 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -16,13 +16,11 @@
package com.android.inputmethod.latin.personalization;
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.utils.CollectionUtils;
-import com.android.inputmethod.latin.utils.FileUtils;
-
import android.content.Context;
import android.util.Log;
+import com.android.inputmethod.latin.utils.FileUtils;
+
import java.io.File;
import java.io.FilenameFilter;
import java.lang.ref.SoftReference;
@@ -34,9 +32,9 @@ public class PersonalizationHelper {
private static final String TAG = PersonalizationHelper.class.getSimpleName();
private static final boolean DEBUG = false;
private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>>
- sLangUserHistoryDictCache = CollectionUtils.newConcurrentHashMap();
+ sLangUserHistoryDictCache = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, SoftReference<PersonalizationDictionary>>
- sLangPersonalizationDictCache = CollectionUtils.newConcurrentHashMap();
+ sLangPersonalizationDictCache = new ConcurrentHashMap<>();
public static UserHistoryDictionary getUserHistoryDictionary(
final Context context, final Locale locale) {
@@ -55,8 +53,7 @@ public class PersonalizationHelper {
}
}
final UserHistoryDictionary dict = new UserHistoryDictionary(context, locale);
- sLangUserHistoryDictCache.put(localeStr,
- new SoftReference<UserHistoryDictionary>(dict));
+ sLangUserHistoryDictCache.put(localeStr, new SoftReference<>(dict));
return dict;
}
}
@@ -66,8 +63,8 @@ public class PersonalizationHelper {
if (TimeUnit.MILLISECONDS.toSeconds(
DictionaryDecayBroadcastReciever.DICTIONARY_DECAY_INTERVAL)
< currentTimestamp - sCurrentTimestampForTesting) {
- // TODO: Run GC for both PersonalizationDictionary and UserHistoryDictionary.
runGCOnAllOpenedUserHistoryDictionaries();
+ runGCOnAllOpenedPersonalizationDictionaries();
}
}
@@ -75,7 +72,6 @@ public class PersonalizationHelper {
runGCOnAllDictionariesIfRequired(sLangUserHistoryDictCache);
}
- @UsedForTesting
public static void runGCOnAllOpenedPersonalizationDictionaries() {
runGCOnAllDictionariesIfRequired(sLangPersonalizationDictCache);
}
@@ -110,8 +106,7 @@ public class PersonalizationHelper {
}
}
final PersonalizationDictionary dict = new PersonalizationDictionary(context, locale);
- sLangPersonalizationDictCache.put(
- localeStr, new SoftReference<PersonalizationDictionary>(dict));
+ sLangPersonalizationDictCache.put(localeStr, new SoftReference<>(dict));
return dict;
}
}
@@ -140,11 +135,13 @@ public class PersonalizationHelper {
}
}
dictionaryMap.clear();
- if (!FileUtils.deleteFilteredFiles(
- context.getFilesDir(), new DictFilter(dictNamePrefix))) {
+ final File filesDir = context.getFilesDir();
+ if (filesDir == null) {
+ Log.e(TAG, "context.getFilesDir() returned null.");
+ }
+ if (!FileUtils.deleteFilteredFiles(filesDir, new DictFilter(dictNamePrefix))) {
Log.e(TAG, "Cannot remove all existing dictionary files. filesDir: "
- + context.getFilesDir().getAbsolutePath() + ", dictNamePrefix: "
- + dictNamePrefix);
+ + filesDir.getAbsolutePath() + ", dictNamePrefix: " + dictNamePrefix);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index 8a29c354d..3916fc24c 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -18,9 +18,12 @@ package com.android.inputmethod.latin.personalization;
import android.content.Context;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
+import com.android.inputmethod.latin.PrevWordsInfo;
+import com.android.inputmethod.latin.utils.DistracterFilter;
import java.io.File;
import java.util.Locale;
@@ -32,46 +35,47 @@ import java.util.Locale;
public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase {
/* package */ static final String NAME = UserHistoryDictionary.class.getSimpleName();
+ // TODO: Make this constructor private
/* package */ UserHistoryDictionary(final Context context, final Locale locale) {
- this(context, locale, null /* dictFile */);
+ super(context, getDictName(NAME, locale, null /* dictFile */), locale,
+ Dictionary.TYPE_USER_HISTORY, null /* dictFile */);
}
- public UserHistoryDictionary(final Context context, final Locale locale,
- final File dictFile) {
- super(context, getDictName(NAME, locale, dictFile), locale, Dictionary.TYPE_USER_HISTORY,
- dictFile);
- }
-
- @Override
- public boolean isValidWord(final String word) {
- // Strings out of this dictionary should not be considered existing words.
- return false;
+ @UsedForTesting
+ public static UserHistoryDictionary getDictionary(final Context context, final Locale locale,
+ final File dictFile, final String dictNamePrefix) {
+ return PersonalizationHelper.getUserHistoryDictionary(context, locale);
}
/**
- * Pair will be added to the user history dictionary.
+ * Add a word to the user history dictionary.
*
- * The first word may be null. That means we don't know the context, in other words,
- * it's only a unigram. The first word may also be an empty string : this means start
- * context, as in beginning of a sentence for example.
- * The second word may not be null (a NullPointerException would be thrown).
+ * @param userHistoryDictionary the user history dictionary
+ * @param prevWordsInfo the information of previous words
+ * @param word the word the user inputted
+ * @param isValid whether the word is valid or not
+ * @param timestamp the timestamp when the word has been inputted
+ * @param distracterFilter the filter to check whether the word is a distracter
*/
public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary,
- final String word0, final String word1, final boolean isValid, final int timestamp) {
- if (word1.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
- (word0 != null && word0.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
+ final PrevWordsInfo prevWordsInfo, final String word, final boolean isValid,
+ final int timestamp, final DistracterFilter distracterFilter) {
+ final String prevWord = prevWordsInfo.mPrevWord;
+ if (word.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH ||
+ (prevWord != null && prevWord.length() >= Constants.DICTIONARY_MAX_WORD_LENGTH)) {
return;
}
final int frequency = isValid ?
FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS;
- userHistoryDictionary.addWordDynamically(word1, frequency, null /* shortcutTarget */,
- 0 /* shortcutFreq */, false /* isNotAWord */, false /* isBlacklisted */, timestamp);
+ userHistoryDictionary.addUnigramEntryWithCheckingDistracter(word, frequency,
+ null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */,
+ false /* isBlacklisted */, timestamp, distracterFilter);
// Do not insert a word as a bigram of itself
- if (word1.equals(word0)) {
+ if (word.equals(prevWord)) {
return;
}
- if (null != word0) {
- userHistoryDictionary.addBigramDynamically(word0, word1, frequency, timestamp);
+ if (null != prevWord) {
+ userHistoryDictionary.addNgramEntry(prevWordsInfo, word, frequency, timestamp);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
index 39977e76f..31fa86774 100644
--- a/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/AdditionalSubtypeSettings.java
@@ -47,7 +47,6 @@ import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.DialogUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -101,7 +100,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment {
super(context, android.R.layout.simple_spinner_item);
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- final TreeSet<SubtypeLocaleItem> items = CollectionUtils.newTreeSet();
+ final TreeSet<SubtypeLocaleItem> items = new TreeSet<>();
final InputMethodInfo imi = RichInputMethodManager.getInstance()
.getInputMethodInfoOfThisIme();
final int count = imi.getSubtypeCount();
@@ -369,7 +368,6 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment {
mSubtype = (InputMethodSubtype)source.readParcelable(null);
}
- @SuppressWarnings("hiding")
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
@@ -516,8 +514,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment {
localeString, keyboardLayoutSetName);
}
- private AlertDialog createDialog(
- @SuppressWarnings("unused") final SubtypePreference subtypePref) {
+ private AlertDialog createDialog(final SubtypePreference subtypePref) {
final AlertDialog.Builder builder = new AlertDialog.Builder(
DialogUtils.getPlatformDialogThemeContext(getActivity()));
builder.setTitle(R.string.custom_input_styles_title)
@@ -555,7 +552,7 @@ public final class AdditionalSubtypeSettings extends PreferenceFragment {
private InputMethodSubtype[] getSubtypes() {
final PreferenceGroup group = getPreferenceScreen();
- final ArrayList<InputMethodSubtype> subtypes = CollectionUtils.newArrayList();
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>();
final int count = group.getPreferenceCount();
for (int i = 0; i < count; i++) {
final Preference pref = group.getPreference(i);
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index c4c1234fc..845ddb377 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -25,11 +25,12 @@ import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
+import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryDumpBroadcastReceiver;
-import com.android.inputmethod.latin.LatinImeLogger;
+import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug;
import com.android.inputmethod.latin.utils.ApplicationUtils;
@@ -40,8 +41,6 @@ public final class DebugSettings extends PreferenceFragment
public static final String PREF_DEBUG_MODE = "debug_mode";
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
- public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
- public static final String PREF_STATISTICS_LOGGING = "enable_logging";
public static final String PREF_KEY_PREVIEW_SHOW_UP_START_SCALE =
"pref_key_preview_show_up_start_scale";
public static final String PREF_KEY_PREVIEW_DISMISS_END_SCALE =
@@ -51,18 +50,14 @@ public final class DebugSettings extends PreferenceFragment
public static final String PREF_KEY_PREVIEW_DISMISS_DURATION =
"pref_key_preview_dismiss_duration";
private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary";
- private static final String PREF_DUMP_CONTACTS_DICT = "dump_contacts_dict";
- private static final String PREF_DUMP_USER_DICT = "dump_user_dict";
- private static final String PREF_DUMP_USER_HISTORY_DICT = "dump_user_history_dict";
- private static final String PREF_DUMP_PERSONALIZATION_DICT = "dump_personalization_dict";
+ private static final String PREF_KEY_DUMP_DICTS = "pref_key_dump_dictionaries";
+ private static final String PREF_KEY_DUMP_DICT_PREFIX = "pref_key_dump_dictionaries";
+ private static final String DICT_NAME_KEY_FOR_EXTRAS = "dict_name";
public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview";
public static final String PREF_KEY_LONGPRESS_TIMEOUT = "pref_key_longpress_timeout";
- private static final boolean SHOW_STATISTICS_LOGGING = false;
-
private boolean mServiceNeedsRestart = false;
private CheckBoxPreference mDebugMode;
- private CheckBoxPreference mStatisticsLoggingPref;
@Override
public void onCreate(Bundle icicle) {
@@ -71,21 +66,6 @@ public final class DebugSettings extends PreferenceFragment
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
prefs.registerOnSharedPreferenceChangeListener(this);
- final Preference usabilityStudyPref = findPreference(PREF_USABILITY_STUDY_MODE);
- if (usabilityStudyPref instanceof CheckBoxPreference) {
- final CheckBoxPreference checkbox = (CheckBoxPreference)usabilityStudyPref;
- checkbox.setChecked(prefs.getBoolean(PREF_USABILITY_STUDY_MODE,
- LatinImeLogger.getUsabilityStudyMode(prefs)));
- checkbox.setSummary(R.string.settings_warning_researcher_mode);
- }
- final Preference statisticsLoggingPref = findPreference(PREF_STATISTICS_LOGGING);
- if (statisticsLoggingPref instanceof CheckBoxPreference) {
- mStatisticsLoggingPref = (CheckBoxPreference) statisticsLoggingPref;
- if (!SHOW_STATISTICS_LOGGING) {
- getPreferenceScreen().removePreference(statisticsLoggingPref);
- }
- }
-
final PreferenceScreen readExternalDictionary =
(PreferenceScreen) findPreference(PREF_READ_EXTERNAL_DICTIONARY);
if (null != readExternalDictionary) {
@@ -101,16 +81,18 @@ public final class DebugSettings extends PreferenceFragment
});
}
+ final PreferenceGroup dictDumpPreferenceGroup =
+ (PreferenceGroup)findPreference(PREF_KEY_DUMP_DICTS);
final OnPreferenceClickListener dictDumpPrefClickListener =
new DictDumpPrefClickListener(this);
- findPreference(PREF_DUMP_CONTACTS_DICT).setOnPreferenceClickListener(
- dictDumpPrefClickListener);
- findPreference(PREF_DUMP_USER_DICT).setOnPreferenceClickListener(
- dictDumpPrefClickListener);
- findPreference(PREF_DUMP_USER_HISTORY_DICT).setOnPreferenceClickListener(
- dictDumpPrefClickListener);
- findPreference(PREF_DUMP_PERSONALIZATION_DICT).setOnPreferenceClickListener(
- dictDumpPrefClickListener);
+ for (final String dictName : DictionaryFacilitator.DICT_TYPE_TO_CLASS.keySet()) {
+ final Preference preference = new Preference(getActivity());
+ preference.setKey(PREF_KEY_DUMP_DICT_PREFIX + dictName);
+ preference.setTitle("Dump " + dictName + " dictionary");
+ preference.setOnPreferenceClickListener(dictDumpPrefClickListener);
+ preference.getExtras().putString(DICT_NAME_KEY_FOR_EXTRAS, dictName);
+ dictDumpPreferenceGroup.addPreference(preference);
+ }
final Resources res = getResources();
setupKeyLongpressTimeoutSettings(prefs, res);
setupKeyPreviewAnimationDuration(prefs, res, PREF_KEY_PREVIEW_SHOW_UP_DURATION,
@@ -138,18 +120,7 @@ public final class DebugSettings extends PreferenceFragment
@Override
public boolean onPreferenceClick(final Preference arg0) {
- final String dictName;
- if (arg0.getKey().equals(PREF_DUMP_CONTACTS_DICT)) {
- dictName = Dictionary.TYPE_CONTACTS;
- } else if (arg0.getKey().equals(PREF_DUMP_USER_DICT)) {
- dictName = Dictionary.TYPE_USER;
- } else if (arg0.getKey().equals(PREF_DUMP_USER_HISTORY_DICT)) {
- dictName = Dictionary.TYPE_USER_HISTORY;
- } else if (arg0.getKey().equals(PREF_DUMP_PERSONALIZATION_DICT)) {
- dictName = Dictionary.TYPE_PERSONALIZATION;
- } else {
- dictName = null;
- }
+ final String dictName = arg0.getExtras().getString(DICT_NAME_KEY_FOR_EXTRAS);
if (dictName != null) {
final Intent intent =
new Intent(DictionaryDumpBroadcastReceiver.DICTIONARY_DUMP_INTENT_ACTION);
@@ -163,27 +134,22 @@ public final class DebugSettings extends PreferenceFragment
@Override
public void onStop() {
super.onStop();
- if (mServiceNeedsRestart) Process.killProcess(Process.myPid());
+ if (mServiceNeedsRestart) {
+ Process.killProcess(Process.myPid());
+ }
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- if (key.equals(PREF_DEBUG_MODE)) {
- if (mDebugMode != null) {
- mDebugMode.setChecked(prefs.getBoolean(PREF_DEBUG_MODE, false));
- final boolean checked = mDebugMode.isChecked();
- if (mStatisticsLoggingPref != null) {
- if (checked) {
- getPreferenceScreen().addPreference(mStatisticsLoggingPref);
- } else {
- getPreferenceScreen().removePreference(mStatisticsLoggingPref);
- }
- }
- updateDebugMode();
- mServiceNeedsRestart = true;
- }
- } else if (key.equals(PREF_FORCE_NON_DISTINCT_MULTITOUCH)) {
+ if (key.equals(PREF_DEBUG_MODE) && mDebugMode != null) {
+ mDebugMode.setChecked(prefs.getBoolean(PREF_DEBUG_MODE, false));
+ updateDebugMode();
mServiceNeedsRestart = true;
+ return;
+ }
+ if (key.equals(PREF_FORCE_NON_DISTINCT_MULTITOUCH)) {
+ mServiceNeedsRestart = true;
+ return;
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
index cd726c969..04a2ee3ce 100644
--- a/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
+++ b/java/src/com/android/inputmethod/latin/settings/NativeSuggestOptions.java
@@ -20,7 +20,8 @@ public class NativeSuggestOptions {
// Need to update suggest_options.h when you add, remove or reorder options.
private static final int IS_GESTURE = 0;
private static final int USE_FULL_EDIT_DISTANCE = 1;
- private static final int OPTIONS_SIZE = 2;
+ private static final int BLOCK_OFFENSIVE_WORDS = 2;
+ private static final int OPTIONS_SIZE = 3;
private final int[] mOptions = new int[OPTIONS_SIZE
+ AdditionalFeaturesSettingUtils.ADDITIONAL_FEATURES_SETTINGS_SIZE];
@@ -33,6 +34,10 @@ public class NativeSuggestOptions {
setBooleanOption(USE_FULL_EDIT_DISTANCE, value);
}
+ public void setBlockOffensiveWords(final boolean value) {
+ setBooleanOption(BLOCK_OFFENSIVE_WORDS, value);
+ }
+
public void setAdditionalFeaturesOptions(final int[] additionalOptions) {
if (additionalOptions == null) {
return;
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index a3aae8cb3..235847799 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
+import android.os.Build;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -60,11 +61,15 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
"pref_key_use_double_space_period";
public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE =
"pref_key_block_potentially_offensive";
+ public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS =
+ (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
+ || (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT
+ && Build.VERSION.CODENAME.equals("REL"));
public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
"pref_show_language_switch_key";
public static final String PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST =
"pref_include_other_imes_in_language_switch_list";
- public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916";
+ public static final String PREF_KEYBOARD_THEME = "pref_keyboard_theme";
public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
// TODO: consolidate key preview dismiss delay with the key preview animation parameters.
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
@@ -87,6 +92,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_DEBUG_SETTINGS = "debug_settings";
public static final String PREF_KEY_IS_INTERNAL = "pref_key_is_internal";
+ public static final String PREF_ENABLE_METRICS_LOGGING = "pref_enable_metrics_logging";
+
// This preference key is deprecated. Use {@link #PREF_SHOW_LANGUAGE_SWITCH_KEY} instead.
// This is being used only for the backward compatibility.
private static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY =
@@ -325,10 +332,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
R.array.keypress_vibration_durations, DEFAULT_KEYPRESS_VIBRATION_DURATION));
}
- public static boolean readUsabilityStudyMode(final SharedPreferences prefs) {
- return prefs.getBoolean(DebugSettings.PREF_USABILITY_STUDY_MODE, true);
- }
-
public static float readKeyPreviewAnimationScale(final SharedPreferences prefs,
final String prefKey, final float defaultValue) {
final float fraction = prefs.getFloat(prefKey, UNDEFINED_PREFERENCE_VALUE_FLOAT);
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 22cbd204c..5eb0377c7 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -37,6 +37,7 @@ import android.util.Log;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
+import com.android.inputmethod.keyboard.KeyboardTheme;
import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
@@ -58,7 +59,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment
private static final boolean DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS = false;
private static final boolean USE_INTERNAL_PERSONAL_DICTIONARY_SETTIGS =
DBG_USE_INTERNAL_PERSONAL_DICTIONARY_SETTINGS
- || Build.VERSION.SDK_INT <= 18 /* Build.VERSION.JELLY_BEAN_MR2 */;
+ || Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2;
private void setPreferenceEnabled(final String preferenceKey, final boolean enabled) {
final Preference preference = findPreference(preferenceKey);
@@ -151,10 +152,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
miscSettings.removePreference(aboutSettings);
}
}
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- // The about screen contains items that may be confusing in development-only versions.
- miscSettings.removePreference(aboutSettings);
- }
final boolean showVoiceKeyOption = res.getBoolean(
R.bool.config_enable_show_voice_key_option);
@@ -168,6 +165,13 @@ public final class SettingsFragment extends InputMethodSettingsFragment
removePreference(Settings.PREF_VIBRATE_ON, generalSettings);
removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings);
}
+ if (!Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS) {
+ removePreference(
+ Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, advancedSettings);
+ removePreference(
+ Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, advancedSettings);
+ }
+
// TODO: consolidate key preview dismiss delay with the key preview animation parameters.
if (!Settings.readFromBuildConfigIfToShowKeyPreviewPopupOption(res)) {
@@ -198,9 +202,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
removePreference(Settings.PREF_SHOW_SETUP_WIZARD_ICON, advancedSettings);
}
- setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
- Settings.readShowsLanguageSwitchKey(prefs));
-
final PreferenceGroup textCorrectionGroup =
(PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS);
final PreferenceScreen dictionaryLink =
@@ -212,6 +213,20 @@ public final class SettingsFragment extends InputMethodSettingsFragment
textCorrectionGroup.removePreference(dictionaryLink);
}
+ if (ProductionFlag.IS_METRICS_LOGGING_SUPPORTED) {
+ final Preference enableMetricsLogging =
+ findPreference(Settings.PREF_ENABLE_METRICS_LOGGING);
+ if (enableMetricsLogging != null) {
+ final int applicationLabelRes = context.getApplicationInfo().labelRes;
+ final String applicationName = res.getString(applicationLabelRes);
+ final String enableMetricsLoggingTitle = res.getString(
+ R.string.enable_metrics_logging, applicationName);
+ enableMetricsLogging.setTitle(enableMetricsLoggingTitle);
+ }
+ } else {
+ removePreference(Settings.PREF_ENABLE_METRICS_LOGGING, textCorrectionGroup);
+ }
+
final Preference editPersonalDictionary =
findPreference(Settings.PREF_EDIT_PERSONAL_DICTIONARY);
final Intent editPersonalDictionaryIntent = editPersonalDictionary.getIntent();
@@ -253,11 +268,31 @@ public final class SettingsFragment extends InputMethodSettingsFragment
}
updateListPreferenceSummaryToCurrentValue(Settings.PREF_SHOW_SUGGESTIONS_SETTING);
updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
- updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEYBOARD_LAYOUT);
+ final ListPreference keyboardThemePref = (ListPreference)findPreference(
+ Settings.PREF_KEYBOARD_THEME);
+ if (keyboardThemePref != null) {
+ final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(prefs);
+ final String value = Integer.toString(keyboardTheme.mThemeId);
+ final CharSequence entries[] = keyboardThemePref.getEntries();
+ final int entryIndex = keyboardThemePref.findIndexOfValue(value);
+ keyboardThemePref.setSummary(entryIndex < 0 ? null : entries[entryIndex]);
+ keyboardThemePref.setValue(value);
+ }
updateCustomInputStylesSummary(prefs, res);
}
@Override
+ public void onPause() {
+ super.onPause();
+ final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ final ListPreference keyboardThemePref = (ListPreference)findPreference(
+ Settings.PREF_KEYBOARD_THEME);
+ if (keyboardThemePref != null) {
+ KeyboardTheme.saveKeyboardThemeId(keyboardThemePref.getValue(), prefs);
+ }
+ }
+
+ @Override
public void onDestroy() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
this);
@@ -278,16 +313,13 @@ public final class SettingsFragment extends InputMethodSettingsFragment
if (key.equals(Settings.PREF_POPUP_ON)) {
setPreferenceEnabled(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY,
Settings.readKeyPreviewPopupEnabled(prefs, res));
- } else if (key.equals(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY)) {
- setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
- Settings.readShowsLanguageSwitchKey(prefs));
} else if (key.equals(Settings.PREF_SHOW_SETUP_WIZARD_ICON)) {
LauncherIconVisibilityManager.updateSetupWizardIconVisibility(getActivity());
}
ensureConsistencyOfAutoCorrectionSettings();
updateListPreferenceSummaryToCurrentValue(Settings.PREF_SHOW_SUGGESTIONS_SETTING);
updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
- updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEYBOARD_LAYOUT);
+ updateListPreferenceSummaryToCurrentValue(Settings.PREF_KEYBOARD_THEME);
refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources());
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index dde50ccaf..44104019b 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -28,6 +28,7 @@ import com.android.inputmethod.compat.AppWorkaroundsUtils;
import com.android.inputmethod.latin.InputAttributes;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
+import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.utils.AsyncResultHolder;
import com.android.inputmethod.latin.utils.ResourceUtils;
import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask;
@@ -73,6 +74,7 @@ public final class SettingsValues {
public final boolean mPhraseGestureEnabled;
public final int mKeyLongpressTimeout;
public final Locale mLocale;
+ public final boolean mEnableMetricsLogging;
// From the input box
public final InputAttributes mInputAttributes;
@@ -83,7 +85,8 @@ public final class SettingsValues {
public final int mKeyPreviewPopupDismissDelay;
private final boolean mAutoCorrectEnabled;
public final float mAutoCorrectionThreshold;
- public final boolean mCorrectionEnabled;
+ // TODO: Rename this to mAutoCorrectionEnabledPerUserSettings.
+ public final boolean mAutoCorrectionEnabled;
public final int mSuggestionVisibility;
public final int mDisplayOrientation;
private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds;
@@ -108,7 +111,8 @@ public final class SettingsValues {
// Store the input attributes
if (null == inputAttributes) {
- mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
+ mInputAttributes = new InputAttributes(
+ null, false /* isFullscreenMode */, context.getPackageName());
} else {
mInputAttributes = inputAttributes;
}
@@ -120,13 +124,18 @@ public final class SettingsValues {
mKeyPreviewPopupOn = Settings.readKeyPreviewPopupEnabled(prefs, res);
mSlidingKeyInputPreviewEnabled = prefs.getBoolean(
DebugSettings.PREF_SLIDING_KEY_INPUT_PREVIEW, true);
- mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res);
+ mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res)
+ && !mInputAttributes.mIsPasswordField
+ && !mInputAttributes.hasNoMicrophoneKeyOption()
+ && SubtypeSwitcher.getInstance().isShortcutImeEnabled();
final String autoCorrectionThresholdRawValue = prefs.getString(
Settings.PREF_AUTO_CORRECTION_THRESHOLD,
res.getString(R.string.auto_correction_threshold_mode_index_modest));
- mIncludesOtherImesInLanguageSwitchList = prefs.getBoolean(
- Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false);
- mShowsLanguageSwitchKey = Settings.readShowsLanguageSwitchKey(prefs);
+ mIncludesOtherImesInLanguageSwitchList = Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS
+ ? prefs.getBoolean(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false)
+ : true /* forcibly */;
+ mShowsLanguageSwitchKey = Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS
+ ? Settings.readShowsLanguageSwitchKey(prefs) : true /* forcibly */;
mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true);
mUsePersonalizedDicts = prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true);
@@ -134,7 +143,7 @@ public final class SettingsValues {
mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
mDoubleSpacePeriodTimeout = res.getInteger(R.integer.config_double_space_period_timeout);
-
+ mEnableMetricsLogging = prefs.getBoolean(Settings.PREF_ENABLE_METRICS_LOGGING, true);
// Compute other readable settings
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
@@ -147,7 +156,7 @@ public final class SettingsValues {
mGestureFloatingPreviewTextEnabled = prefs.getBoolean(
Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, true);
mPhraseGestureEnabled = Settings.readPhraseGestureEnabled(prefs, res);
- mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
+ mAutoCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
final String showSuggestionsSetting = prefs.getString(
Settings.PREF_SHOW_SUGGESTIONS_SETTING,
res.getString(R.string.prefs_suggestion_visibility_default_value));
@@ -170,7 +179,7 @@ public final class SettingsValues {
ResourceUtils.getFloatFromFraction(
res, R.fraction.config_key_preview_dismiss_end_scale));
mDisplayOrientation = res.getConfiguration().orientation;
- mAppWorkarounds = new AsyncResultHolder<AppWorkaroundsUtils>();
+ mAppWorkarounds = new AsyncResultHolder<>();
final PackageInfo packageInfo = TargetPackageInfoGetterTask.getCachedPackageInfo(
mInputAttributes.mTargetApplicationPackageName);
if (null != packageInfo) {
@@ -185,12 +194,14 @@ public final class SettingsValues {
return mInputAttributes.mApplicationSpecifiedCompletionOn;
}
+ // TODO: Rename this to needsToLookupSuggestions().
public boolean isSuggestionsRequested() {
- return mInputAttributes.mIsSettingsSuggestionStripOn
- && (mCorrectionEnabled || isSuggestionStripVisible());
+ return mInputAttributes.mShouldShowSuggestions
+ && (mAutoCorrectionEnabled
+ || isCurrentOrientationAllowingSuggestionsPerUserSettings());
}
- public boolean isSuggestionStripVisible() {
+ public boolean isCurrentOrientationAllowingSuggestionsPerUserSettings() {
return (mSuggestionVisibility == SUGGESTION_VISIBILITY_SHOW_VALUE)
|| (mSuggestionVisibility == SUGGESTION_VISIBILITY_SHOW_ONLY_PORTRAIT_VALUE
&& mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT);
@@ -205,7 +216,8 @@ public final class SettingsValues {
}
public boolean isWordCodePoint(final int code) {
- return Character.isLetter(code) || isWordConnector(code);
+ return Character.isLetter(code) || isWordConnector(code)
+ || Character.COMBINING_SPACING_MARK == Character.getType(code);
}
public boolean isUsuallyPrecededBySpace(final int code) {
@@ -313,18 +325,18 @@ public final class SettingsValues {
private static boolean needsToShowVoiceInputKey(final SharedPreferences prefs,
final Resources res) {
- if (!prefs.contains(Settings.PREF_VOICE_INPUT_KEY)) {
- // Migrate preference from {@link Settings#PREF_VOICE_MODE_OBSOLETE} to
- // {@link Settings#PREF_VOICE_INPUT_KEY}.
+ // Migrate preference from {@link Settings#PREF_VOICE_MODE_OBSOLETE} to
+ // {@link Settings#PREF_VOICE_INPUT_KEY}.
+ if (prefs.contains(Settings.PREF_VOICE_MODE_OBSOLETE)) {
final String voiceModeMain = res.getString(R.string.voice_mode_main);
final String voiceMode = prefs.getString(
Settings.PREF_VOICE_MODE_OBSOLETE, voiceModeMain);
final boolean shouldShowVoiceInputKey = voiceModeMain.equals(voiceMode);
- prefs.edit().putBoolean(Settings.PREF_VOICE_INPUT_KEY, shouldShowVoiceInputKey).apply();
- }
- // Remove the obsolete preference if exists.
- if (prefs.contains(Settings.PREF_VOICE_MODE_OBSOLETE)) {
- prefs.edit().remove(Settings.PREF_VOICE_MODE_OBSOLETE).apply();
+ prefs.edit()
+ .putBoolean(Settings.PREF_VOICE_INPUT_KEY, shouldShowVoiceInputKey)
+ // Remove the obsolete preference if exists.
+ .remove(Settings.PREF_VOICE_MODE_OBSOLETE)
+ .apply();
}
return prefs.getBoolean(Settings.PREF_VOICE_INPUT_KEY, true);
}
@@ -385,8 +397,8 @@ public final class SettingsValues {
sb.append("" + mAutoCorrectEnabled);
sb.append("\n mAutoCorrectionThreshold = ");
sb.append("" + mAutoCorrectionThreshold);
- sb.append("\n mCorrectionEnabled = ");
- sb.append("" + mCorrectionEnabled);
+ sb.append("\n mAutoCorrectionEnabled = ");
+ sb.append("" + mAutoCorrectionEnabled);
sb.append("\n mSuggestionVisibility = ");
sb.append("" + mSuggestionVisibility);
sb.append("\n mDisplayOrientation = ");
diff --git a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
index 796921f71..b8d2a2248 100644
--- a/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
+++ b/java/src/com/android/inputmethod/latin/settings/SpacingAndPunctuations.java
@@ -30,6 +30,7 @@ import java.util.Locale;
public final class SpacingAndPunctuations {
private final int[] mSortedSymbolsPrecededBySpace;
private final int[] mSortedSymbolsFollowedBySpace;
+ private final int[] mSortedSymbolsClusteringTogether;
private final int[] mSortedWordConnectors;
public final int[] mSortedWordSeparators;
public final PunctuationSuggestions mSuggestPuncList;
@@ -46,6 +47,8 @@ public final class SpacingAndPunctuations {
// To be able to binary search the code point. See {@link #isUsuallyFollowedBySpace(int)}.
mSortedSymbolsFollowedBySpace = StringUtils.toSortedCodePointArray(
res.getString(R.string.symbols_followed_by_space));
+ mSortedSymbolsClusteringTogether = StringUtils.toSortedCodePointArray(
+ res.getString(R.string.symbols_clustering_together));
// To be able to binary search the code point. See {@link #isWordConnector(int)}.
mSortedWordConnectors = StringUtils.toSortedCodePointArray(
res.getString(R.string.symbols_word_connectors));
@@ -85,6 +88,10 @@ public final class SpacingAndPunctuations {
return Arrays.binarySearch(mSortedSymbolsFollowedBySpace, code) >= 0;
}
+ public boolean isClusteringSymbol(final int code) {
+ return Arrays.binarySearch(mSortedSymbolsClusteringTogether, code) >= 0;
+ }
+
public boolean isSentenceSeparator(final int code) {
return code == mSentenceSeparator;
}
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
index 974dfddd3..73d25f6aa 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupStartIndicatorView.java
@@ -21,13 +21,13 @@ import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
+import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.R;
public final class SetupStartIndicatorView extends LinearLayout {
@@ -96,13 +96,13 @@ public final class SetupStartIndicatorView extends LinearLayout {
@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
- final int layoutDirection = ViewCompatUtils.getLayoutDirection(this);
+ final int layoutDirection = ViewCompat.getLayoutDirection(this);
final int width = getWidth();
final int height = getHeight();
final float halfHeight = height / 2.0f;
final Path path = mIndicatorPath;
path.rewind();
- if (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) {
+ if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) {
// Left arrow
path.moveTo(width, 0.0f);
path.lineTo(0.0f, halfHeight);
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java
index c909507c6..6734e61b8 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupStepIndicatorView.java
@@ -20,10 +20,10 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
+import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.View;
-import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.R;
public final class SetupStepIndicatorView extends View {
@@ -38,12 +38,12 @@ public final class SetupStepIndicatorView extends View {
}
public void setIndicatorPosition(final int stepPos, final int totalStepNum) {
- final int layoutDirection = ViewCompatUtils.getLayoutDirection(this);
+ final int layoutDirection = ViewCompat.getLayoutDirection(this);
// The indicator position is the center of the partition that is equally divided into
// the total step number.
final float partionWidth = 1.0f / totalStepNum;
final float pos = stepPos * partionWidth + partionWidth / 2.0f;
- mXRatio = (layoutDirection == ViewCompatUtils.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos;
+ mXRatio = (layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL) ? 1.0f - pos : pos;
invalidate();
}
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index 5072fabd6..bcac05a6a 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -37,7 +37,6 @@ import com.android.inputmethod.compat.TextViewCompatUtils;
import com.android.inputmethod.compat.ViewCompatUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.settings.SettingsActivity;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
import java.util.ArrayList;
@@ -482,7 +481,7 @@ public final class SetupWizardActivity extends Activity implements View.OnClickL
static final class SetupStepGroup {
private final SetupStepIndicatorView mIndicatorView;
- private final ArrayList<SetupStep> mGroup = CollectionUtils.newArrayList();
+ private final ArrayList<SetupStep> mGroup = new ArrayList<>();
public SetupStepGroup(final SetupStepIndicatorView indicatorView) {
mIndicatorView = indicatorView;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 65ebcf5f1..8d495646d 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -27,7 +27,6 @@ import android.view.inputmethod.InputMethodSubtype;
import android.view.textservice.SuggestionsInfo;
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
-import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.ContactsBinaryDictionary;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryCollection;
@@ -77,7 +76,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
private final Object mUseContactsLock = new Object();
private final HashSet<WeakReference<DictionaryCollection>> mDictionaryCollectionsList =
- CollectionUtils.newHashSet();
+ new HashSet<>();
public static final int SCRIPT_LATIN = 0;
public static final int SCRIPT_CYRILLIC = 1;
@@ -94,7 +93,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
// proximity to pass to the dictionary descent algorithm.
// IMPORTANT: this only contains languages - do not write countries in there.
// Only the language is searched from the map.
- mLanguageToScript = CollectionUtils.newTreeMap();
+ mLanguageToScript = new TreeMap<>();
mLanguageToScript.put("cs", SCRIPT_LATIN);
mLanguageToScript.put("da", SCRIPT_LATIN);
mLanguageToScript.put("de", SCRIPT_LATIN);
@@ -255,7 +254,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
mOriginalText = originalText;
mRecommendedThreshold = recommendedThreshold;
mMaxLength = maxLength;
- mSuggestions = CollectionUtils.newArrayList(maxLength + 1);
+ mSuggestions = new ArrayList<>(maxLength + 1);
mScores = new int[mMaxLength];
}
@@ -441,8 +440,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
}
}
dictionaryCollection.addDictionary(mContactsDictionary);
- mDictionaryCollectionsList.add(
- new WeakReference<DictionaryCollection>(dictionaryCollection));
+ mDictionaryCollectionsList.add(new WeakReference<>(dictionaryCollection));
}
return new DictAndKeyboard(dictionaryCollection, keyboardLayoutSet);
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
index ddda52d71..55274cfe2 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java
@@ -16,6 +16,7 @@
package com.android.inputmethod.latin.spellcheck;
+import android.content.res.Resources;
import android.os.Binder;
import android.text.TextUtils;
import android.util.Log;
@@ -23,17 +24,21 @@ import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
-import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.PrevWordsInfo;
import java.util.ArrayList;
+import java.util.Locale;
public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheckerSession {
private static final String TAG = AndroidSpellCheckerSession.class.getSimpleName();
private static final boolean DBG = false;
private final static String[] EMPTY_STRING_ARRAY = new String[0];
+ private final Resources mResources;
+ private SentenceLevelAdapter mSentenceLevelAdapter;
public AndroidSpellCheckerSession(AndroidSpellCheckerService service) {
super(service);
+ mResources = service.getResources();
}
private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti,
@@ -43,10 +48,9 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
return null;
}
final int N = ssi.getSuggestionsCount();
- final ArrayList<Integer> additionalOffsets = CollectionUtils.newArrayList();
- final ArrayList<Integer> additionalLengths = CollectionUtils.newArrayList();
- final ArrayList<SuggestionsInfo> additionalSuggestionsInfos =
- CollectionUtils.newArrayList();
+ final ArrayList<Integer> additionalOffsets = new ArrayList<>();
+ final ArrayList<Integer> additionalLengths = new ArrayList<>();
+ final ArrayList<SuggestionsInfo> additionalSuggestionsInfos = new ArrayList<>();
String currentWord = null;
for (int i = 0; i < N; ++i) {
final SuggestionsInfo si = ssi.getSuggestionsInfoAt(i);
@@ -57,7 +61,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
final int offset = ssi.getOffsetAt(i);
final int length = ssi.getLengthAt(i);
final String subText = typedText.substring(offset, offset + length);
- final String prevWord = currentWord;
+ final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(currentWord);
currentWord = subText;
if (!subText.contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
continue;
@@ -73,7 +77,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
if (TextUtils.isEmpty(splitText)) {
continue;
}
- if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWord) == null) {
+ if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWordsInfo) == null) {
continue;
}
final int newLength = splitText.length();
@@ -116,8 +120,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
@Override
public SentenceSuggestionsInfo[] onGetSentenceSuggestionsMultiple(TextInfo[] textInfos,
int suggestionsLimit) {
- final SentenceSuggestionsInfo[] retval =
- super.onGetSentenceSuggestionsMultiple(textInfos, suggestionsLimit);
+ final SentenceSuggestionsInfo[] retval = splitAndSuggest(textInfos, suggestionsLimit);
if (retval == null || retval.length != textInfos.length) {
return retval;
}
@@ -131,6 +134,58 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
return retval;
}
+ /**
+ * Get sentence suggestions for specified texts in an array of TextInfo. This is taken from
+ * SpellCheckerService#onGetSentenceSuggestionsMultiple that we can't use because it's
+ * using private variables.
+ * The default implementation splits the input text to words and returns
+ * {@link SentenceSuggestionsInfo} which contains suggestions for each word.
+ * This function will run on the incoming IPC thread.
+ * So, this is not called on the main thread,
+ * but will be called in series on another thread.
+ * @param textInfos an array of the text metadata
+ * @param suggestionsLimit the maximum number of suggestions to be returned
+ * @return an array of {@link SentenceSuggestionsInfo} returned by
+ * {@link SpellCheckerService.Session#onGetSuggestions(TextInfo, int)}
+ */
+ private SentenceSuggestionsInfo[] splitAndSuggest(TextInfo[] textInfos, int suggestionsLimit) {
+ if (textInfos == null || textInfos.length == 0) {
+ return SentenceLevelAdapter.EMPTY_SENTENCE_SUGGESTIONS_INFOS;
+ }
+ SentenceLevelAdapter sentenceLevelAdapter;
+ synchronized(this) {
+ sentenceLevelAdapter = mSentenceLevelAdapter;
+ if (sentenceLevelAdapter == null) {
+ final String localeStr = getLocale();
+ if (!TextUtils.isEmpty(localeStr)) {
+ sentenceLevelAdapter = new SentenceLevelAdapter(mResources,
+ new Locale(localeStr));
+ mSentenceLevelAdapter = sentenceLevelAdapter;
+ }
+ }
+ }
+ if (sentenceLevelAdapter == null) {
+ return SentenceLevelAdapter.EMPTY_SENTENCE_SUGGESTIONS_INFOS;
+ }
+ final int infosSize = textInfos.length;
+ final SentenceSuggestionsInfo[] retval = new SentenceSuggestionsInfo[infosSize];
+ for (int i = 0; i < infosSize; ++i) {
+ final SentenceLevelAdapter.SentenceTextInfoParams textInfoParams =
+ sentenceLevelAdapter.getSplitWords(textInfos[i]);
+ final ArrayList<SentenceLevelAdapter.SentenceWordItem> mItems =
+ textInfoParams.mItems;
+ final int itemsSize = mItems.size();
+ final TextInfo[] splitTextInfos = new TextInfo[itemsSize];
+ for (int j = 0; j < itemsSize; ++j) {
+ splitTextInfos[j] = mItems.get(j).mTextInfo;
+ }
+ retval[i] = SentenceLevelAdapter.reconstructSuggestions(
+ textInfoParams, onGetSuggestionsMultiple(
+ splitTextInfos, suggestionsLimit, true));
+ }
+ return retval;
+ }
+
@Override
public SuggestionsInfo[] onGetSuggestionsMultiple(TextInfo[] textInfos,
int suggestionsLimit, boolean sequentialWords) {
@@ -148,7 +203,8 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
} else {
prevWord = null;
}
- retval[i] = onGetSuggestionsInternal(textInfos[i], prevWord, suggestionsLimit);
+ final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(prevWord);
+ retval[i] = onGetSuggestionsInternal(textInfos[i], prevWordsInfo, suggestionsLimit);
retval[i].setCookieAndSequence(textInfos[i].getCookie(),
textInfos[i].getSequence());
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 69d092751..54eebe399 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -28,9 +28,9 @@ import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
@@ -68,29 +68,29 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
private static final char CHAR_DELIMITER = '\uFFFC';
private static final int MAX_CACHE_SIZE = 50;
private final LruCache<String, SuggestionsParams> mUnigramSuggestionsInfoCache =
- new LruCache<String, SuggestionsParams>(MAX_CACHE_SIZE);
+ new LruCache<>(MAX_CACHE_SIZE);
// TODO: Support n-gram input
- private static String generateKey(String query, String prevWord) {
- if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWord)) {
+ private static String generateKey(final String query, final PrevWordsInfo prevWordsInfo) {
+ if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWordsInfo.mPrevWord)) {
return query;
}
- return query + CHAR_DELIMITER + prevWord;
+ return query + CHAR_DELIMITER + prevWordsInfo.mPrevWord;
}
- // TODO: Support n-gram input
- public SuggestionsParams getSuggestionsFromCache(String query, String prevWord) {
- return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWord));
+ public SuggestionsParams getSuggestionsFromCache(String query,
+ final PrevWordsInfo prevWordsInfo) {
+ return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWordsInfo));
}
- // TODO: Support n-gram input
public void putSuggestionsToCache(
- String query, String prevWord, String[] suggestions, int flags) {
+ final String query, final PrevWordsInfo prevWordsInfo,
+ final String[] suggestions, final int flags) {
if (suggestions == null || TextUtils.isEmpty(query)) {
return;
}
mUnigramSuggestionsInfoCache.put(
- generateKey(query, prevWord), new SuggestionsParams(suggestions, flags));
+ generateKey(query, prevWordsInfo), new SuggestionsParams(suggestions, flags));
}
public void clearCache() {
@@ -259,11 +259,12 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
}
protected SuggestionsInfo onGetSuggestionsInternal(
- final TextInfo textInfo, final String prevWord, final int suggestionsLimit) {
+ final TextInfo textInfo, final PrevWordsInfo prevWordsInfo,
+ final int suggestionsLimit) {
try {
final String inText = textInfo.getText();
final SuggestionsParams cachedSuggestionsParams =
- mSuggestionsCache.getSuggestionsFromCache(inText, prevWord);
+ mSuggestionsCache.getSuggestionsFromCache(inText, prevWordsInfo);
if (cachedSuggestionsParams != null) {
if (DBG) {
Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags);
@@ -281,6 +282,22 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
return AndroidSpellCheckerService.getNotInDictEmptySuggestions(
false /* reportAsTypo */);
}
+ if (CHECKABILITY_CONTAINS_PERIOD == checkability) {
+ final String[] splitText = inText.split(Constants.REGEXP_PERIOD);
+ boolean allWordsAreValid = true;
+ for (final String word : splitText) {
+ if (!dictInfo.mDictionary.isValidWord(word)) {
+ allWordsAreValid = false;
+ break;
+ }
+ }
+ if (allWordsAreValid) {
+ return new SuggestionsInfo(SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO
+ | SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS,
+ new String[] {
+ TextUtils.join(Constants.STRING_SPACE, splitText) });
+ }
+ }
return dictInfo.mDictionary.isValidWord(inText)
? AndroidSpellCheckerService.getInDictEmptySuggestions()
: AndroidSpellCheckerService.getNotInDictEmptySuggestions(
@@ -322,12 +339,12 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
} else {
coordinates = dictInfo.mKeyboard.getCoordinates(codePoints);
}
- composer.setComposingWord(codePoints, coordinates, null /* previousWord */);
+ composer.setComposingWord(codePoints, coordinates);
// TODO: make a spell checker option to block offensive words or not
final ArrayList<SuggestedWordInfo> suggestions =
- dictInfo.mDictionary.getSuggestions(composer, prevWord,
+ dictInfo.mDictionary.getSuggestions(composer, prevWordsInfo,
dictInfo.getProximityInfo(), true /* blockOffensiveWords */,
- null /* additionalFeaturesOptions */,
+ null /* additionalFeaturesOptions */, 0 /* sessionId */,
null /* inOutLanguageWeight */);
if (suggestions != null) {
for (final SuggestedWordInfo suggestion : suggestions) {
@@ -369,7 +386,8 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
.getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS()
: 0);
final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions);
- mSuggestionsCache.putSuggestionsToCache(text, prevWord, result.mSuggestions, flags);
+ mSuggestionsCache.putSuggestionsToCache(text, prevWordsInfo, result.mSuggestions,
+ flags);
return retval;
} catch (RuntimeException e) {
// Don't kill the keyboard if there is a bug in the spell checker
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java b/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java
index 1ffe50681..b33739fc1 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java
@@ -16,11 +16,11 @@
package com.android.inputmethod.latin.spellcheck;
-import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.Dictionary;
/**
* A container for a Dictionary and a Keyboard.
@@ -28,19 +28,15 @@ import com.android.inputmethod.keyboard.ProximityInfo;
public final class DictAndKeyboard {
public final Dictionary mDictionary;
public final Keyboard mKeyboard;
- private final Keyboard mManualShiftedKeyboard;
public DictAndKeyboard(
final Dictionary dictionary, final KeyboardLayoutSet keyboardLayoutSet) {
mDictionary = dictionary;
if (keyboardLayoutSet == null) {
mKeyboard = null;
- mManualShiftedKeyboard = null;
return;
}
mKeyboard = keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
- mManualShiftedKeyboard =
- keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED);
}
public ProximityInfo getProximityInfo() {
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index c99264347..cc52a3e0f 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -20,9 +20,9 @@ import android.util.Log;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
-import com.android.inputmethod.latin.utils.CollectionUtils;
import java.util.ArrayList;
import java.util.Locale;
@@ -46,19 +46,19 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> {
private final Locale mLocale;
private int mSize;
private volatile boolean mClosed;
- final static ArrayList<SuggestedWordInfo> noSuggestions = CollectionUtils.newArrayList();
+ final static ArrayList<SuggestedWordInfo> noSuggestions = new ArrayList<>();
private final static DictAndKeyboard dummyDict = new DictAndKeyboard(
new Dictionary(Dictionary.TYPE_MAIN) {
// TODO: this dummy dictionary should be a singleton in the Dictionary class.
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
- final String prevWord, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
+ final int sessionId, final float[] inOutLanguageWeight) {
return noSuggestions;
}
@Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
// This is never called. However if for some strange reason it ever gets
// called, returning true is less destructive (it will not underline the
// word in red).
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java b/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java
new file mode 100644
index 000000000..13352f39e
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SentenceLevelAdapter.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.spellcheck;
+
+import android.content.res.Resources;
+import android.view.textservice.SentenceSuggestionsInfo;
+import android.view.textservice.SuggestionsInfo;
+import android.view.textservice.TextInfo;
+
+import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
+import com.android.inputmethod.latin.utils.RunInLocale;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+/**
+ * This code is mostly lifted directly from android.service.textservice.SpellCheckerService in
+ * the framework; maybe that should be protected instead, so that implementers don't have to
+ * rewrite everything for any small change.
+ */
+public class SentenceLevelAdapter {
+ public static final SentenceSuggestionsInfo[] EMPTY_SENTENCE_SUGGESTIONS_INFOS =
+ new SentenceSuggestionsInfo[] {};
+ private static final SuggestionsInfo EMPTY_SUGGESTIONS_INFO = new SuggestionsInfo(0, null);
+ /**
+ * Container for split TextInfo parameters
+ */
+ public static class SentenceWordItem {
+ public final TextInfo mTextInfo;
+ public final int mStart;
+ public final int mLength;
+ public SentenceWordItem(TextInfo ti, int start, int end) {
+ mTextInfo = ti;
+ mStart = start;
+ mLength = end - start;
+ }
+ }
+
+ /**
+ * Container for originally queried TextInfo and parameters
+ */
+ public static class SentenceTextInfoParams {
+ final TextInfo mOriginalTextInfo;
+ final ArrayList<SentenceWordItem> mItems;
+ final int mSize;
+ public SentenceTextInfoParams(TextInfo ti, ArrayList<SentenceWordItem> items) {
+ mOriginalTextInfo = ti;
+ mItems = items;
+ mSize = items.size();
+ }
+ }
+
+ private static class WordIterator {
+ private final SpacingAndPunctuations mSpacingAndPunctuations;
+ public WordIterator(final Resources res, final Locale locale) {
+ final RunInLocale<SpacingAndPunctuations> job
+ = new RunInLocale<SpacingAndPunctuations>() {
+ @Override
+ protected SpacingAndPunctuations job(final Resources res) {
+ return new SpacingAndPunctuations(res);
+ }
+ };
+ mSpacingAndPunctuations = job.runInLocale(res, locale);
+ }
+
+ public int getEndOfWord(final CharSequence sequence, int index) {
+ final int length = sequence.length();
+ index = index < 0 ? 0 : Character.offsetByCodePoints(sequence, index, 1);
+ while (index < length) {
+ final int codePoint = Character.codePointAt(sequence, index);
+ if (mSpacingAndPunctuations.isWordSeparator(codePoint)) {
+ // If it's a period, we want to stop here only if it's followed by another
+ // word separator. In all other cases we stop here.
+ if (Constants.CODE_PERIOD == codePoint) {
+ final int indexOfNextCodePoint =
+ index + Character.charCount(Constants.CODE_PERIOD);
+ if (indexOfNextCodePoint < length
+ && mSpacingAndPunctuations.isWordSeparator(
+ Character.codePointAt(sequence, indexOfNextCodePoint))) {
+ return index;
+ }
+ } else {
+ return index;
+ }
+ }
+ index += Character.charCount(codePoint);
+ }
+ return index;
+ }
+
+ public int getBeginningOfNextWord(final CharSequence sequence, int index) {
+ final int length = sequence.length();
+ if (index >= length) {
+ return -1;
+ }
+ index = index < 0 ? 0 : Character.offsetByCodePoints(sequence, index, 1);
+ while (index < length) {
+ final int codePoint = Character.codePointAt(sequence, index);
+ if (!mSpacingAndPunctuations.isWordSeparator(codePoint)) {
+ return index;
+ }
+ index += Character.charCount(codePoint);
+ }
+ return -1;
+ }
+ }
+
+ private final WordIterator mWordIterator;
+ public SentenceLevelAdapter(final Resources res, final Locale locale) {
+ mWordIterator = new WordIterator(res, locale);
+ }
+
+ public SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) {
+ final WordIterator wordIterator = mWordIterator;
+ final CharSequence originalText = originalTextInfo.getText();
+ final int cookie = originalTextInfo.getCookie();
+ final int start = -1;
+ final int end = originalText.length();
+ final ArrayList<SentenceWordItem> wordItems = new ArrayList<SentenceWordItem>();
+ int wordStart = wordIterator.getBeginningOfNextWord(originalText, start);
+ int wordEnd = wordIterator.getEndOfWord(originalText, wordStart);
+ while (wordStart <= end && wordEnd != -1 && wordStart != -1) {
+ if (wordEnd >= start && wordEnd > wordStart) {
+ final String query = originalText.subSequence(wordStart, wordEnd).toString();
+ final TextInfo ti = new TextInfo(query, cookie, query.hashCode());
+ wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd));
+ }
+ wordStart = wordIterator.getBeginningOfNextWord(originalText, wordEnd);
+ if (wordStart == -1) {
+ break;
+ }
+ wordEnd = wordIterator.getEndOfWord(originalText, wordStart);
+ }
+ return new SentenceTextInfoParams(originalTextInfo, wordItems);
+ }
+
+ public static SentenceSuggestionsInfo reconstructSuggestions(
+ SentenceTextInfoParams originalTextInfoParams, SuggestionsInfo[] results) {
+ if (results == null || results.length == 0) {
+ return null;
+ }
+ if (originalTextInfoParams == null) {
+ return null;
+ }
+ final int originalCookie = originalTextInfoParams.mOriginalTextInfo.getCookie();
+ final int originalSequence =
+ originalTextInfoParams.mOriginalTextInfo.getSequence();
+
+ final int querySize = originalTextInfoParams.mSize;
+ final int[] offsets = new int[querySize];
+ final int[] lengths = new int[querySize];
+ final SuggestionsInfo[] reconstructedSuggestions = new SuggestionsInfo[querySize];
+ for (int i = 0; i < querySize; ++i) {
+ final SentenceWordItem item = originalTextInfoParams.mItems.get(i);
+ SuggestionsInfo result = null;
+ for (int j = 0; j < results.length; ++j) {
+ final SuggestionsInfo cur = results[j];
+ if (cur != null && cur.getSequence() == item.mTextInfo.getSequence()) {
+ result = cur;
+ result.setCookieAndSequence(originalCookie, originalSequence);
+ break;
+ }
+ }
+ offsets[i] = item.mStart;
+ lengths[i] = item.mLength;
+ reconstructedSuggestions[i] = result != null ? result : EMPTY_SUGGESTIONS_INFO;
+ }
+ return new SentenceSuggestionsInfo(reconstructedSuggestions, offsets, lengths);
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java
index a694bf47d..a6437bac3 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -20,6 +20,7 @@ import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.ContactsBinaryDictionary;
+import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
@@ -36,19 +37,19 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
- final String prevWordForBigrams, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
+ final int sessionId, final float[] inOutLanguageWeight) {
synchronized (mLock) {
- return super.getSuggestions(codes, prevWordForBigrams, proximityInfo,
- blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight);
+ return super.getSuggestions(codes, prevWordsInfo, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight);
}
}
@Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
synchronized (mLock) {
- return super.isValidWord(word);
+ return super.isInDictionary(word);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java
index 1a6dd5818..8c9d5d681 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin.spellcheck;
import android.content.Context;
import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.UserBinaryDictionary;
import com.android.inputmethod.latin.WordComposer;
@@ -41,19 +42,19 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
- final String prevWordForBigrams, final ProximityInfo proximityInfo,
+ final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo,
final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
- final float[] inOutLanguageWeight) {
+ final int sessionId, final float[] inOutLanguageWeight) {
synchronized (mLock) {
- return super.getSuggestions(codes, prevWordForBigrams, proximityInfo,
- blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight);
+ return super.getSuggestions(codes, prevWordsInfo, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight);
}
}
@Override
- public boolean isValidWord(final String word) {
+ public boolean isInDictionary(final String word) {
synchronized (mLock) {
- return super.isValidWord(word);
+ return super.isInDictionary(word);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
index 5a325ea82..346aea34a 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestions.java
@@ -23,24 +23,17 @@ import android.graphics.drawable.Drawable;
import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.internal.KeyboardParams;
+import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.utils.TypefaceUtils;
public final class MoreSuggestions extends Keyboard {
- public static final int SUGGESTION_CODE_BASE = 1024;
-
public final SuggestedWords mSuggestedWords;
- public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter {
- public abstract void onSuggestionSelected(final int index, final SuggestedWordInfo info);
- }
-
MoreSuggestions(final MoreSuggestionsParam params, final SuggestedWords suggestedWords) {
super(params);
mSuggestedWords = suggestedWords;
@@ -178,7 +171,7 @@ public final class MoreSuggestions extends Keyboard {
}
}
- private static boolean isIndexSubjectToAutoCorrection(final SuggestedWords suggestedWords,
+ static boolean isIndexSubjectToAutoCorrection(final SuggestedWords suggestedWords,
final int index) {
return suggestedWords.mWillAutoCorrect && index == SuggestedWords.INDEX_OF_AUTO_CORRECTION;
}
@@ -226,11 +219,7 @@ public final class MoreSuggestions extends Keyboard {
word = mSuggestedWords.getLabel(index);
info = mSuggestedWords.getDebugString(index);
}
- final int indexInMoreSuggestions = index + SUGGESTION_CODE_BASE;
- final Key key = new Key(word, KeyboardIconsSet.ICON_UNDEFINED,
- indexInMoreSuggestions, null /* outputText */, info, 0 /* labelFlags */,
- Key.BACKGROUND_TYPE_NORMAL, x, y, width, params.mDefaultRowHeight,
- params.mHorizontalGap, params.mVerticalGap);
+ final Key key = new MoreSuggestionKey(word, info, index, params);
params.markAsEdgeKey(key, index);
params.onAddKey(key);
final int columnNumber = params.getColumnNumber(index);
@@ -245,6 +234,19 @@ public final class MoreSuggestions extends Keyboard {
}
}
+ static final class MoreSuggestionKey extends Key {
+ public final int mSuggestedWordIndex;
+
+ public MoreSuggestionKey(final String word, final String info, final int index,
+ final MoreSuggestionsParam params) {
+ super(word /* label */, KeyboardIconsSet.ICON_UNDEFINED, Constants.CODE_OUTPUT_TEXT,
+ word /* outputText */, info, 0 /* labelFlags */, Key.BACKGROUND_TYPE_NORMAL,
+ params.getX(index), params.getY(index), params.getWidth(index),
+ params.mDefaultRowHeight, params.mHorizontalGap, params.mVerticalGap);
+ mSuggestedWordIndex = index;
+ }
+ }
+
private static final class Divider extends Key.Spacer {
private final Drawable mIcon;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
index 549ff0d9d..528d500d2 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/MoreSuggestionsView.java
@@ -20,11 +20,16 @@ import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
+import com.android.inputmethod.accessibility.AccessibilityUtils;
+import com.android.inputmethod.accessibility.MoreSuggestionsAccessibilityDelegate;
+import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.keyboard.Keyboard;
+import com.android.inputmethod.keyboard.KeyboardActionListener;
import com.android.inputmethod.keyboard.MoreKeysKeyboardView;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionKey;
/**
* A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
@@ -33,6 +38,10 @@ import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestions
public final class MoreSuggestionsView extends MoreKeysKeyboardView {
private static final String TAG = MoreSuggestionsView.class.getSimpleName();
+ public static abstract class MoreSuggestionsListener extends KeyboardActionListener.Adapter {
+ public abstract void onSuggestionSelected(final int index, final SuggestedWordInfo info);
+ }
+
public MoreSuggestionsView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.moreKeysKeyboardViewStyle);
}
@@ -43,6 +52,26 @@ public final class MoreSuggestionsView extends MoreKeysKeyboardView {
}
@Override
+ public void setKeyboard(final Keyboard keyboard) {
+ super.setKeyboard(keyboard);
+ // With accessibility mode off, {@link #mAccessibilityDelegate} is set to null at the
+ // above {@link MoreKeysKeyboardView#setKeyboard(Keyboard)} call.
+ // With accessibility mode on, {@link #mAccessibilityDelegate} is set to a
+ // {@link MoreKeysKeyboardAccessibilityDelegate} object at the above
+ // {@link MoreKeysKeyboardView#setKeyboard(Keyboard)} call. And the object has to be
+ // overwritten by a {@link MoreSuggestionsAccessibilityDelegate} object here.
+ if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
+ if (!(mAccessibilityDelegate instanceof MoreSuggestionsAccessibilityDelegate)) {
+ mAccessibilityDelegate = new MoreSuggestionsAccessibilityDelegate(
+ this, mKeyDetector);
+ mAccessibilityDelegate.setOpenAnnounce(R.string.spoken_open_more_suggestions);
+ mAccessibilityDelegate.setCloseAnnounce(R.string.spoken_close_more_suggestions);
+ }
+ mAccessibilityDelegate.setKeyboard(keyboard);
+ }
+ }
+
+ @Override
protected int getDefaultCoordX() {
final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
return pane.mOccupiedWidth / 2;
@@ -59,7 +88,12 @@ public final class MoreSuggestionsView extends MoreKeysKeyboardView {
}
@Override
- public void onCodeInput(final int code, final int x, final int y) {
+ protected void onKeyInput(final Key key, final int x, final int y) {
+ if (!(key instanceof MoreSuggestionKey)) {
+ Log.e(TAG, "Expected key is MoreSuggestionKey, but found "
+ + key.getClass().getName());
+ return;
+ }
final Keyboard keyboard = getKeyboard();
if (!(keyboard instanceof MoreSuggestions)) {
Log.e(TAG, "Expected keyboard is MoreSuggestions, but found "
@@ -67,7 +101,7 @@ public final class MoreSuggestionsView extends MoreKeysKeyboardView {
return;
}
final SuggestedWords suggestedWords = ((MoreSuggestions)keyboard).mSuggestedWords;
- final int index = code - MoreSuggestions.SUGGESTION_CODE_BASE;
+ final int index = ((MoreSuggestionKey)key).mSuggestedWordIndex;
if (index < 0 || index >= suggestedWords.size()) {
Log.e(TAG, "Selected suggestion has an illegal index: " + index);
return;
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index 1d84bb59f..19b48f081 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -309,9 +309,8 @@ final class SuggestionStripLayoutHelper {
setupWordViewsTextAndColor(suggestedWords, mSuggestionsCountInStrip);
final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);
- final int availableStripWidth = placerView.getWidth()
- - placerView.getPaddingRight() - placerView.getPaddingLeft();
- final int centerWidth = getSuggestionWidth(mCenterPositionInStrip, availableStripWidth);
+ final int stripWidth = stripView.getWidth();
+ final int centerWidth = getSuggestionWidth(mCenterPositionInStrip, stripWidth);
final int countInStrip;
if (suggestedWords.size() == 1 || getTextScaleX(centerWordView.getText(), centerWidth,
centerWordView.getPaint()) < MIN_TEXT_XSCALE) {
@@ -319,11 +318,11 @@ final class SuggestionStripLayoutHelper {
// by consolidating all slots in the strip.
countInStrip = 1;
mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip);
- layoutWord(mCenterPositionInStrip, availableStripWidth - mPadding);
+ layoutWord(mCenterPositionInStrip, stripWidth - mPadding);
stripView.addView(centerWordView);
setLayoutWeight(centerWordView, 1.0f, ViewGroup.LayoutParams.MATCH_PARENT);
if (SuggestionStripView.DBG) {
- layoutDebugInfo(mCenterPositionInStrip, placerView, availableStripWidth);
+ layoutDebugInfo(mCenterPositionInStrip, placerView, stripWidth);
}
} else {
countInStrip = mSuggestionsCountInStrip;
@@ -337,7 +336,7 @@ final class SuggestionStripLayoutHelper {
x += divider.getMeasuredWidth();
}
- final int width = getSuggestionWidth(positionInStrip, availableStripWidth);
+ final int width = getSuggestionWidth(positionInStrip, stripWidth);
final TextView wordView = layoutWord(positionInStrip, width);
stripView.addView(wordView);
setLayoutWeight(wordView, getSuggestionWeight(positionInStrip),
@@ -380,9 +379,9 @@ final class SuggestionStripLayoutHelper {
} else {
wordView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
}
-
- // Disable this suggestion if the suggestion is null or empty.
- wordView.setEnabled(!TextUtils.isEmpty(word));
+ // {@link StyleSpan} in a content description may cause an issue of TTS/TalkBack.
+ // Use a simple {@link String} to avoid the issue.
+ wordView.setContentDescription(TextUtils.isEmpty(word) ? null : word.toString());
final CharSequence text = getEllipsizedText(word, width, wordView.getPaint());
final float scaleX = getTextScaleX(word, width, wordView.getPaint());
wordView.setText(text); // TextView.setText() resets text scale x to 1.0.
@@ -425,7 +424,9 @@ final class SuggestionStripLayoutHelper {
final int countInStrip) {
// Clear all suggestions first
for (int positionInStrip = 0; positionInStrip < countInStrip; ++positionInStrip) {
- mWordViews.get(positionInStrip).setText(null);
+ final TextView wordView = mWordViews.get(positionInStrip);
+ wordView.setText(null);
+ wordView.setTag(null);
// Make this inactive for touches in {@link #layoutWord(int,int)}.
if (SuggestionStripView.DBG) {
mDebugInfoViews.get(positionInStrip).setText(null);
@@ -459,14 +460,15 @@ final class SuggestionStripLayoutHelper {
}
final TextView wordView = mWordViews.get(positionInStrip);
- wordView.setEnabled(true);
- wordView.setTextColor(mColorAutoCorrect);
+ final String punctuation = punctuationSuggestions.getLabel(positionInStrip);
// {@link TextView#getTag()} is used to get the index in suggestedWords at
// {@link SuggestionStripView#onClick(View)}.
wordView.setTag(positionInStrip);
- wordView.setText(punctuationSuggestions.getLabel(positionInStrip));
+ wordView.setText(punctuation);
+ wordView.setContentDescription(punctuation);
wordView.setTextScaleX(1.0f);
wordView.setCompoundDrawables(null, null, null, null);
+ wordView.setTextColor(mColorAutoCorrect);
stripView.addView(wordView);
setLayoutWeight(wordView, 1.0f, mSuggestionsStripHeight);
}
@@ -474,8 +476,8 @@ final class SuggestionStripLayoutHelper {
return countInStrip;
}
- public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip,
- final int stripWidth) {
+ public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip) {
+ final int stripWidth = addToDictionaryStrip.getWidth();
final int width = stripWidth - mDividerWidth - mPadding * 2;
final TextView wordView = (TextView)addToDictionaryStrip.findViewById(R.id.word_to_save);
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index a0793b133..3be933ff7 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -18,7 +18,9 @@ package com.android.inputmethod.latin.suggestions;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Color;
+import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -31,6 +33,7 @@ import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewParent;
+import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -39,17 +42,14 @@ import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.keyboard.MoreKeysPanel;
import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.InputAttributes;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.Settings;
-import com.android.inputmethod.latin.suggestions.MoreSuggestions.MoreSuggestionsListener;
-import com.android.inputmethod.latin.utils.CollectionUtils;
+import com.android.inputmethod.latin.settings.SettingsValues;
+import com.android.inputmethod.latin.suggestions.MoreSuggestionsView.MoreSuggestionsListener;
import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
-import com.android.inputmethod.research.ResearchLogger;
import java.util.ArrayList;
@@ -59,12 +59,14 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
public void addWordToUserDictionary(String word);
public void showImportantNoticeContents();
public void pickSuggestionManually(int index, SuggestedWordInfo word);
+ public void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat);
}
static final boolean DBG = LatinImeLogger.sDBG;
private static final float DEBUG_INFO_TEXT_SIZE_IN_DIP = 6.0f;
private final ViewGroup mSuggestionsStrip;
+ private final ImageButton mVoiceKey;
private final ViewGroup mAddToDictionaryStrip;
private final View mImportantNoticeStrip;
MainKeyboardView mMainKeyboardView;
@@ -73,9 +75,9 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final MoreSuggestionsView mMoreSuggestionsView;
private final MoreSuggestions.Builder mMoreSuggestionsBuilder;
- private final ArrayList<TextView> mWordViews = CollectionUtils.newArrayList();
- private final ArrayList<TextView> mDebugInfoViews = CollectionUtils.newArrayList();
- private final ArrayList<View> mDividerViews = CollectionUtils.newArrayList();
+ private final ArrayList<TextView> mWordViews = new ArrayList<>();
+ private final ArrayList<TextView> mDebugInfoViews = new ArrayList<>();
+ private final ArrayList<View> mDividerViews = new ArrayList<>();
Listener mListener;
private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
@@ -85,12 +87,15 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final StripVisibilityGroup mStripVisibilityGroup;
private static class StripVisibilityGroup {
+ private final View mSuggestionStripView;
private final View mSuggestionsStrip;
private final View mAddToDictionaryStrip;
private final View mImportantNoticeStrip;
- public StripVisibilityGroup(final View suggestionsStrip, final View addToDictionaryStrip,
+ public StripVisibilityGroup(final View suggestionStripView,
+ final ViewGroup suggestionsStrip, final ViewGroup addToDictionaryStrip,
final View importantNoticeStrip) {
+ mSuggestionStripView = suggestionStripView;
mSuggestionsStrip = suggestionsStrip;
mAddToDictionaryStrip = addToDictionaryStrip;
mImportantNoticeStrip = importantNoticeStrip;
@@ -100,6 +105,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
public void setLayoutDirection(final boolean isRtlLanguage) {
final int layoutDirection = isRtlLanguage ? ViewCompat.LAYOUT_DIRECTION_RTL
: ViewCompat.LAYOUT_DIRECTION_LTR;
+ ViewCompat.setLayoutDirection(mSuggestionStripView, layoutDirection);
ViewCompat.setLayoutDirection(mSuggestionsStrip, layoutDirection);
ViewCompat.setLayoutDirection(mAddToDictionaryStrip, layoutDirection);
ViewCompat.setLayoutDirection(mImportantNoticeStrip, layoutDirection);
@@ -145,10 +151,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
inflater.inflate(R.layout.suggestions_strip, this);
mSuggestionsStrip = (ViewGroup)findViewById(R.id.suggestions_strip);
+ mVoiceKey = (ImageButton)findViewById(R.id.suggestions_strip_voice_key);
mAddToDictionaryStrip = (ViewGroup)findViewById(R.id.add_to_dictionary_strip);
mImportantNoticeStrip = findViewById(R.id.important_notice_strip);
- mStripVisibilityGroup = new StripVisibilityGroup(mSuggestionsStrip, mAddToDictionaryStrip,
- mImportantNoticeStrip);
+ mStripVisibilityGroup = new StripVisibilityGroup(this, mSuggestionsStrip,
+ mAddToDictionaryStrip, mImportantNoticeStrip);
for (int pos = 0; pos < SuggestedWords.MAX_SUGGESTIONS; pos++) {
final TextView word = new TextView(context, null, R.attr.suggestionWordStyle);
@@ -156,7 +163,6 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
word.setOnLongClickListener(this);
mWordViews.add(word);
final View divider = inflater.inflate(R.layout.suggestion_divider, null);
- divider.setOnClickListener(this);
mDividerViews.add(divider);
final TextView info = new TextView(context, null, R.attr.suggestionWordStyle);
info.setTextColor(Color.WHITE);
@@ -177,6 +183,13 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
R.dimen.config_more_suggestions_modal_tolerance);
mMoreSuggestionsSlidingDetector = new GestureDetector(
context, mMoreSuggestionsSlidingListener);
+
+ final TypedArray keyboardAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.Keyboard, defStyle, R.style.SuggestionStripView);
+ final Drawable iconVoice = keyboardAttr.getDrawable(R.styleable.Keyboard_iconShortcutKey);
+ keyboardAttr.recycle();
+ mVoiceKey.setImageDrawable(iconVoice);
+ mVoiceKey.setOnClickListener(this);
}
/**
@@ -188,15 +201,19 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
mMainKeyboardView = (MainKeyboardView)inputView.findViewById(R.id.keyboard_view);
}
+ public void updateVisibility(final boolean shouldBeVisible, final boolean isFullscreenMode) {
+ final int visibility = shouldBeVisible ? VISIBLE : (isFullscreenMode ? GONE : INVISIBLE);
+ setVisibility(visibility);
+ final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
+ mVoiceKey.setVisibility(currentSettingsValues.mShowsVoiceInputKey ? VISIBLE : INVISIBLE);
+ }
+
public void setSuggestions(final SuggestedWords suggestedWords, final boolean isRtlLanguage) {
clear();
mStripVisibilityGroup.setLayoutDirection(isRtlLanguage);
mSuggestedWords = suggestedWords;
mSuggestionsCountInStrip = mLayoutHelper.layoutAndReturnSuggestionCountInStrip(
mSuggestedWords, mSuggestionsStrip, this);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- ResearchLogger.suggestionStripView_setSuggestions(mSuggestedWords);
- }
mStripVisibilityGroup.showSuggestionsStrip();
}
@@ -209,7 +226,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
public void showAddToDictionaryHint(final String word) {
- mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip, getWidth());
+ mLayoutHelper.layoutAddToDictionaryHint(word, mAddToDictionaryStrip);
// {@link TextView#setTag()} is used to hold the word to be added to dictionary. The word
// will be extracted at {@link #onClick(View)}.
mAddToDictionaryStrip.setTag(word);
@@ -228,8 +245,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
// This method checks if we should show the important notice (checks on permanent storage if
// it has been shown once already or not, and if in the setup wizard). If applicable, it shows
// the notice. In all cases, it returns true if it was shown, false otherwise.
- public boolean maybeShowImportantNoticeTitle(final InputAttributes inputAttributes) {
- if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext(), inputAttributes)) {
+ public boolean maybeShowImportantNoticeTitle() {
+ if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext())) {
return false;
}
if (getWidth() <= 0) {
@@ -411,10 +428,18 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
@Override
public void onClick(final View view) {
+ AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
+ Constants.CODE_UNSPECIFIED, this);
if (view == mImportantNoticeStrip) {
mListener.showImportantNoticeContents();
return;
}
+ if (view == mVoiceKey) {
+ mListener.onCodeInput(Constants.CODE_SHORTCUT,
+ Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE,
+ false /* isKeyRepeat */);
+ return;
+ }
final Object tag = view.getTag();
// {@link String} tag is set at {@link #showAddToDictionaryHint(String,CharSequence)}.
if (tag instanceof String) {
@@ -448,7 +473,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
// Called by the framework when the size is known. Show the important notice if applicable.
// This may be overriden by showing suggestions later, if applicable.
if (oldw <= 0 && w > 0) {
- maybeShowImportantNoticeTitle(Settings.getInstance().getCurrent().mInputAttributes);
+ maybeShowImportantNoticeTitle();
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
index 21426d1eb..eda81940f 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordContents.java
@@ -167,7 +167,9 @@ public class UserDictionaryAddWordContents {
// should not insert, because either A. the word exists with no shortcut, in which
// case the exact same thing we want to insert is already there, or B. the word
// exists with at least one shortcut, in which case it has priority on our word.
- if (hasWord(newWord, context)) return CODE_ALREADY_PRESENT;
+ if (TextUtils.isEmpty(newShortcut) && hasWord(newWord, context)) {
+ return CODE_ALREADY_PRESENT;
+ }
// Disallow duplicates. If the same word with no shortcut is defined, remove it; if
// the same word with the same shortcut is defined, remove it; but we don't mind if
@@ -256,7 +258,7 @@ public class UserDictionaryAddWordContents {
// The system locale should be inside. We want it at the 2nd spot.
locales.remove(systemLocale); // system locale may not be null
locales.remove(""); // Remove the empty string if it's there
- final ArrayList<LocaleRenderer> localesList = new ArrayList<LocaleRenderer>();
+ final ArrayList<LocaleRenderer> localesList = new ArrayList<>();
// Add the passed locale, then the system locale at the top of the list. Add an
// "all languages" entry at the bottom of the list.
addLocaleDisplayNameToList(activity, localesList, mLocale);
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
index 4fc132f68..163443036 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryAddWordFragment.java
@@ -134,8 +134,8 @@ public class UserDictionaryAddWordFragment extends Fragment
final Spinner localeSpinner =
(Spinner)mRootView.findViewById(R.id.user_dictionary_add_locale);
- final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<LocaleRenderer>(getActivity(),
- android.R.layout.simple_spinner_item, localesList);
+ final ArrayAdapter<LocaleRenderer> adapter = new ArrayAdapter<>(
+ getActivity(), android.R.layout.simple_spinner_item, localesList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
localeSpinner.setAdapter(adapter);
localeSpinner.setOnItemSelectedListener(this);
diff --git a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java
index 97a924d7b..624783a70 100644
--- a/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java
+++ b/java/src/com/android/inputmethod/latin/userdictionary/UserDictionaryList.java
@@ -56,7 +56,7 @@ public class UserDictionaryList extends PreferenceFragment {
final Cursor cursor = activity.getContentResolver().query(UserDictionary.Words.CONTENT_URI,
new String[] { UserDictionary.Words.LOCALE },
null, null, null);
- final TreeSet<String> localeSet = new TreeSet<String>();
+ final TreeSet<String> localeSet = new TreeSet<>();
if (null == cursor) {
// The user dictionary service is not present or disabled. Return null.
return null;
diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
index 2bb30a2ba..3ca7c7e1c 100644
--- a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
@@ -95,8 +95,7 @@ public final class AdditionalSubtypeUtils {
return EMPTY_SUBTYPE_ARRAY;
}
final String[] prefSubtypeArray = prefSubtypes.split(PREF_SUBTYPE_SEPARATOR);
- final ArrayList<InputMethodSubtype> subtypesList =
- CollectionUtils.newArrayList(prefSubtypeArray.length);
+ final ArrayList<InputMethodSubtype> subtypesList = new ArrayList<>(prefSubtypeArray.length);
for (final String prefSubtype : prefSubtypeArray) {
final String elems[] = prefSubtype.split(LOCALE_AND_LAYOUT_SEPARATOR);
if (elems.length != LENGTH_WITHOUT_EXTRA_VALUE
diff --git a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
index 22b9b77d2..34ee2152a 100644
--- a/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AutoCorrectionUtils.java
@@ -16,12 +16,11 @@
package com.android.inputmethod.latin.utils;
-import com.android.inputmethod.latin.BinaryDictionary;
+import android.util.Log;
+
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import android.util.Log;
-
public final class AutoCorrectionUtils {
private static final boolean DBG = LatinImeLogger.sDBG;
private static final String TAG = AutoCorrectionUtils.class.getSimpleName();
@@ -36,7 +35,9 @@ public final class AutoCorrectionUtils {
final float autoCorrectionThreshold) {
if (null != suggestion) {
// Shortlist a whitelisted word
- if (suggestion.mKind == SuggestedWordInfo.KIND_WHITELIST) return true;
+ if (suggestion.isKindOf(SuggestedWordInfo.KIND_WHITELIST)) {
+ return true;
+ }
final int autoCorrectionSuggestionScore = suggestion.mScore;
// TODO: when the normalized score of the first suggestion is nearly equals to
// the normalized score of the second suggestion, behave less aggressive.
diff --git a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
index 702688f93..936219332 100644
--- a/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CapsModeUtils.java
@@ -62,6 +62,22 @@ public final class CapsModeUtils {
}
/**
+ * Helper method to find out if a code point is starting punctuation.
+ *
+ * This include the Unicode START_PUNCTUATION category, but also some other symbols that are
+ * starting, like the inverted question mark or the double quote.
+ *
+ * @param codePoint the code point
+ * @return true if it's starting punctuation, false otherwise.
+ */
+ private static boolean isStartPunctuation(final int codePoint) {
+ return (codePoint == Constants.CODE_DOUBLE_QUOTE || codePoint == Constants.CODE_SINGLE_QUOTE
+ || codePoint == Constants.CODE_INVERTED_QUESTION_MARK
+ || codePoint == Constants.CODE_INVERTED_EXCLAMATION_MARK
+ || Character.getType(codePoint) == Character.START_PUNCTUATION);
+ }
+
+ /**
* Determine what caps mode should be in effect at the current offset in
* the text. Only the mode bits set in <var>reqModes</var> will be
* checked. Note that the caps mode flags here are explicitly defined
@@ -115,8 +131,7 @@ public final class CapsModeUtils {
} else {
for (i = cs.length(); i > 0; i--) {
final char c = cs.charAt(i - 1);
- if (c != Constants.CODE_DOUBLE_QUOTE && c != Constants.CODE_SINGLE_QUOTE
- && Character.getType(c) != Character.START_PUNCTUATION) {
+ if (!isStartPunctuation(c)) {
break;
}
}
@@ -210,11 +225,14 @@ public final class CapsModeUtils {
// We found out that we have a period. We need to determine if this is a full stop or
// otherwise sentence-ending period, or an abbreviation like "e.g.". An abbreviation
- // looks like (\w\.){2,}
+ // looks like (\w\.){2,}. Moreover, in German, you put periods after digits for dates
+ // and some other things, and in German specifically we need to not go into autocaps after
+ // a whitespace-digits-period sequence.
// To find out, we will have a simple state machine with the following states :
- // START, WORD, PERIOD, ABBREVIATION
+ // START, WORD, PERIOD, ABBREVIATION, NUMBER
// On START : (just before the first period)
// letter => WORD
+ // digit => NUMBER if German; end with caps otherwise
// whitespace => end with no caps (it was a stand-alone period)
// otherwise => end with caps (several periods/symbols in a row)
// On WORD : (within the word just before the first period)
@@ -228,6 +246,11 @@ public final class CapsModeUtils {
// letter => LETTER
// period => PERIOD
// otherwise => end with no caps (it was an abbreviation)
+ // On NUMBER : (period immediately preceded by one or more digits)
+ // digit => NUMBER
+ // letter => LETTER (promote to word)
+ // otherwise => end with no caps (it was a whitespace-digits-period sequence,
+ // or a punctuation-digits-period sequence like "11.11.")
// "Not an abbreviation" in the above chart essentially covers cases like "...yes.". This
// should capitalize.
@@ -235,6 +258,7 @@ public final class CapsModeUtils {
final int WORD = 1;
final int PERIOD = 2;
final int LETTER = 3;
+ final int NUMBER = 4;
final int caps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS
| TextUtils.CAP_MODE_SENTENCES) & reqModes;
final int noCaps = (TextUtils.CAP_MODE_CHARACTERS | TextUtils.CAP_MODE_WORDS) & reqModes;
@@ -247,6 +271,8 @@ public final class CapsModeUtils {
state = WORD;
} else if (Character.isWhitespace(c)) {
return noCaps;
+ } else if (Character.isDigit(c) && spacingAndPunctuations.mUsesGermanRules) {
+ state = NUMBER;
} else {
return caps;
}
@@ -275,6 +301,15 @@ public final class CapsModeUtils {
} else {
return noCaps;
}
+ break;
+ case NUMBER:
+ if (Character.isLetter(c)) {
+ state = WORD;
+ } else if (Character.isDigit(c)) {
+ state = NUMBER;
+ } else {
+ return noCaps;
+ }
}
}
// Here we arrived at the start of the line. This should behave exactly like whitespace.
diff --git a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
index bbfa0f091..e3aef29ba 100644
--- a/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CollectionUtils.java
@@ -16,93 +16,21 @@
package com.android.inputmethod.latin.utils;
-import android.util.SparseArray;
-
-import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.WeakHashMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
public final class CollectionUtils {
private CollectionUtils() {
// This utility class is not publicly instantiable.
}
- public static <K,V> HashMap<K,V> newHashMap() {
- return new HashMap<K,V>();
- }
-
- public static <K, V> WeakHashMap<K, V> newWeakHashMap() {
- return new WeakHashMap<K, V>();
- }
-
- public static <K,V> TreeMap<K,V> newTreeMap() {
- return new TreeMap<K,V>();
- }
-
public static <K, V> Map<K,V> newSynchronizedTreeMap() {
- final TreeMap<K,V> treeMap = newTreeMap();
+ final TreeMap<K,V> treeMap = new TreeMap<>();
return Collections.synchronizedMap(treeMap);
}
- public static <K,V> ConcurrentHashMap<K,V> newConcurrentHashMap() {
- return new ConcurrentHashMap<K,V>();
- }
-
- public static <E> HashSet<E> newHashSet() {
- return new HashSet<E>();
- }
-
- public static <E> TreeSet<E> newTreeSet() {
- return new TreeSet<E>();
- }
-
- public static <E> ArrayList<E> newArrayList() {
- return new ArrayList<E>();
- }
-
- public static <E> ArrayList<E> newArrayList(final int initialCapacity) {
- return new ArrayList<E>(initialCapacity);
- }
-
- public static <E> ArrayList<E> newArrayList(final Collection<E> collection) {
- return new ArrayList<E>(collection);
- }
-
- public static <E> LinkedList<E> newLinkedList() {
- return new LinkedList<E>();
- }
-
- public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList() {
- return new CopyOnWriteArrayList<E>();
- }
-
- public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList(
- final Collection<E> collection) {
- return new CopyOnWriteArrayList<E>(collection);
- }
-
- public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList(final E[] array) {
- return new CopyOnWriteArrayList<E>(array);
- }
-
- public static <E> ArrayDeque<E> newArrayDeque() {
- return new ArrayDeque<E>();
- }
-
- public static <E> SparseArray<E> newSparseArray() {
- return new SparseArray<E>();
- }
-
public static <E> ArrayList<E> arrayAsList(final E[] array, final int start, final int end) {
if (array == null) {
throw new NullPointerException();
@@ -111,7 +39,7 @@ public final class CollectionUtils {
throw new IllegalArgumentException();
}
- final ArrayList<E> list = newArrayList(end - start);
+ final ArrayList<E> list = new ArrayList<>(end - start);
for (int i = start; i < end; i++) {
list.add(array[i]);
}
diff --git a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
index b18a1d83b..a21a1373b 100644
--- a/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/CsvUtils.java
@@ -209,7 +209,7 @@ public final class CsvUtils {
@UsedForTesting
public static String[] split(final int splitFlags, final String line) throws CsvParseException {
final boolean trimSpaces = (splitFlags & SPLIT_FLAGS_TRIM_SPACES) != 0;
- final ArrayList<String> fields = CollectionUtils.newArrayList();
+ final ArrayList<String> fields = new ArrayList<>();
final int length = line.length();
int start = 0;
do {
diff --git a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
index 315913e2f..d76ea10c0 100644
--- a/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/DictionaryInfoUtils.java
@@ -336,7 +336,7 @@ public class DictionaryInfoUtils {
public static ArrayList<DictionaryInfo> getCurrentDictionaryFileNameAndVersionInfo(
final Context context) {
- final ArrayList<DictionaryInfo> dictList = CollectionUtils.newArrayList();
+ final ArrayList<DictionaryInfo> dictList = new ArrayList<>();
// Retrieve downloaded dictionaries
final File[] directoryList = getCachedDirectoryList(context);
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
index f2a1e524d..787e4a59d 100644
--- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java
@@ -16,33 +16,43 @@
package com.android.inputmethod.latin.utils;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.latin.Suggest;
+import java.util.List;
+import java.util.Locale;
-/**
- * This class is used to prevent distracters/misspellings being added to personalization
- * or user history dictionaries
- */
-public class DistracterFilter {
- private final Suggest mSuggest;
- private final Keyboard mKeyboard;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.PrevWordsInfo;
+public interface DistracterFilter {
/**
- * Create a DistracterFilter instance.
+ * Determine whether a word is a distracter to words in dictionaries.
*
- * @param suggest an instance of Suggest which will be used to obtain a list of suggestions
- * for a potential distracter/misspelling
- * @param keyboard the keyboard that is currently being used. This information is needed
- * when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions.
+ * @param prevWordsInfo the information of previous words.
+ * @param testedWord the word that will be tested to see whether it is a distracter to words
+ * in dictionaries.
+ * @param locale the locale of word.
+ * @return true if testedWord is a distracter, otherwise false.
*/
- public DistracterFilter(final Suggest suggest, final Keyboard keyboard) {
- mSuggest = suggest;
- mKeyboard = keyboard;
- }
-
- public boolean isDistractorToWordsInDictionaries(final String prevWord,
- final String targetWord) {
- // TODO: to be implemented
- return false;
- }
+ public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo,
+ final String testedWord, final Locale locale);
+
+ public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes);
+
+ public void close();
+
+ public static final DistracterFilter EMPTY_DISTRACTER_FILTER = new DistracterFilter() {
+ @Override
+ public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo,
+ String testedWord, Locale locale) {
+ return false;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public void updateEnabledSubtypes(List<InputMethodSubtype> enabledSubtypes) {
+ }
+ };
}
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatches.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatches.java
new file mode 100644
index 000000000..0ee6236b1
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingExactMatches.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+import android.content.Context;
+import android.util.Log;
+import android.util.LruCache;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.DictionaryFacilitator;
+import com.android.inputmethod.latin.PrevWordsInfo;
+
+/**
+ * This class is used to prevent distracters being added to personalization
+ * or user history dictionaries
+ */
+public class DistracterFilterCheckingExactMatches implements DistracterFilter {
+ private static final String TAG = DistracterFilterCheckingExactMatches.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120;
+ private static final int MAX_DISTRACTERS_CACHE_SIZE = 512;
+
+ private final Context mContext;
+ private final DictionaryFacilitator mDictionaryFacilitator;
+ private final LruCache<String, Boolean> mDistractersCache;
+ private final Object mLock = new Object();
+
+ /**
+ * Create a DistracterFilter instance.
+ *
+ * @param context the context.
+ */
+ public DistracterFilterCheckingExactMatches(final Context context) {
+ mContext = context;
+ mDictionaryFacilitator = new DictionaryFacilitator();
+ mDistractersCache = new LruCache<>(MAX_DISTRACTERS_CACHE_SIZE);
+ }
+
+ @Override
+ public void close() {
+ mDictionaryFacilitator.closeDictionaries();
+ }
+
+ @Override
+ public void updateEnabledSubtypes(final List<InputMethodSubtype> enabledSubtypes) {
+ }
+
+ private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException {
+ mDictionaryFacilitator.resetDictionaries(mContext, newlocale,
+ false /* useContactsDict */, false /* usePersonalizedDicts */,
+ false /* forceReloadMainDictionary */, null /* listener */);
+ mDictionaryFacilitator.waitForLoadingMainDictionary(
+ TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Determine whether a word is a distracter to words in dictionaries.
+ *
+ * @param prevWordsInfo the information of previous words. Not used for now.
+ * @param testedWord the word that will be tested to see whether it is a distracter to words
+ * in dictionaries.
+ * @param locale the locale of word.
+ * @return true if testedWord is a distracter, otherwise false.
+ */
+ @Override
+ public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo,
+ final String testedWord, final Locale locale) {
+ if (locale == null) {
+ return false;
+ }
+ if (!locale.equals(mDictionaryFacilitator.getLocale())) {
+ synchronized (mLock) {
+ // Reset dictionaries for the locale.
+ try {
+ mDistractersCache.evictAll();
+ loadDictionariesForLocale(locale);
+ } catch (final InterruptedException e) {
+ Log.e(TAG, "Interrupted while waiting for loading dicts in DistracterFilter",
+ e);
+ return false;
+ }
+ }
+ }
+
+ final Boolean isCachedDistracter = mDistractersCache.get(testedWord);
+ if (isCachedDistracter != null && isCachedDistracter) {
+ if (DEBUG) {
+ Log.d(TAG, "testedWord: " + testedWord);
+ Log.d(TAG, "isDistracter: true (cache hit)");
+ }
+ return true;
+ }
+ // The tested word is a distracter when there is a word that is exact matched to the tested
+ // word and its probability is higher than the tested word's probability.
+ final int perfectMatchFreq = mDictionaryFacilitator.getFrequency(testedWord);
+ final int exactMatchFreq = mDictionaryFacilitator.getMaxFrequencyOfExactMatches(testedWord);
+ final boolean isDistracter = perfectMatchFreq < exactMatchFreq;
+ if (DEBUG) {
+ Log.d(TAG, "testedWord: " + testedWord);
+ Log.d(TAG, "perfectMatchFreq: " + perfectMatchFreq);
+ Log.d(TAG, "exactMatchFreq: " + exactMatchFreq);
+ Log.d(TAG, "isDistracter: " + isDistracter);
+ }
+ if (isDistracter) {
+ // Add the word to the cache.
+ mDistractersCache.put(testedWord, Boolean.TRUE);
+ }
+ return isDistracter;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java
new file mode 100644
index 000000000..4ad4ba784
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterCheckingIsInDictionary.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import java.util.List;
+import java.util.Locale;
+
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.Dictionary;
+import com.android.inputmethod.latin.PrevWordsInfo;
+
+public class DistracterFilterCheckingIsInDictionary implements DistracterFilter {
+ private final DistracterFilter mDistracterFilter;
+ private final Dictionary mDictionary;
+
+ public DistracterFilterCheckingIsInDictionary(final DistracterFilter distracterFilter,
+ final Dictionary dictionary) {
+ mDistracterFilter = distracterFilter;
+ mDictionary = dictionary;
+ }
+
+ @Override
+ public boolean isDistracterToWordsInDictionaries(PrevWordsInfo prevWordsInfo,
+ String testedWord, Locale locale) {
+ if (mDictionary.isInDictionary(testedWord)) {
+ // This filter treats entries that are already in the dictionary as non-distracters
+ // because they have passed the filtering in the past.
+ return false;
+ } else {
+ return mDistracterFilter.isDistracterToWordsInDictionaries(
+ prevWordsInfo, testedWord, locale);
+ }
+ }
+
+ @Override
+ public void updateEnabledSubtypes(List<InputMethodSubtype> enabledSubtypes) {
+ // Do nothing.
+ }
+
+ @Override
+ public void close() {
+ // Do nothing.
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
index ed502ed3d..61da1b789 100644
--- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
@@ -19,22 +19,42 @@ package com.android.inputmethod.latin.utils;
import com.android.inputmethod.annotations.UsedForTesting;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
/**
* Utilities to manage executors.
*/
public class ExecutorUtils {
- private static final ConcurrentHashMap<String, PrioritizedSerialExecutor>
- sExecutorMap = CollectionUtils.newConcurrentHashMap();
+ private static final ConcurrentHashMap<String, ExecutorService> sExecutorMap =
+ new ConcurrentHashMap<>();
+
+ private static class ThreadFactoryWithId implements ThreadFactory {
+ private final String mId;
+
+ public ThreadFactoryWithId(final String id) {
+ mId = id;
+ }
+
+ @Override
+ public Thread newThread(final Runnable r) {
+ return new Thread(r, "Executor - " + mId);
+ }
+ }
+
/**
- * Gets the executor for the given dictionary name.
+ * Gets the executor for the given id.
*/
- public static PrioritizedSerialExecutor getExecutor(final String dictName) {
- PrioritizedSerialExecutor executor = sExecutorMap.get(dictName);
+ public static ExecutorService getExecutor(final String id) {
+ ExecutorService executor = sExecutorMap.get(id);
if (executor == null) {
synchronized(sExecutorMap) {
- executor = new PrioritizedSerialExecutor();
- sExecutorMap.put(dictName, executor);
+ executor = sExecutorMap.get(id);
+ if (executor == null) {
+ executor = Executors.newSingleThreadExecutor(new ThreadFactoryWithId(id));
+ sExecutorMap.put(id, executor);
+ }
}
}
return executor;
@@ -46,7 +66,7 @@ public class ExecutorUtils {
@UsedForTesting
public static void shutdownAllExecutors() {
synchronized(sExecutorMap) {
- for (final PrioritizedSerialExecutor executor : sExecutorMap.values()) {
+ for (final ExecutorService executor : sExecutorMap.values()) {
executor.execute(new Runnable() {
@Override
public void run() {
diff --git a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
index ee2b97b2a..e300bd1d3 100644
--- a/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/FragmentUtils.java
@@ -26,12 +26,11 @@ import com.android.inputmethod.latin.userdictionary.UserDictionaryAddWordFragmen
import com.android.inputmethod.latin.userdictionary.UserDictionaryList;
import com.android.inputmethod.latin.userdictionary.UserDictionaryLocalePicker;
import com.android.inputmethod.latin.userdictionary.UserDictionarySettings;
-import com.android.inputmethod.research.FeedbackFragment;
import java.util.HashSet;
public class FragmentUtils {
- private static final HashSet<String> sLatinImeFragments = new HashSet<String>();
+ private static final HashSet<String> sLatinImeFragments = new HashSet<>();
static {
sLatinImeFragments.add(DictionarySettingsFragment.class.getName());
sLatinImeFragments.add(AboutPreferences.class.getName());
@@ -43,7 +42,6 @@ public class FragmentUtils {
sLatinImeFragments.add(UserDictionaryList.class.getName());
sLatinImeFragments.add(UserDictionaryLocalePicker.class.getName());
sLatinImeFragments.add(UserDictionarySettings.class.getName());
- sLatinImeFragments.add(FeedbackFragment.class.getName());
}
public static boolean isValidFragment(String fragmentName) {
diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
index 7d937a9d2..8b7077879 100644
--- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
@@ -23,7 +23,6 @@ import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Log;
-import com.android.inputmethod.latin.InputAttributes;
import com.android.inputmethod.latin.R;
public final class ImportantNoticeUtils {
@@ -78,14 +77,7 @@ public final class ImportantNoticeUtils {
return getCurrentImportantNoticeVersion(context) > lastVersion;
}
- public static boolean shouldShowImportantNotice(final Context context,
- final InputAttributes inputAttributes) {
- if (inputAttributes == null || inputAttributes.mIsPasswordField) {
- return false;
- }
- if (isInSystemSetupWizard(context)) {
- return false;
- }
+ public static boolean shouldShowImportantNotice(final Context context) {
if (!hasNewImportantNotice(context)) {
return false;
}
@@ -93,6 +85,9 @@ public final class ImportantNoticeUtils {
if (TextUtils.isEmpty(importantNoticeTitle)) {
return false;
}
+ if (isInSystemSetupWizard(context)) {
+ return false;
+ }
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/JsonUtils.java b/java/src/com/android/inputmethod/latin/utils/JsonUtils.java
index 764ef72ce..6dd8d9711 100644
--- a/java/src/com/android/inputmethod/latin/utils/JsonUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/JsonUtils.java
@@ -37,7 +37,7 @@ public final class JsonUtils {
private static final String EMPTY_STRING = "";
public static List<Object> jsonStrToList(final String s) {
- final ArrayList<Object> list = CollectionUtils.newArrayList();
+ final ArrayList<Object> list = new ArrayList<>();
final JsonReader reader = new JsonReader(new StringReader(s));
try {
reader.beginArray();
diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
index 5ce977d5e..4248bebf6 100644
--- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
+++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java
@@ -19,10 +19,12 @@ package com.android.inputmethod.latin.utils;
import android.util.Log;
import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest;
+import com.android.inputmethod.latin.DictionaryFacilitator;
+import com.android.inputmethod.latin.PrevWordsInfo;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import java.util.ArrayList;
+import java.util.List;
import java.util.Locale;
// Note: this class is used as a parameter type of a native method. You should be careful when you
@@ -78,13 +80,13 @@ public final class LanguageModelParam {
// Process a list of words and return a list of {@link LanguageModelParam} objects.
public static ArrayList<LanguageModelParam> createLanguageModelParamsFrom(
- final ArrayList<String> tokens, final int timestamp,
- final DictionaryFacilitatorForSuggest dictionaryFacilitator,
- final SpacingAndPunctuations spacingAndPunctuations) {
- final ArrayList<LanguageModelParam> languageModelParams =
- CollectionUtils.newArrayList();
+ final List<String> tokens, final int timestamp,
+ final DictionaryFacilitator dictionaryFacilitator,
+ final SpacingAndPunctuations spacingAndPunctuations,
+ final DistracterFilter distracterFilter) {
+ final ArrayList<LanguageModelParam> languageModelParams = new ArrayList<>();
final int N = tokens.size();
- String prevWord = null;
+ PrevWordsInfo prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
for (int i = 0; i < N; ++i) {
final String tempWord = tokens.get(i);
if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) {
@@ -101,7 +103,7 @@ public final class LanguageModelParam {
+ tempWord + "\"");
}
// Sentence terminator found. Split.
- prevWord = null;
+ prevWordsInfo = PrevWordsInfo.EMPTY_PREV_WORDS_INFO;
continue;
}
if (DEBUG_TOKEN) {
@@ -109,56 +111,63 @@ public final class LanguageModelParam {
}
final LanguageModelParam languageModelParam =
detectWhetherVaildWordOrNotAndGetLanguageModelParam(
- prevWord, tempWord, timestamp, dictionaryFacilitator);
+ prevWordsInfo, tempWord, timestamp, dictionaryFacilitator,
+ distracterFilter);
if (languageModelParam == null) {
continue;
}
languageModelParams.add(languageModelParam);
- prevWord = languageModelParam.mTargetWord;
+ prevWordsInfo = new PrevWordsInfo(languageModelParam.mTargetWord);
}
return languageModelParams;
}
private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam(
- final String prevWord, final String targetWord, final int timestamp,
- final DictionaryFacilitatorForSuggest dictionaryFacilitator) {
+ final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp,
+ final DictionaryFacilitator dictionaryFacilitator,
+ final DistracterFilter distracterFilter) {
final Locale locale = dictionaryFacilitator.getLocale();
if (locale == null) {
return null;
}
- if (!dictionaryFacilitator.isValidWord(targetWord, true /* ignoreCase */)) {
- // OOV word.
- return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp,
- false /* isValidWord */, locale);
- }
if (dictionaryFacilitator.isValidWord(targetWord, false /* ignoreCase */)) {
- return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp,
- true /* isValidWord */, locale);
+ return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp,
+ true /* isValidWord */, locale, distracterFilter);
}
+
final String lowerCaseTargetWord = targetWord.toLowerCase(locale);
if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) {
// Add the lower-cased word.
- return createAndGetLanguageModelParamOfWord(prevWord, lowerCaseTargetWord,
- timestamp, true /* isValidWord */, locale);
+ return createAndGetLanguageModelParamOfWord(prevWordsInfo, lowerCaseTargetWord,
+ timestamp, true /* isValidWord */, locale, distracterFilter);
}
+
// Treat the word as an OOV word.
- return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp,
- false /* isValidWord */, locale);
+ return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp,
+ false /* isValidWord */, locale, distracterFilter);
}
private static LanguageModelParam createAndGetLanguageModelParamOfWord(
- final String prevWord, final String targetWord, final int timestamp,
- final boolean isValidWord, final Locale locale) {
+ final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp,
+ final boolean isValidWord, final Locale locale,
+ final DistracterFilter distracterFilter) {
final String word;
if (StringUtils.getCapitalizationType(targetWord) == StringUtils.CAPITALIZE_FIRST
- && prevWord == null && !isValidWord) {
+ && prevWordsInfo.mPrevWord == null && !isValidWord) {
word = targetWord.toLowerCase(locale);
} else {
word = targetWord;
}
+ // Check whether the word is a distracter to words in the dictionaries.
+ if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, word, locale)) {
+ if (DEBUG) {
+ Log.d(TAG, "The word (" + word + ") is a distracter. Skip this word.");
+ }
+ return null;
+ }
final int unigramProbability = isValidWord ?
UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD;
- if (prevWord == null) {
+ if (prevWordsInfo.mPrevWord == null) {
if (DEBUG) {
Log.d(TAG, "--- add unigram: current("
+ (isValidWord ? "Valid" : "OOV") + ") = " + word);
@@ -166,12 +175,12 @@ public final class LanguageModelParam {
return new LanguageModelParam(word, unigramProbability, timestamp);
}
if (DEBUG) {
- Log.d(TAG, "--- add bigram: prev = " + prevWord + ", current("
+ Log.d(TAG, "--- add bigram: prev = " + prevWordsInfo.mPrevWord + ", current("
+ (isValidWord ? "Valid" : "OOV") + ") = " + word);
}
final int bigramProbability = isValidWord ?
BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD;
- return new LanguageModelParam(prevWord, word, unigramProbability,
+ return new LanguageModelParam(prevWordsInfo.mPrevWord, word, unigramProbability,
bigramProbability, timestamp);
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/LatinImeLoggerUtils.java b/java/src/com/android/inputmethod/latin/utils/LatinImeLoggerUtils.java
deleted file mode 100644
index d14ba508b..000000000
--- a/java/src/com/android/inputmethod/latin/utils/LatinImeLoggerUtils.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.text.TextUtils;
-
-import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.WordComposer;
-
-public final class LatinImeLoggerUtils {
- private LatinImeLoggerUtils() {
- // This utility class is not publicly instantiable.
- }
-
- public static void onNonSeparator(final char code, final int x, final int y) {
- UserLogRingCharBuffer.getInstance().push(code, x, y);
- LatinImeLogger.logOnInputChar();
- }
-
- public static void onSeparator(final int code, final int x, final int y) {
- // Helper method to log a single code point separator
- // TODO: cache this mapping of a code point to a string in a sparse array in StringUtils
- onSeparator(StringUtils.newSingleCodePointString(code), x, y);
- }
-
- public static void onSeparator(final String separator, final int x, final int y) {
- final int length = separator.length();
- for (int i = 0; i < length; i = Character.offsetByCodePoints(separator, i, 1)) {
- int codePoint = Character.codePointAt(separator, i);
- // TODO: accept code points
- UserLogRingCharBuffer.getInstance().push((char)codePoint, x, y);
- }
- LatinImeLogger.logOnInputSeparator();
- }
-
- public static void onAutoCorrection(final String typedWord, final String correctedWord,
- final String separatorString, final WordComposer wordComposer) {
- final boolean isBatchMode = wordComposer.isBatchMode();
- if (!isBatchMode && TextUtils.isEmpty(typedWord)) {
- return;
- }
- // TODO: this fails when the separator is more than 1 code point long, but
- // the backend can't handle it yet. The only case when this happens is with
- // smileys and other multi-character keys.
- final int codePoint = TextUtils.isEmpty(separatorString) ? Constants.NOT_A_CODE
- : separatorString.codePointAt(0);
- if (!isBatchMode) {
- LatinImeLogger.logOnAutoCorrectionForTyping(typedWord, correctedWord, codePoint);
- } else {
- if (!TextUtils.isEmpty(correctedWord)) {
- // We must make sure that InputPointer contains only the relative timestamps,
- // not actual timestamps.
- LatinImeLogger.logOnAutoCorrectionForGeometric(
- "", correctedWord, codePoint, wordComposer.getInputPointers());
- }
- }
- }
-
- public static void onAutoCorrectionCancellation() {
- LatinImeLogger.logOnAutoCorrectionCancelled();
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java b/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java
index 8469c87b0..dd6fac671 100644
--- a/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java
+++ b/java/src/com/android/inputmethod/latin/utils/LeakGuardHandlerWrapper.java
@@ -33,7 +33,7 @@ public class LeakGuardHandlerWrapper<T> extends Handler {
if (ownerInstance == null) {
throw new NullPointerException("ownerInstance is null");
}
- mOwnerInstanceRef = new WeakReference<T>(ownerInstance);
+ mOwnerInstanceRef = new WeakReference<>(ownerInstance);
}
public T getOwnerInstance() {
diff --git a/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java
index 0c55484b4..c519a0de6 100644
--- a/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/LocaleUtils.java
@@ -159,7 +159,7 @@ public final class LocaleUtils {
return LOCALE_MATCH <= level;
}
- private static final HashMap<String, Locale> sLocaleCache = CollectionUtils.newHashMap();
+ private static final HashMap<String, Locale> sLocaleCache = new HashMap<>();
/**
* Creates a locale from a string specification.
diff --git a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java b/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
deleted file mode 100644
index bf38abc95..000000000
--- a/java/src/com/android/inputmethod/latin/utils/PrioritizedSerialExecutor.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-
-import java.util.Queue;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * An object that executes submitted tasks using a thread.
- */
-public class PrioritizedSerialExecutor {
- public static final String TAG = PrioritizedSerialExecutor.class.getSimpleName();
-
- private final Object mLock = new Object();
-
- private final Queue<Runnable> mTasks;
- private final Queue<Runnable> mPrioritizedTasks;
- private boolean mIsShutdown;
- private final ThreadPoolExecutor mThreadPoolExecutor;
-
- // The task which is running now.
- private Runnable mActive;
-
- public PrioritizedSerialExecutor() {
- mTasks = new ConcurrentLinkedQueue<Runnable>();
- mPrioritizedTasks = new ConcurrentLinkedQueue<Runnable>();
- mIsShutdown = false;
- mThreadPoolExecutor = new ThreadPoolExecutor(1 /* corePoolSize */, 1 /* maximumPoolSize */,
- 0 /* keepAliveTime */, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
- }
-
- /**
- * Enqueues the given task into the task queue.
- * @param r the enqueued task
- */
- public void execute(final Runnable r) {
- synchronized(mLock) {
- if (!mIsShutdown) {
- mTasks.offer(new Runnable() {
- @Override
- public void run() {
- try {
- r.run();
- } finally {
- scheduleNext();
- }
- }
- });
- if (mActive == null) {
- scheduleNext();
- }
- }
- }
- }
-
- /**
- * Enqueues the given task into the prioritized task queue.
- * @param r the enqueued task
- */
- @UsedForTesting
- public void executePrioritized(final Runnable r) {
- synchronized(mLock) {
- if (!mIsShutdown) {
- mPrioritizedTasks.offer(new Runnable() {
- @Override
- public void run() {
- try {
- r.run();
- } finally {
- scheduleNext();
- }
- }
- });
- if (mActive == null) {
- scheduleNext();
- }
- }
- }
- }
-
- private boolean fetchNextTasksLocked() {
- mActive = mPrioritizedTasks.poll();
- if (mActive == null) {
- mActive = mTasks.poll();
- }
- return mActive != null;
- }
-
- private void scheduleNext() {
- synchronized(mLock) {
- if (fetchNextTasksLocked()) {
- mThreadPoolExecutor.execute(mActive);
- }
- }
- }
-
- public void shutdown() {
- synchronized(mLock) {
- mIsShutdown = true;
- mThreadPoolExecutor.shutdown();
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
index 4521ec531..e3cac97f0 100644
--- a/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
+++ b/java/src/com/android/inputmethod/latin/utils/RecapitalizeStatus.java
@@ -62,18 +62,22 @@ public class RecapitalizeStatus {
private Locale mLocale;
private int[] mSortedSeparators;
private String mStringAfter;
- private boolean mIsActive;
+ private boolean mIsStarted;
+ private boolean mIsEnabled = true;
private static final int[] EMPTY_STORTED_SEPARATORS = {};
public RecapitalizeStatus() {
// By default, initialize with dummy values that won't match any real recapitalize.
- initialize(-1, -1, "", Locale.getDefault(), EMPTY_STORTED_SEPARATORS);
- deactivate();
+ start(-1, -1, "", Locale.getDefault(), EMPTY_STORTED_SEPARATORS);
+ stop();
}
- public void initialize(final int cursorStart, final int cursorEnd, final String string,
+ public void start(final int cursorStart, final int cursorEnd, final String string,
final Locale locale, final int[] sortedSeparators) {
+ if (!mIsEnabled) {
+ return;
+ }
mCursorStartBefore = cursorStart;
mStringBefore = string;
mCursorStartAfter = cursorStart;
@@ -96,15 +100,27 @@ public class RecapitalizeStatus {
mRotationStyleCurrentIndex = currentMode;
mSkipOriginalMixedCaseMode = true;
}
- mIsActive = true;
+ mIsStarted = true;
+ }
+
+ public void stop() {
+ mIsStarted = false;
+ }
+
+ public boolean isStarted() {
+ return mIsStarted;
+ }
+
+ public void enable() {
+ mIsEnabled = true;
}
- public void deactivate() {
- mIsActive = false;
+ public void disable() {
+ mIsEnabled = false;
}
- public boolean isActive() {
- return mIsActive;
+ public boolean mIsEnabled() {
+ return mIsEnabled;
}
public boolean isSetAt(final int cursorStart, final int cursorEnd) {
diff --git a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
index 49f4929b4..093c5a6c1 100644
--- a/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ResourceUtils.java
@@ -41,8 +41,7 @@ public final class ResourceUtils {
// This utility class is not publicly instantiable.
}
- private static final HashMap<String, String> sDeviceOverrideValueMap =
- CollectionUtils.newHashMap();
+ private static final HashMap<String, String> sDeviceOverrideValueMap = new HashMap<>();
private static final String[] BUILD_KEYS_AND_VALUES = {
"HARDWARE", Build.HARDWARE,
@@ -54,8 +53,8 @@ public final class ResourceUtils {
private static final String sBuildKeyValuesDebugString;
static {
- sBuildKeyValues = CollectionUtils.newHashMap();
- final ArrayList<String> keyValuePairs = CollectionUtils.newArrayList();
+ sBuildKeyValues = new HashMap<>();
+ final ArrayList<String> keyValuePairs = new ArrayList<>();
final int keyCount = BUILD_KEYS_AND_VALUES.length / 2;
for (int i = 0; i < keyCount; i++) {
final int index = i * 2;
diff --git a/java/src/com/android/inputmethod/latin/utils/StatsUtils.java b/java/src/com/android/inputmethod/latin/utils/StatsUtils.java
index a059f877b..79c19d077 100644
--- a/java/src/com/android/inputmethod/latin/utils/StatsUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StatsUtils.java
@@ -17,37 +17,18 @@
package com.android.inputmethod.latin.utils;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-import com.android.inputmethod.latin.settings.Settings;
+import com.android.inputmethod.latin.settings.SettingsValues;
public final class StatsUtils {
- private static final String TAG = StatsUtils.class.getSimpleName();
- private static final StatsUtils sInstance = new StatsUtils();
-
- public static void onCreateCompleted(final Context context) {
- sInstance.onCreateCompletedInternal(context);
+ public static void init(final Context context) {
}
- private void onCreateCompletedInternal(final Context context) {
- mContext = context;
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
- final Boolean usePersonalizedDict =
- prefs.getBoolean(Settings.PREF_KEY_USE_PERSONALIZED_DICTS, true);
- Log.d(TAG, "onCreateCompleted. context: " + context.toString() + "usePersonalizedDict: "
- + usePersonalizedDict);
+ public static void onCreate(final SettingsValues settingsValues) {
}
- public static void onDestroy() {
- sInstance.onDestroyInternal();
+ public static void onLoadSettings(final SettingsValues settingsValues) {
}
- private void onDestroyInternal() {
- Log.d(TAG, "onDestroy. context: " + mContext.toString());
- mContext = null;
+ public static void onDestroy() {
}
-
- private Context mContext;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
index 374badc19..e4237a7f2 100644
--- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java
@@ -28,7 +28,6 @@ import java.util.Arrays;
import java.util.Locale;
public final class StringUtils {
- private static final String TAG = StringUtils.class.getSimpleName();
public static final int CAPITALIZE_NONE = 0; // No caps, or mixed case
public static final int CAPITALIZE_FIRST = 1; // First only
public static final int CAPITALIZE_ALL = 2; // All caps
@@ -110,7 +109,7 @@ public final class StringUtils {
if (!containsInArray(text, elements)) {
return extraValues;
}
- final ArrayList<String> result = CollectionUtils.newArrayList(elements.length - 1);
+ final ArrayList<String> result = new ArrayList<>(elements.length - 1);
for (final String element : elements) {
if (!text.equals(element)) {
result.add(element);
@@ -316,24 +315,6 @@ public final class StringUtils {
return true;
}
- /**
- * Returns true if all code points in text are whitespace, false otherwise. Empty is true.
- */
- // Interestingly enough, U+00A0 NO-BREAK SPACE and U+200B ZERO-WIDTH SPACE are not considered
- // whitespace, while EN SPACE, EM SPACE and IDEOGRAPHIC SPACES are.
- public static boolean containsOnlyWhitespace(final String text) {
- final int length = text.length();
- int i = 0;
- while (i < length) {
- final int codePoint = text.codePointAt(i);
- if (!Character.isWhitespace(codePoint)) {
- return false;
- }
- i += Character.charCount(codePoint);
- }
- return true;
- }
-
public static boolean isIdenticalAfterCapitalizeEachWord(final String text,
final int[] sortedSeparators) {
boolean needsCapsNext = true;
@@ -538,6 +519,15 @@ public final class StringUtils {
? casedText.codePointAt(0) : CODE_UNSPECIFIED;
}
+ public static int getTrailingSingleQuotesCount(final CharSequence charSequence) {
+ final int lastIndex = charSequence.length() - 1;
+ int i = lastIndex;
+ while (i >= 0 && charSequence.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
+ --i;
+ }
+ return lastIndex - i;
+ }
+
@UsedForTesting
public static class Stringizer<E> {
public String stringize(final E element) {
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index b37779bdc..351d01400 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -49,17 +49,14 @@ public final class SubtypeLocaleUtils {
private static Resources sResources;
private static String[] sPredefinedKeyboardLayoutSet;
// Keyboard layout to its display name map.
- private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap =
- CollectionUtils.newHashMap();
+ private static final HashMap<String, String> sKeyboardLayoutToDisplayNameMap = new HashMap<>();
// Keyboard layout to subtype name resource id map.
- private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap =
- CollectionUtils.newHashMap();
+ private static final HashMap<String, Integer> sKeyboardLayoutToNameIdsMap = new HashMap<>();
// Exceptional locale to subtype name resource id map.
- private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap =
- CollectionUtils.newHashMap();
+ private static final HashMap<String, Integer> sExceptionalLocaleToNameIdsMap = new HashMap<>();
// Exceptional locale to subtype name with layout resource id map.
private static final HashMap<String, Integer> sExceptionalLocaleToWithLayoutNameIdsMap =
- CollectionUtils.newHashMap();
+ new HashMap<>();
private static final String SUBTYPE_NAME_RESOURCE_PREFIX =
"string/subtype_";
private static final String SUBTYPE_NAME_RESOURCE_GENERIC_PREFIX =
@@ -71,7 +68,7 @@ public final class SubtypeLocaleUtils {
// Keyboard layout set name for the subtypes that don't have a keyboardLayoutSet extra value.
// This is for compatibility to keep the same subtype ids as pre-JellyBean.
private static final HashMap<String, String> sLocaleAndExtraValueToKeyboardLayoutSetMap =
- CollectionUtils.newHashMap();
+ new HashMap<>();
private SubtypeLocaleUtils() {
// Intentional empty constructor for utility class.
@@ -324,4 +321,8 @@ public final class SubtypeLocaleUtils {
public static boolean isRtlLanguage(final InputMethodSubtype subtype) {
return isRtlLanguage(getSubtypeLocale(subtype));
}
+
+ public static String getCombiningRulesExtraValue(final InputMethodSubtype subtype) {
+ return subtype.getExtraValueOf(Constants.Subtype.ExtraValue.COMBINING_RULES);
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java b/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java
index 42ea3c959..ab2b00e36 100644
--- a/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java
+++ b/java/src/com/android/inputmethod/latin/utils/TargetPackageInfoGetterTask.java
@@ -27,8 +27,7 @@ import com.android.inputmethod.compat.AppWorkaroundsUtils;
public final class TargetPackageInfoGetterTask extends
AsyncTask<String, Void, PackageInfo> {
private static final int MAX_CACHE_ENTRIES = 64; // arbitrary
- private static final LruCache<String, PackageInfo> sCache =
- new LruCache<String, PackageInfo>(MAX_CACHE_ENTRIES);
+ private static final LruCache<String, PackageInfo> sCache = new LruCache<>(MAX_CACHE_ENTRIES);
public static PackageInfo getCachedPackageInfo(final String packageName) {
if (null == packageName) return null;
diff --git a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
index 087a7f255..fafba79c2 100644
--- a/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/TypefaceUtils.java
@@ -30,7 +30,7 @@ public final class TypefaceUtils {
}
// This sparse array caches key label text height in pixel indexed by key label text size.
- private static final SparseArray<Float> sTextHeightCache = CollectionUtils.newSparseArray();
+ private static final SparseArray<Float> sTextHeightCache = new SparseArray<>();
// Working variable for the following method.
private static final Rect sTextHeightBounds = new Rect();
@@ -50,7 +50,7 @@ public final class TypefaceUtils {
}
// This sparse array caches key label text width in pixel indexed by key label text size.
- private static final SparseArray<Float> sTextWidthCache = CollectionUtils.newSparseArray();
+ private static final SparseArray<Float> sTextWidthCache = new SparseArray<>();
// Working variable for the following method.
private static final Rect sTextWidthBounds = new Rect();
diff --git a/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java b/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java
deleted file mode 100644
index 06826dac0..000000000
--- a/java/src/com/android/inputmethod/latin/utils/UsabilityStudyLogUtils.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.inputmethodservice.InputMethodService;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.util.Log;
-import android.view.MotionEvent;
-
-import com.android.inputmethod.latin.LatinImeLogger;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.channels.FileChannel;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-public final class UsabilityStudyLogUtils {
- // TODO: remove code duplication with ResearchLog class
- private static final String USABILITY_TAG = UsabilityStudyLogUtils.class.getSimpleName();
- private static final String FILENAME = "log.txt";
- private final Handler mLoggingHandler;
- private File mFile;
- private File mDirectory;
- private InputMethodService mIms;
- private PrintWriter mWriter;
- private final Date mDate;
- private final SimpleDateFormat mDateFormat;
-
- private UsabilityStudyLogUtils() {
- mDate = new Date();
- mDateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss.SSSZ", Locale.US);
-
- HandlerThread handlerThread = new HandlerThread("UsabilityStudyLogUtils logging task",
- Process.THREAD_PRIORITY_BACKGROUND);
- handlerThread.start();
- mLoggingHandler = new Handler(handlerThread.getLooper());
- }
-
- // Initialization-on-demand holder
- private static final class OnDemandInitializationHolder {
- public static final UsabilityStudyLogUtils sInstance = new UsabilityStudyLogUtils();
- }
-
- public static UsabilityStudyLogUtils getInstance() {
- return OnDemandInitializationHolder.sInstance;
- }
-
- public void init(final InputMethodService ims) {
- mIms = ims;
- mDirectory = ims.getFilesDir();
- }
-
- private void createLogFileIfNotExist() {
- if ((mFile == null || !mFile.exists())
- && (mDirectory != null && mDirectory.exists())) {
- try {
- mWriter = getPrintWriter(mDirectory, FILENAME, false);
- } catch (final IOException e) {
- Log.e(USABILITY_TAG, "Can't create log file.");
- }
- }
- }
-
- public static void writeBackSpace(final int x, final int y) {
- UsabilityStudyLogUtils.getInstance().write("<backspace>\t" + x + "\t" + y);
- }
-
- public static void writeChar(final char c, final int x, final int y) {
- String inputChar = String.valueOf(c);
- switch (c) {
- case '\n':
- inputChar = "<enter>";
- break;
- case '\t':
- inputChar = "<tab>";
- break;
- case ' ':
- inputChar = "<space>";
- break;
- }
- UsabilityStudyLogUtils.getInstance().write(inputChar + "\t" + x + "\t" + y);
- LatinImeLogger.onPrintAllUsabilityStudyLogs();
- }
-
- public static void writeMotionEvent(final MotionEvent me) {
- final int action = me.getActionMasked();
- final long eventTime = me.getEventTime();
- final int pointerCount = me.getPointerCount();
- for (int index = 0; index < pointerCount; index++) {
- final int id = me.getPointerId(index);
- final int x = (int)me.getX(index);
- final int y = (int)me.getY(index);
- final float size = me.getSize(index);
- final float pressure = me.getPressure(index);
-
- final String eventTag;
- switch (action) {
- case MotionEvent.ACTION_UP:
- eventTag = "[Up]";
- break;
- case MotionEvent.ACTION_DOWN:
- eventTag = "[Down]";
- break;
- case MotionEvent.ACTION_POINTER_UP:
- eventTag = "[PointerUp]";
- break;
- case MotionEvent.ACTION_POINTER_DOWN:
- eventTag = "[PointerDown]";
- break;
- case MotionEvent.ACTION_MOVE:
- eventTag = "[Move]";
- break;
- default:
- eventTag = "[Action" + action + "]";
- break;
- }
- getInstance().write(eventTag + eventTime + "," + id + "," + x + "," + y + "," + size
- + "," + pressure);
- }
- }
-
- public void write(final String log) {
- mLoggingHandler.post(new Runnable() {
- @Override
- public void run() {
- createLogFileIfNotExist();
- final long currentTime = System.currentTimeMillis();
- mDate.setTime(currentTime);
-
- final String printString = String.format(Locale.US, "%s\t%d\t%s\n",
- mDateFormat.format(mDate), currentTime, log);
- if (LatinImeLogger.sDBG) {
- Log.d(USABILITY_TAG, "Write: " + log);
- }
- mWriter.print(printString);
- }
- });
- }
-
- private synchronized String getBufferedLogs() {
- mWriter.flush();
- final StringBuilder sb = new StringBuilder();
- final BufferedReader br = getBufferedReader();
- String line;
- try {
- while ((line = br.readLine()) != null) {
- sb.append('\n');
- sb.append(line);
- }
- } catch (final IOException e) {
- Log.e(USABILITY_TAG, "Can't read log file.");
- } finally {
- if (LatinImeLogger.sDBG) {
- Log.d(USABILITY_TAG, "Got all buffered logs\n" + sb.toString());
- }
- try {
- br.close();
- } catch (final IOException e) {
- // ignore.
- }
- }
- return sb.toString();
- }
-
- public void emailResearcherLogsAll() {
- mLoggingHandler.post(new Runnable() {
- @Override
- public void run() {
- final Date date = new Date();
- date.setTime(System.currentTimeMillis());
- final String currentDateTimeString =
- new SimpleDateFormat("yyyyMMdd-HHmmssZ", Locale.US).format(date);
- if (mFile == null) {
- Log.w(USABILITY_TAG, "No internal log file found.");
- return;
- }
- if (mIms.checkCallingOrSelfPermission(
- android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
- != PackageManager.PERMISSION_GRANTED) {
- Log.w(USABILITY_TAG, "Doesn't have the permission WRITE_EXTERNAL_STORAGE");
- return;
- }
- mWriter.flush();
- final String destPath = Environment.getExternalStorageDirectory()
- + "/research-" + currentDateTimeString + ".log";
- final File destFile = new File(destPath);
- try {
- final FileInputStream srcStream = new FileInputStream(mFile);
- final FileOutputStream destStream = new FileOutputStream(destFile);
- final FileChannel src = srcStream.getChannel();
- final FileChannel dest = destStream.getChannel();
- src.transferTo(0, src.size(), dest);
- src.close();
- srcStream.close();
- dest.close();
- destStream.close();
- } catch (final FileNotFoundException e1) {
- Log.w(USABILITY_TAG, e1);
- return;
- } catch (final IOException e2) {
- Log.w(USABILITY_TAG, e2);
- return;
- }
- if (!destFile.exists()) {
- Log.w(USABILITY_TAG, "Dest file doesn't exist.");
- return;
- }
- final Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (LatinImeLogger.sDBG) {
- Log.d(USABILITY_TAG, "Destination file URI is " + destFile.toURI());
- }
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + destPath));
- intent.putExtra(Intent.EXTRA_SUBJECT,
- "[Research Logs] " + currentDateTimeString);
- mIms.startActivity(intent);
- }
- });
- }
-
- public void printAll() {
- mLoggingHandler.post(new Runnable() {
- @Override
- public void run() {
- mIms.getCurrentInputConnection().commitText(getBufferedLogs(), 0);
- }
- });
- }
-
- public void clearAll() {
- mLoggingHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mFile != null && mFile.exists()) {
- if (LatinImeLogger.sDBG) {
- Log.d(USABILITY_TAG, "Delete log file.");
- }
- mFile.delete();
- mWriter.close();
- }
- }
- });
- }
-
- private BufferedReader getBufferedReader() {
- createLogFileIfNotExist();
- try {
- return new BufferedReader(new FileReader(mFile));
- } catch (final FileNotFoundException e) {
- return null;
- }
- }
-
- private PrintWriter getPrintWriter(final File dir, final String filename,
- final boolean renew) throws IOException {
- mFile = new File(dir, filename);
- if (mFile.exists()) {
- if (renew) {
- mFile.delete();
- }
- }
- return new PrintWriter(new FileOutputStream(mFile), true /* autoFlush */);
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java b/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java
deleted file mode 100644
index a75d353c9..000000000
--- a/java/src/com/android/inputmethod/latin/utils/UserLogRingCharBuffer.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.utils;
-
-import android.inputmethodservice.InputMethodService;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.LatinImeLogger;
-import com.android.inputmethod.latin.settings.Settings;
-
-public final class UserLogRingCharBuffer {
- public /* for test */ static final int BUFSIZE = 20;
- public /* for test */ int mLength = 0;
-
- private static UserLogRingCharBuffer sUserLogRingCharBuffer = new UserLogRingCharBuffer();
- private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC';
- private static final int INVALID_COORDINATE = -2;
- private boolean mEnabled = false;
- private int mEnd = 0;
- private char[] mCharBuf = new char[BUFSIZE];
- private int[] mXBuf = new int[BUFSIZE];
- private int[] mYBuf = new int[BUFSIZE];
-
- private UserLogRingCharBuffer() {
- // Intentional empty constructor for singleton.
- }
-
- @UsedForTesting
- public static UserLogRingCharBuffer getInstance() {
- return sUserLogRingCharBuffer;
- }
-
- public static UserLogRingCharBuffer init(final InputMethodService context,
- final boolean enabled, final boolean usabilityStudy) {
- if (!(enabled || usabilityStudy)) {
- return null;
- }
- sUserLogRingCharBuffer.mEnabled = true;
- UsabilityStudyLogUtils.getInstance().init(context);
- return sUserLogRingCharBuffer;
- }
-
- private static int normalize(final int in) {
- int ret = in % BUFSIZE;
- return ret < 0 ? ret + BUFSIZE : ret;
- }
-
- // TODO: accept code points
- @UsedForTesting
- public void push(final char c, final int x, final int y) {
- if (!mEnabled) {
- return;
- }
- if (LatinImeLogger.sUsabilityStudy) {
- UsabilityStudyLogUtils.getInstance().writeChar(c, x, y);
- }
- mCharBuf[mEnd] = c;
- mXBuf[mEnd] = x;
- mYBuf[mEnd] = y;
- mEnd = normalize(mEnd + 1);
- if (mLength < BUFSIZE) {
- ++mLength;
- }
- }
-
- public char pop() {
- if (mLength < 1) {
- return PLACEHOLDER_DELIMITER_CHAR;
- }
- mEnd = normalize(mEnd - 1);
- --mLength;
- return mCharBuf[mEnd];
- }
-
- public char getBackwardNthChar(final int n) {
- if (mLength <= n || n < 0) {
- return PLACEHOLDER_DELIMITER_CHAR;
- }
- return mCharBuf[normalize(mEnd - n - 1)];
- }
-
- public int getPreviousX(final char c, final int back) {
- final int index = normalize(mEnd - 2 - back);
- if (mLength <= back
- || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) {
- return INVALID_COORDINATE;
- }
- return mXBuf[index];
- }
-
- public int getPreviousY(final char c, final int back) {
- int index = normalize(mEnd - 2 - back);
- if (mLength <= back
- || Character.toLowerCase(c) != Character.toLowerCase(mCharBuf[index])) {
- return INVALID_COORDINATE;
- }
- return mYBuf[index];
- }
-
- public String getLastWord(final int ignoreCharCount) {
- final StringBuilder sb = new StringBuilder();
- int i = ignoreCharCount;
- for (; i < mLength; ++i) {
- final char c = mCharBuf[normalize(mEnd - 1 - i)];
- if (!Settings.getInstance().isWordSeparator(c)) {
- break;
- }
- }
- for (; i < mLength; ++i) {
- char c = mCharBuf[normalize(mEnd - 1 - i)];
- if (!Settings.getInstance().isWordSeparator(c)) {
- sb.append(c);
- } else {
- break;
- }
- }
- return sb.reverse().toString();
- }
-
- public void reset() {
- mLength = 0;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java b/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java
deleted file mode 100644
index 4f86526a7..000000000
--- a/java/src/com/android/inputmethod/research/BootBroadcastReceiver.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-/**
- * Arrange for the uploading service to be run on regular intervals.
- */
-public final class BootBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(final Context context, final Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
- UploaderService.cancelAndRescheduleUploadingService(context,
- true /* needsRescheduling */);
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/research/FeedbackActivity.java b/java/src/com/android/inputmethod/research/FeedbackActivity.java
deleted file mode 100644
index 520b88d2f..000000000
--- a/java/src/com/android/inputmethod/research/FeedbackActivity.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-import com.android.inputmethod.latin.R;
-
-public class FeedbackActivity extends Activity {
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.research_feedback_activity);
- final FeedbackLayout layout = (FeedbackLayout) findViewById(R.id.research_feedback_layout);
- layout.setActivity(this);
- }
-
- @Override
- public void onBackPressed() {
- ResearchLogger.getInstance().onLeavingSendFeedbackDialog();
- super.onBackPressed();
- }
-}
diff --git a/java/src/com/android/inputmethod/research/FeedbackFragment.java b/java/src/com/android/inputmethod/research/FeedbackFragment.java
deleted file mode 100644
index 75fbbf1ba..000000000
--- a/java/src/com/android/inputmethod/research/FeedbackFragment.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.app.Fragment;
-import android.os.Bundle;
-import android.text.Editable;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.Toast;
-
-import com.android.inputmethod.latin.R;
-
-public class FeedbackFragment extends Fragment implements OnClickListener {
- private static final String TAG = FeedbackFragment.class.getSimpleName();
-
- public static final String KEY_FEEDBACK_STRING = "FeedbackString";
- public static final String KEY_INCLUDE_ACCOUNT_NAME = "IncludeAccountName";
- public static final String KEY_HAS_USER_RECORDING = "HasRecording";
-
- private EditText mEditText;
- private CheckBox mIncludingAccountNameCheckBox;
- private CheckBox mIncludingUserRecordingCheckBox;
- private Button mSendButton;
- private Button mCancelButton;
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- final View view = inflater.inflate(R.layout.research_feedback_fragment_layout, container,
- false);
- mEditText = (EditText) view.findViewById(R.id.research_feedback_contents);
- mEditText.requestFocus();
- mIncludingAccountNameCheckBox = (CheckBox) view.findViewById(
- R.id.research_feedback_include_account_name);
- mIncludingUserRecordingCheckBox = (CheckBox) view.findViewById(
- R.id.research_feedback_include_recording_checkbox);
- mIncludingUserRecordingCheckBox.setOnClickListener(this);
-
- mSendButton = (Button) view.findViewById(R.id.research_feedback_send_button);
- mSendButton.setOnClickListener(this);
- mCancelButton = (Button) view.findViewById(R.id.research_feedback_cancel_button);
- mCancelButton.setOnClickListener(this);
-
- if (savedInstanceState != null) {
- restoreState(savedInstanceState);
- } else {
- final Bundle bundle = getActivity().getIntent().getExtras();
- if (bundle != null) {
- restoreState(bundle);
- }
- }
- return view;
- }
-
- @Override
- public void onClick(final View view) {
- final ResearchLogger researchLogger = ResearchLogger.getInstance();
- if (view == mIncludingUserRecordingCheckBox) {
- if (mIncludingUserRecordingCheckBox.isChecked()) {
- final Bundle bundle = new Bundle();
- onSaveInstanceState(bundle);
-
- // Let the user make a recording
- getActivity().finish();
-
- researchLogger.setFeedbackDialogBundle(bundle);
- researchLogger.onLeavingSendFeedbackDialog();
- researchLogger.startRecording();
- }
- } else if (view == mSendButton) {
- final Editable editable = mEditText.getText();
- final String feedbackContents = editable.toString();
- if (TextUtils.isEmpty(feedbackContents)) {
- Toast.makeText(getActivity(),
- R.string.research_feedback_empty_feedback_error_message,
- Toast.LENGTH_LONG).show();
- } else {
- final boolean isIncludingAccountName = mIncludingAccountNameCheckBox.isChecked();
- researchLogger.sendFeedback(feedbackContents, false /* isIncludingHistory */,
- isIncludingAccountName, mIncludingUserRecordingCheckBox.isChecked());
- getActivity().finish();
- researchLogger.setFeedbackDialogBundle(null);
- researchLogger.onLeavingSendFeedbackDialog();
- }
- } else if (view == mCancelButton) {
- Log.d(TAG, "Finishing");
- getActivity().finish();
- researchLogger.setFeedbackDialogBundle(null);
- researchLogger.onLeavingSendFeedbackDialog();
- } else {
- Log.e(TAG, "Unknown view passed to FeedbackFragment.onClick()");
- }
- }
-
- @Override
- public void onSaveInstanceState(final Bundle bundle) {
- final String savedFeedbackString = mEditText.getText().toString();
-
- bundle.putString(KEY_FEEDBACK_STRING, savedFeedbackString);
- bundle.putBoolean(KEY_INCLUDE_ACCOUNT_NAME, mIncludingAccountNameCheckBox.isChecked());
- bundle.putBoolean(KEY_HAS_USER_RECORDING, mIncludingUserRecordingCheckBox.isChecked());
- }
-
- private void restoreState(final Bundle bundle) {
- mEditText.setText(bundle.getString(KEY_FEEDBACK_STRING));
- mIncludingAccountNameCheckBox.setChecked(bundle.getBoolean(KEY_INCLUDE_ACCOUNT_NAME));
- mIncludingUserRecordingCheckBox.setChecked(bundle.getBoolean(KEY_HAS_USER_RECORDING));
- }
-}
diff --git a/java/src/com/android/inputmethod/research/FeedbackLayout.java b/java/src/com/android/inputmethod/research/FeedbackLayout.java
deleted file mode 100644
index d283d14b2..000000000
--- a/java/src/com/android/inputmethod/research/FeedbackLayout.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.app.Activity;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.widget.LinearLayout;
-
-public class FeedbackLayout extends LinearLayout {
- private Activity mActivity;
-
- public FeedbackLayout(Context context) {
- super(context);
- }
-
- public FeedbackLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public FeedbackLayout(Context context, AttributeSet attrs, int defstyle) {
- super(context, attrs, defstyle);
- }
-
- public void setActivity(Activity activity) {
- mActivity = activity;
- }
-
- @Override
- public boolean dispatchKeyEventPreIme(KeyEvent event) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- KeyEvent.DispatcherState state = getKeyDispatcherState();
- if (state != null) {
- if (event.getAction() == KeyEvent.ACTION_DOWN
- && event.getRepeatCount() == 0) {
- state.startTracking(event, this);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP
- && !event.isCanceled() && state.isTracking(event)) {
- mActivity.onBackPressed();
- return true;
- }
- }
- }
- return super.dispatchKeyEventPreIme(event);
- }
-}
diff --git a/java/src/com/android/inputmethod/research/FeedbackLog.java b/java/src/com/android/inputmethod/research/FeedbackLog.java
deleted file mode 100644
index 5af194c32..000000000
--- a/java/src/com/android/inputmethod/research/FeedbackLog.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.Context;
-
-import java.io.File;
-
-public class FeedbackLog extends ResearchLog {
- public FeedbackLog(final File outputFile, final Context context) {
- super(outputFile, context);
- }
-
- @Override
- public boolean isFeedbackLog() {
- return true;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/FixedLogBuffer.java b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
deleted file mode 100644
index 8b64de8ae..000000000
--- a/java/src/com/android/inputmethod/research/FixedLogBuffer.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-
-/**
- * A buffer that holds a fixed number of LogUnits.
- *
- * LogUnits are added in and shifted out in temporal order. Only a subset of the LogUnits are
- * actual words; the other LogUnits do not count toward the word limit. Once the buffer reaches
- * capacity, adding another LogUnit that is a word evicts the oldest LogUnits out one at a time to
- * stay under the capacity limit.
- *
- * This variant of a LogBuffer has a limited memory footprint because of its limited size. This
- * makes it useful, for example, for recording a window of the user's most recent actions in case
- * they want to report an observed error that they do not know how to reproduce.
- */
-public class FixedLogBuffer extends LogBuffer {
- /* package for test */ int mWordCapacity;
- // The number of members of mLogUnits that are actual words.
- private int mNumActualWords;
-
- /**
- * Create a new LogBuffer that can hold a fixed number of LogUnits that are words (and
- * unlimited number of non-word LogUnits), and that outputs its result to a researchLog.
- *
- * @param wordCapacity maximum number of words
- */
- public FixedLogBuffer(final int wordCapacity) {
- super();
- if (wordCapacity <= 0) {
- throw new IllegalArgumentException("wordCapacity must be 1 or greater.");
- }
- mWordCapacity = wordCapacity;
- mNumActualWords = 0;
- }
-
- /**
- * Adds a new LogUnit to the front of the LIFO queue, evicting existing LogUnit's
- * (oldest first) if word capacity is reached.
- */
- @Override
- public void shiftIn(final LogUnit newLogUnit) {
- if (!newLogUnit.hasOneOrMoreWords()) {
- // This LogUnit doesn't contain any word, so it doesn't count toward the word-limit.
- super.shiftIn(newLogUnit);
- return;
- }
- final int numWordsIncoming = newLogUnit.getNumWords();
- if (mNumActualWords >= mWordCapacity) {
- // Give subclass a chance to handle the buffer full condition by shifting out logUnits.
- // TODO: Tell onBufferFull() how much space it needs to make to avoid forced eviction.
- onBufferFull();
- // If still full, evict.
- if (mNumActualWords >= mWordCapacity) {
- shiftOutWords(numWordsIncoming);
- }
- }
- super.shiftIn(newLogUnit);
- mNumActualWords += numWordsIncoming;
- }
-
- @Override
- public LogUnit unshiftIn() {
- final LogUnit logUnit = super.unshiftIn();
- if (logUnit != null && logUnit.hasOneOrMoreWords()) {
- mNumActualWords -= logUnit.getNumWords();
- }
- return logUnit;
- }
-
- public int getNumWords() {
- return mNumActualWords;
- }
-
- /**
- * Removes all LogUnits from the buffer without calling onShiftOut().
- */
- @Override
- public void clear() {
- super.clear();
- mNumActualWords = 0;
- }
-
- /**
- * Called when the buffer has just shifted in one more word than its maximum, and its about to
- * shift out LogUnits to bring it back down to the maximum.
- *
- * Base class does nothing; subclasses may override if they want to record non-privacy sensitive
- * events that fall off the end.
- */
- protected void onBufferFull() {
- }
-
- @Override
- public LogUnit shiftOut() {
- final LogUnit logUnit = super.shiftOut();
- if (logUnit != null && logUnit.hasOneOrMoreWords()) {
- mNumActualWords -= logUnit.getNumWords();
- }
- return logUnit;
- }
-
- /**
- * Remove LogUnits from the front of the LogBuffer until {@code numWords} have been removed.
- *
- * If there are less than {@code numWords} in the buffer, shifts out all {@code LogUnit}s.
- *
- * @param numWords the minimum number of words in {@link LogUnit}s to shift out
- * @return the number of actual words LogUnit}s shifted out
- */
- protected int shiftOutWords(final int numWords) {
- int numWordsShiftedOut = 0;
- do {
- final LogUnit logUnit = shiftOut();
- if (logUnit == null) break;
- numWordsShiftedOut += logUnit.getNumWords();
- } while (numWordsShiftedOut < numWords);
- return numWordsShiftedOut;
- }
-
- public void shiftOutAll() {
- final LinkedList<LogUnit> logUnits = getLogUnits();
- while (!logUnits.isEmpty()) {
- shiftOut();
- }
- mNumActualWords = 0;
- }
-
- /**
- * Returns a list of {@link LogUnit}s at the front of the buffer that have words associated with
- * them.
- *
- * There will be no more than {@code n} words in the returned list. So if 2 words are
- * requested, and the first LogUnit has 3 words, it is not returned. If 2 words are requested,
- * and the first LogUnit has only 1 word, and the next LogUnit 2 words, only the first LogUnit
- * is returned. If the first LogUnit has no words associated with it, and the second LogUnit
- * has three words, then only the first LogUnit (which has no associated words) is returned. If
- * there are not enough LogUnits in the buffer to meet the word requirement, then all LogUnits
- * will be returned.
- *
- * @param n The maximum number of {@link LogUnit}s with words to return.
- * @return The list of the {@link LogUnit}s containing the first n words
- */
- public ArrayList<LogUnit> peekAtFirstNWords(int n) {
- final LinkedList<LogUnit> logUnits = getLogUnits();
- // Allocate space for n*2 logUnits. There will be at least n, one for each word, and
- // there may be additional for punctuation, between-word commands, etc. This should be
- // enough that reallocation won't be necessary.
- final ArrayList<LogUnit> resultList = new ArrayList<LogUnit>(n * 2);
- for (final LogUnit logUnit : logUnits) {
- n -= logUnit.getNumWords();
- if (n < 0) break;
- resultList.add(logUnit);
- }
- return resultList;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/JsonUtils.java b/java/src/com/android/inputmethod/research/JsonUtils.java
deleted file mode 100644
index 6170b4339..000000000
--- a/java/src/com/android/inputmethod/research/JsonUtils.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.SharedPreferences;
-import android.util.JsonWriter;
-import android.view.MotionEvent;
-import android.view.inputmethod.CompletionInfo;
-
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-
-import java.io.IOException;
-import java.util.Map;
-
-/**
- * Routines for mapping classes and variables to JSON representations for logging.
- */
-/* package */ class JsonUtils {
- private JsonUtils() {
- // This utility class is not publicly instantiable.
- }
-
- /* package */ static void writeJson(final CompletionInfo[] ci, final JsonWriter jsonWriter)
- throws IOException {
- jsonWriter.beginArray();
- for (int j = 0; j < ci.length; j++) {
- jsonWriter.value(ci[j].toString());
- }
- jsonWriter.endArray();
- }
-
- /* package */ static void writeJson(final SharedPreferences prefs, final JsonWriter jsonWriter)
- throws IOException {
- jsonWriter.beginObject();
- for (Map.Entry<String,?> entry : prefs.getAll().entrySet()) {
- jsonWriter.name(entry.getKey());
- final Object innerValue = entry.getValue();
- if (innerValue == null) {
- jsonWriter.nullValue();
- } else if (innerValue instanceof Boolean) {
- jsonWriter.value((Boolean) innerValue);
- } else if (innerValue instanceof Number) {
- jsonWriter.value((Number) innerValue);
- } else {
- jsonWriter.value(innerValue.toString());
- }
- }
- jsonWriter.endObject();
- }
-
- /* package */ static void writeJson(final Key[] keys, final JsonWriter jsonWriter)
- throws IOException {
- jsonWriter.beginArray();
- for (Key key : keys) {
- writeJson(key, jsonWriter);
- }
- jsonWriter.endArray();
- }
-
- private static void writeJson(final Key key, final JsonWriter jsonWriter) throws IOException {
- jsonWriter.beginObject();
- jsonWriter.name("code").value(key.getCode());
- jsonWriter.name("altCode").value(key.getAltCode());
- jsonWriter.name("x").value(key.getX());
- jsonWriter.name("y").value(key.getY());
- jsonWriter.name("w").value(key.getWidth());
- jsonWriter.name("h").value(key.getHeight());
- jsonWriter.endObject();
- }
-
- /* package */ static void writeJson(final SuggestedWords words, final JsonWriter jsonWriter)
- throws IOException {
- jsonWriter.beginObject();
- jsonWriter.name("typedWordValid").value(words.mTypedWordValid);
- jsonWriter.name("willAutoCorrect")
- .value(words.mWillAutoCorrect);
- jsonWriter.name("isPunctuationSuggestions")
- .value(words.isPunctuationSuggestions());
- jsonWriter.name("isObsoleteSuggestions").value(words.mIsObsoleteSuggestions);
- jsonWriter.name("isPrediction").value(words.mIsPrediction);
- jsonWriter.name("suggestedWords");
- jsonWriter.beginArray();
- final int size = words.size();
- for (int j = 0; j < size; j++) {
- final SuggestedWordInfo wordInfo = words.getInfo(j);
- jsonWriter.beginObject();
- jsonWriter.name("word").value(wordInfo.toString());
- jsonWriter.name("score").value(wordInfo.mScore);
- jsonWriter.name("kind").value(wordInfo.mKind);
- jsonWriter.name("sourceDict").value(wordInfo.mSourceDict.mDictType);
- jsonWriter.endObject();
- }
- jsonWriter.endArray();
- jsonWriter.endObject();
- }
-
- /* package */ static void writeJson(final MotionEvent me, final JsonWriter jsonWriter)
- throws IOException {
- jsonWriter.beginObject();
- jsonWriter.name("pointerIds");
- jsonWriter.beginArray();
- final int pointerCount = me.getPointerCount();
- for (int index = 0; index < pointerCount; index++) {
- jsonWriter.value(me.getPointerId(index));
- }
- jsonWriter.endArray();
-
- jsonWriter.name("xyt");
- jsonWriter.beginArray();
- final int historicalSize = me.getHistorySize();
- for (int index = 0; index < historicalSize; index++) {
- jsonWriter.beginObject();
- jsonWriter.name("t");
- jsonWriter.value(me.getHistoricalEventTime(index));
- jsonWriter.name("d");
- jsonWriter.beginArray();
- for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
- jsonWriter.beginObject();
- jsonWriter.name("x");
- jsonWriter.value(me.getHistoricalX(pointerIndex, index));
- jsonWriter.name("y");
- jsonWriter.value(me.getHistoricalY(pointerIndex, index));
- jsonWriter.endObject();
- }
- jsonWriter.endArray();
- jsonWriter.endObject();
- }
- jsonWriter.beginObject();
- jsonWriter.name("t");
- jsonWriter.value(me.getEventTime());
- jsonWriter.name("d");
- jsonWriter.beginArray();
- for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
- jsonWriter.beginObject();
- jsonWriter.name("x");
- jsonWriter.value(me.getX(pointerIndex));
- jsonWriter.name("y");
- jsonWriter.value(me.getY(pointerIndex));
- jsonWriter.endObject();
- }
- jsonWriter.endArray();
- jsonWriter.endObject();
- jsonWriter.endArray();
- jsonWriter.endObject();
- }
-}
diff --git a/java/src/com/android/inputmethod/research/LogBuffer.java b/java/src/com/android/inputmethod/research/LogBuffer.java
deleted file mode 100644
index b07b761f0..000000000
--- a/java/src/com/android/inputmethod/research/LogBuffer.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import java.util.LinkedList;
-
-/**
- * Maintain a FIFO queue of LogUnits.
- *
- * This class provides an unbounded queue. This is useful when the user is aware that their actions
- * are being recorded, such as when they are trying to reproduce a bug. In this case, there should
- * not be artificial restrictions on how many events that can be saved.
- */
-public class LogBuffer {
- // TODO: Gracefully handle situations in which this LogBuffer is consuming too much memory.
- // This may happen, for example, if the user has forgotten that data is being logged.
- private final LinkedList<LogUnit> mLogUnits;
-
- public LogBuffer() {
- mLogUnits = new LinkedList<LogUnit>();
- }
-
- protected LinkedList<LogUnit> getLogUnits() {
- return mLogUnits;
- }
-
- public void clear() {
- mLogUnits.clear();
- }
-
- public void shiftIn(final LogUnit logUnit) {
- mLogUnits.add(logUnit);
- }
-
- public LogUnit unshiftIn() {
- if (mLogUnits.isEmpty()) {
- return null;
- }
- return mLogUnits.removeLast();
- }
-
- public LogUnit peekLastLogUnit() {
- if (mLogUnits.isEmpty()) {
- return null;
- }
- return mLogUnits.peekLast();
- }
-
- public boolean isEmpty() {
- return mLogUnits.isEmpty();
- }
-
- public LogUnit shiftOut() {
- if (isEmpty()) {
- return null;
- }
- return mLogUnits.removeFirst();
- }
-}
diff --git a/java/src/com/android/inputmethod/research/LogStatement.java b/java/src/com/android/inputmethod/research/LogStatement.java
deleted file mode 100644
index 06b918af5..000000000
--- a/java/src/com/android/inputmethod/research/LogStatement.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.SharedPreferences;
-import android.util.JsonWriter;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.inputmethod.CompletionInfo;
-
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.io.IOException;
-
-/**
- * A template for typed information stored in the logs.
- *
- * A LogStatement contains a name, keys, and flags about whether the {@code Object[] values}
- * associated with the {@code String[] keys} are likely to reveal information about the user. The
- * actual values are stored separately.
- */
-public class LogStatement {
- private static final String TAG = LogStatement.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
-
- // Constants for particular statements
- public static final String TYPE_POINTER_TRACKER_CALL_LISTENER_ON_CODE_INPUT =
- "PointerTrackerCallListenerOnCodeInput";
- public static final String KEY_CODE = "code";
- public static final String VALUE_RESEARCH = "research";
- public static final String TYPE_MAIN_KEYBOARD_VIEW_ON_LONG_PRESS =
- "MainKeyboardViewOnLongPress";
- public static final String ACTION = "action";
- public static final String VALUE_DOWN = "DOWN";
- public static final String TYPE_MOTION_EVENT = "MotionEvent";
- public static final String KEY_IS_LOGGING_RELATED = "isLoggingRelated";
-
- // Keys for internal key/value pairs
- private static final String CURRENT_TIME_KEY = "_ct";
- private static final String UPTIME_KEY = "_ut";
- private static final String EVENT_TYPE_KEY = "_ty";
-
- // Name specifying the LogStatement type.
- private final String mType;
-
- // mIsPotentiallyPrivate indicates that event contains potentially private information. If
- // the word that this event is a part of is determined to be privacy-sensitive, then this
- // event should not be included in the output log. The system waits to output until the
- // containing word is known.
- private final boolean mIsPotentiallyPrivate;
-
- // mIsPotentiallyRevealing indicates that this statement may disclose details about other
- // words typed in other LogUnits. This can happen if the user is not inserting spaces, and
- // data from Suggestions and/or Composing text reveals the entire "megaword". For example,
- // say the user is typing "for the win", and the system wants to record the bigram "the
- // win". If the user types "forthe", omitting the space, the system will give "for the" as
- // a suggestion. If the user accepts the autocorrection, the suggestion for "for the" is
- // included in the log for the word "the", disclosing that the previous word had been "for".
- // For now, we simply do not include this data when logging part of a "megaword".
- private final boolean mIsPotentiallyRevealing;
-
- // mKeys stores the names that are the attributes in the output json objects
- private final String[] mKeys;
- private static final String[] NULL_KEYS = new String[0];
-
- LogStatement(final String name, final boolean isPotentiallyPrivate,
- final boolean isPotentiallyRevealing, final String... keys) {
- mType = name;
- mIsPotentiallyPrivate = isPotentiallyPrivate;
- mIsPotentiallyRevealing = isPotentiallyRevealing;
- mKeys = (keys == null) ? NULL_KEYS : keys;
- }
-
- public String getType() {
- return mType;
- }
-
- public boolean isPotentiallyPrivate() {
- return mIsPotentiallyPrivate;
- }
-
- public boolean isPotentiallyRevealing() {
- return mIsPotentiallyRevealing;
- }
-
- public String[] getKeys() {
- return mKeys;
- }
-
- /**
- * Utility function to test whether a key-value pair exists in a LogStatement.
- *
- * A LogStatement is really just a template -- it does not contain the values, only the
- * keys. So the values must be passed in as an argument.
- *
- * @param queryKey the String that is tested by {@code String.equals()} to the keys in the
- * LogStatement
- * @param queryValue an Object that must be {@code Object.equals()} to the key's corresponding
- * value in the {@code values} array
- * @param values the values corresponding to mKeys
- *
- * @returns {@true} if {@code queryKey} exists in the keys for this LogStatement, and {@code
- * queryValue} matches the corresponding value in {@code values}
- *
- * @throws IllegalArgumentException if {@code values.length} is not equal to keys().length()
- */
- public boolean containsKeyValuePair(final String queryKey, final Object queryValue,
- final Object[] values) {
- if (mKeys.length != values.length) {
- throw new IllegalArgumentException("Mismatched number of keys and values.");
- }
- final int length = mKeys.length;
- for (int i = 0; i < length; i++) {
- if (mKeys[i].equals(queryKey) && values[i].equals(queryValue)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Utility function to set a value in a LogStatement.
- *
- * A LogStatement is really just a template -- it does not contain the values, only the
- * keys. So the values must be passed in as an argument.
- *
- * @param queryKey the String that is tested by {@code String.equals()} to the keys in the
- * LogStatement
- * @param values the array of values corresponding to mKeys
- * @param newValue the replacement value to go into the {@code values} array
- *
- * @returns {@true} if the key exists and the value was successfully set, {@false} otherwise
- *
- * @throws IllegalArgumentException if {@code values.length} is not equal to keys().length()
- */
- public boolean setValue(final String queryKey, final Object[] values, final Object newValue) {
- if (mKeys.length != values.length) {
- throw new IllegalArgumentException("Mismatched number of keys and values.");
- }
- final int length = mKeys.length;
- for (int i = 0; i < length; i++) {
- if (mKeys[i].equals(queryKey)) {
- values[i] = newValue;
- return true;
- }
- }
- return false;
- }
-
- /**
- * Write the contents out through jsonWriter.
- *
- * The JsonWriter class must have already had {@code JsonWriter.beginArray} called on it.
- *
- * Note that this method is not thread safe for the same jsonWriter. Callers must ensure
- * thread safety.
- */
- public boolean outputToLocked(final JsonWriter jsonWriter, final Long time,
- final Object... values) {
- if (DEBUG) {
- if (mKeys.length != values.length) {
- Log.d(TAG, "Key and Value list sizes do not match. " + mType);
- }
- }
- try {
- jsonWriter.beginObject();
- jsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
- jsonWriter.name(UPTIME_KEY).value(time);
- jsonWriter.name(EVENT_TYPE_KEY).value(mType);
- final int length = values.length;
- for (int i = 0; i < length; i++) {
- jsonWriter.name(mKeys[i]);
- final Object value = values[i];
- if (value instanceof CharSequence) {
- jsonWriter.value(value.toString());
- } else if (value instanceof Number) {
- jsonWriter.value((Number) value);
- } else if (value instanceof Boolean) {
- jsonWriter.value((Boolean) value);
- } else if (value instanceof CompletionInfo[]) {
- JsonUtils.writeJson((CompletionInfo[]) value, jsonWriter);
- } else if (value instanceof SharedPreferences) {
- JsonUtils.writeJson((SharedPreferences) value, jsonWriter);
- } else if (value instanceof Key[]) {
- JsonUtils.writeJson((Key[]) value, jsonWriter);
- } else if (value instanceof SuggestedWords) {
- JsonUtils.writeJson((SuggestedWords) value, jsonWriter);
- } else if (value instanceof MotionEvent) {
- JsonUtils.writeJson((MotionEvent) value, jsonWriter);
- } else if (value == null) {
- jsonWriter.nullValue();
- } else {
- if (DEBUG) {
- Log.w(TAG, "Unrecognized type to be logged: "
- + (value == null ? "<null>" : value.getClass().getName()));
- }
- jsonWriter.nullValue();
- }
- }
- jsonWriter.endObject();
- } catch (IOException e) {
- e.printStackTrace();
- Log.w(TAG, "Error in JsonWriter; skipping LogStatement");
- return false;
- }
- return true;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
deleted file mode 100644
index 3366df12a..000000000
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.JsonWriter;
-import android.util.Log;
-
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Pattern;
-
-/**
- * A group of log statements related to each other.
- *
- * A LogUnit is collection of LogStatements, each of which is generated by at a particular point
- * in the code. (There is no LogStatement class; the data is stored across the instance variables
- * here.) A single LogUnit's statements can correspond to all the calls made while in the same
- * composing region, or all the calls between committing the last composing region, and the first
- * character of the next composing region.
- *
- * Individual statements in a log may be marked as potentially private. If so, then they are only
- * published to a ResearchLog if the ResearchLogger determines that publishing the entire LogUnit
- * will not violate the user's privacy. Checks for this may include whether other LogUnits have
- * been published recently, or whether the LogUnit contains numbers, etc.
- */
-public class LogUnit {
- private static final String TAG = LogUnit.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
-
- private static final Pattern WHITESPACE_PATTERN = Pattern.compile("\\s+");
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
- private final ArrayList<LogStatement> mLogStatementList;
- private final ArrayList<Object[]> mValuesList;
- // Assume that mTimeList is sorted in increasing order. Do not insert null values into
- // mTimeList.
- private final ArrayList<Long> mTimeList;
- // Words that this LogUnit generates. Should be null if the data in the LogUnit does not
- // generate a genuine word (i.e. separators alone do not count as a word). Should never be
- // empty. Note that if the user types spaces explicitly, then normally mWords should contain
- // only a single word; it will only contain space-separate multiple words if the user does not
- // enter a space, and the system enters one automatically.
- private String mWords;
- private String[] mWordArray = EMPTY_STRING_ARRAY;
- private boolean mMayContainDigit;
- private boolean mIsPartOfMegaword;
- private boolean mContainsUserDeletions;
-
- // mCorrectionType indicates whether the word was corrected at all, and if so, the nature of the
- // correction.
- private int mCorrectionType;
- // LogUnits start in this state. If a word is entered without being corrected, it will have
- // this CorrectiontType.
- public static final int CORRECTIONTYPE_NO_CORRECTION = 0;
- // The LogUnit was corrected manually by the user in an unspecified way.
- public static final int CORRECTIONTYPE_CORRECTION = 1;
- // The LogUnit was corrected manually by the user to a word not in the list of suggestions of
- // the first word typed here. (Note: this is a heuristic value, it may be incorrect, for
- // example, if the user repositions the cursor).
- public static final int CORRECTIONTYPE_DIFFERENT_WORD = 2;
- // The LogUnit was corrected manually by the user to a word that was in the list of suggestions
- // of the first word typed here. (Again, a heuristic). It is probably a typo correction.
- public static final int CORRECTIONTYPE_TYPO = 3;
- // TODO: Rather than just tracking the current state, keep a historical record of the LogUnit's
- // state and statistics. This should include how many times it has been corrected, whether
- // other LogUnit edits were done between edits to this LogUnit, etc. Also track when a LogUnit
- // previously contained a word, but was corrected to empty (because it was deleted, and there is
- // no known replacement).
-
- private SuggestedWords mSuggestedWords;
-
- public LogUnit() {
- mLogStatementList = new ArrayList<LogStatement>();
- mValuesList = new ArrayList<Object[]>();
- mTimeList = new ArrayList<Long>();
- mIsPartOfMegaword = false;
- mCorrectionType = CORRECTIONTYPE_NO_CORRECTION;
- mSuggestedWords = null;
- }
-
- private LogUnit(final ArrayList<LogStatement> logStatementList,
- final ArrayList<Object[]> valuesList,
- final ArrayList<Long> timeList,
- final boolean isPartOfMegaword) {
- mLogStatementList = logStatementList;
- mValuesList = valuesList;
- mTimeList = timeList;
- mIsPartOfMegaword = isPartOfMegaword;
- mCorrectionType = CORRECTIONTYPE_NO_CORRECTION;
- mSuggestedWords = null;
- }
-
- private static final Object[] NULL_VALUES = new Object[0];
- /**
- * Adds a new log statement. The time parameter in successive calls to this method must be
- * monotonically increasing, or splitByTime() will not work.
- */
- public void addLogStatement(final LogStatement logStatement, final long time,
- Object... values) {
- if (values == null) {
- values = NULL_VALUES;
- }
- mLogStatementList.add(logStatement);
- mValuesList.add(values);
- mTimeList.add(time);
- }
-
- /**
- * Publish the contents of this LogUnit to {@code researchLog}.
- *
- * For each publishable {@code LogStatement}, invoke {@link LogStatement#outputToLocked}.
- *
- * @param researchLog where to publish the contents of this {@code LogUnit}
- * @param canIncludePrivateData whether the private data in this {@code LogUnit} should be
- * included
- *
- * @throws IOException if publication to the log file is not possible
- */
- public synchronized void publishTo(final ResearchLog researchLog,
- final boolean canIncludePrivateData) throws IOException {
- // Write out any logStatement that passes the privacy filter.
- final int size = mLogStatementList.size();
- if (size != 0) {
- // Note that jsonWriter is only set to a non-null value if the logUnit start text is
- // output and at least one logStatement is output.
- JsonWriter jsonWriter = researchLog.getInitializedJsonWriterLocked();
- outputLogUnitStart(jsonWriter, canIncludePrivateData);
- for (int i = 0; i < size; i++) {
- final LogStatement logStatement = mLogStatementList.get(i);
- if (!canIncludePrivateData && logStatement.isPotentiallyPrivate()) {
- continue;
- }
- if (mIsPartOfMegaword && logStatement.isPotentiallyRevealing()) {
- continue;
- }
- logStatement.outputToLocked(jsonWriter, mTimeList.get(i), mValuesList.get(i));
- }
- outputLogUnitStop(jsonWriter);
- }
- }
-
- private static final String WORD_KEY = "_wo";
- private static final String NUM_WORDS_KEY = "_nw";
- private static final String CORRECTION_TYPE_KEY = "_corType";
- private static final String LOG_UNIT_BEGIN_KEY = "logUnitStart";
- private static final String LOG_UNIT_END_KEY = "logUnitEnd";
-
- final LogStatement LOGSTATEMENT_LOG_UNIT_BEGIN_WITH_PRIVATE_DATA =
- new LogStatement(LOG_UNIT_BEGIN_KEY, false /* isPotentiallyPrivate */,
- false /* isPotentiallyRevealing */, WORD_KEY, CORRECTION_TYPE_KEY,
- NUM_WORDS_KEY);
- final LogStatement LOGSTATEMENT_LOG_UNIT_BEGIN_WITHOUT_PRIVATE_DATA =
- new LogStatement(LOG_UNIT_BEGIN_KEY, false /* isPotentiallyPrivate */,
- false /* isPotentiallyRevealing */, NUM_WORDS_KEY);
- private void outputLogUnitStart(final JsonWriter jsonWriter,
- final boolean canIncludePrivateData) {
- final LogStatement logStatement;
- if (canIncludePrivateData) {
- LOGSTATEMENT_LOG_UNIT_BEGIN_WITH_PRIVATE_DATA.outputToLocked(jsonWriter,
- SystemClock.uptimeMillis(), getWordsAsString(), getCorrectionType(),
- getNumWords());
- } else {
- LOGSTATEMENT_LOG_UNIT_BEGIN_WITHOUT_PRIVATE_DATA.outputToLocked(jsonWriter,
- SystemClock.uptimeMillis(), getNumWords());
- }
- }
-
- final LogStatement LOGSTATEMENT_LOG_UNIT_END =
- new LogStatement(LOG_UNIT_END_KEY, false /* isPotentiallyPrivate */,
- false /* isPotentiallyRevealing */);
- private void outputLogUnitStop(final JsonWriter jsonWriter) {
- LOGSTATEMENT_LOG_UNIT_END.outputToLocked(jsonWriter, SystemClock.uptimeMillis());
- }
-
- /**
- * Mark the current logUnit as containing data to generate {@code newWords}.
- *
- * If {@code setWord()} was previously called for this LogUnit, then the method will try to
- * determine what kind of correction it is, and update its internal state of the correctionType
- * accordingly.
- *
- * @param newWords The words this LogUnit generates. Caller should not pass null or the empty
- * string.
- */
- public void setWords(final String newWords) {
- if (hasOneOrMoreWords()) {
- // The word was already set once, and it is now being changed. See if the new word
- // is close to the old word. If so, then the change is probably a typo correction.
- // If not, the user may have decided to enter a different word, so flag it.
- if (mSuggestedWords != null) {
- if (isInSuggestedWords(newWords, mSuggestedWords)) {
- mCorrectionType = CORRECTIONTYPE_TYPO;
- } else {
- mCorrectionType = CORRECTIONTYPE_DIFFERENT_WORD;
- }
- } else {
- // No suggested words, so it's not clear whether it's a typo or different word.
- // Mark it as a generic correction.
- mCorrectionType = CORRECTIONTYPE_CORRECTION;
- }
- } else {
- mCorrectionType = CORRECTIONTYPE_NO_CORRECTION;
- }
- mWords = newWords;
-
- // Update mWordArray
- mWordArray = (TextUtils.isEmpty(mWords)) ? EMPTY_STRING_ARRAY
- : WHITESPACE_PATTERN.split(mWords);
- if (mWordArray.length > 0 && TextUtils.isEmpty(mWordArray[0])) {
- // Empty string at beginning of array. Must have been whitespace at the start of the
- // word. Remove the empty string.
- mWordArray = Arrays.copyOfRange(mWordArray, 1, mWordArray.length);
- }
- }
-
- public String getWordsAsString() {
- return mWords;
- }
-
- /**
- * Retuns the words generated by the data in this LogUnit.
- *
- * The first word may be an empty string, if the data in the LogUnit started by generating
- * whitespace.
- *
- * @return the array of words. an empty list of there are no words associated with this LogUnit.
- */
- public String[] getWordsAsStringArray() {
- return mWordArray;
- }
-
- public boolean hasOneOrMoreWords() {
- return mWordArray.length >= 1;
- }
-
- public int getNumWords() {
- return mWordArray.length;
- }
-
- // TODO: Refactor to eliminate getter/setters
- public void setMayContainDigit() {
- mMayContainDigit = true;
- }
-
- // TODO: Refactor to eliminate getter/setters
- public boolean mayContainDigit() {
- return mMayContainDigit;
- }
-
- // TODO: Refactor to eliminate getter/setters
- public void setContainsUserDeletions() {
- mContainsUserDeletions = true;
- }
-
- // TODO: Refactor to eliminate getter/setters
- public boolean containsUserDeletions() {
- return mContainsUserDeletions;
- }
-
- // TODO: Refactor to eliminate getter/setters
- public void setCorrectionType(final int correctionType) {
- mCorrectionType = correctionType;
- }
-
- // TODO: Refactor to eliminate getter/setters
- public int getCorrectionType() {
- return mCorrectionType;
- }
-
- public boolean isEmpty() {
- return mLogStatementList.isEmpty();
- }
-
- /**
- * Split this logUnit, with all events before maxTime staying in the current logUnit, and all
- * events after maxTime going into a new LogUnit that is returned.
- */
- public LogUnit splitByTime(final long maxTime) {
- // Assume that mTimeList is in sorted order.
- final int length = mTimeList.size();
- // TODO: find time by binary search, e.g. using Collections#binarySearch()
- for (int index = 0; index < length; index++) {
- if (mTimeList.get(index) > maxTime) {
- final List<LogStatement> laterLogStatements =
- mLogStatementList.subList(index, length);
- final List<Object[]> laterValues = mValuesList.subList(index, length);
- final List<Long> laterTimes = mTimeList.subList(index, length);
-
- // Create the LogUnit containing the later logStatements and associated data.
- final LogUnit newLogUnit = new LogUnit(
- new ArrayList<LogStatement>(laterLogStatements),
- new ArrayList<Object[]>(laterValues),
- new ArrayList<Long>(laterTimes),
- true /* isPartOfMegaword */);
- newLogUnit.mWords = null;
- newLogUnit.mMayContainDigit = mMayContainDigit;
- newLogUnit.mContainsUserDeletions = mContainsUserDeletions;
-
- // Purge the logStatements and associated data from this LogUnit.
- laterLogStatements.clear();
- laterValues.clear();
- laterTimes.clear();
- mIsPartOfMegaword = true;
-
- return newLogUnit;
- }
- }
- return new LogUnit();
- }
-
- public void append(final LogUnit logUnit) {
- mLogStatementList.addAll(logUnit.mLogStatementList);
- mValuesList.addAll(logUnit.mValuesList);
- mTimeList.addAll(logUnit.mTimeList);
- mWords = null;
- if (logUnit.mWords != null) {
- setWords(logUnit.mWords);
- }
- mMayContainDigit = mMayContainDigit || logUnit.mMayContainDigit;
- mContainsUserDeletions = mContainsUserDeletions || logUnit.mContainsUserDeletions;
- mIsPartOfMegaword = false;
- }
-
- public SuggestedWords getSuggestions() {
- return mSuggestedWords;
- }
-
- /**
- * Initialize the suggestions.
- *
- * Once set to a non-null value, the suggestions may not be changed again. This is to keep
- * track of the list of words that are close to the user's initial effort to type the word.
- * Only words that are close to the initial effort are considered typo corrections.
- */
- public void initializeSuggestions(final SuggestedWords suggestedWords) {
- if (mSuggestedWords == null) {
- mSuggestedWords = suggestedWords;
- }
- }
-
- private static boolean isInSuggestedWords(final String queryWord,
- final SuggestedWords suggestedWords) {
- if (TextUtils.isEmpty(queryWord)) {
- return false;
- }
- final int size = suggestedWords.size();
- for (int i = 0; i < size; i++) {
- final SuggestedWordInfo wordInfo = suggestedWords.getInfo(i);
- if (queryWord.equals(wordInfo.mWord)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Remove data associated with selecting the Research button.
- *
- * A LogUnit will capture all user interactions with the IME, including the "meta-interactions"
- * of using the Research button to control the logging (e.g. by starting and stopping recording
- * of a test case). Because meta-interactions should not be part of the normal log, calling
- * this method will set a field in the LogStatements of the motion events to indiciate that
- * they should be disregarded.
- *
- * This implementation assumes that the data recorded by the meta-interaction takes the
- * form of all events following the first MotionEvent.ACTION_DOWN before the first long-press
- * before the last onCodeEvent containing a code matching {@code LogStatement.VALUE_RESEARCH}.
- *
- * @returns true if data was removed
- */
- public boolean removeResearchButtonInvocation() {
- // This method is designed to be idempotent.
-
- // First, find last invocation of "research" key
- final int indexOfLastResearchKey = findLastIndexContainingKeyValue(
- LogStatement.TYPE_POINTER_TRACKER_CALL_LISTENER_ON_CODE_INPUT,
- LogStatement.KEY_CODE, LogStatement.VALUE_RESEARCH);
- if (indexOfLastResearchKey < 0) {
- // Could not find invocation of "research" key. Leave log as is.
- if (DEBUG) {
- Log.d(TAG, "Could not find research key");
- }
- return false;
- }
-
- // Look for the long press that started the invocation of the research key code input.
- final int indexOfLastLongPressBeforeResearchKey =
- findLastIndexBefore(LogStatement.TYPE_MAIN_KEYBOARD_VIEW_ON_LONG_PRESS,
- indexOfLastResearchKey);
-
- // Look for DOWN event preceding the long press
- final int indexOfLastDownEventBeforeLongPress =
- findLastIndexContainingKeyValueBefore(LogStatement.TYPE_MOTION_EVENT,
- LogStatement.ACTION, LogStatement.VALUE_DOWN,
- indexOfLastLongPressBeforeResearchKey);
-
- // Flag all LatinKeyboardViewProcessMotionEvents from the DOWN event to the research key as
- // logging-related
- final int startingIndex = indexOfLastDownEventBeforeLongPress == -1 ? 0
- : indexOfLastDownEventBeforeLongPress;
- for (int index = startingIndex; index < indexOfLastResearchKey; index++) {
- final LogStatement logStatement = mLogStatementList.get(index);
- final String type = logStatement.getType();
- final Object[] values = mValuesList.get(index);
- if (type.equals(LogStatement.TYPE_MOTION_EVENT)) {
- logStatement.setValue(LogStatement.KEY_IS_LOGGING_RELATED, values, true);
- }
- }
- return true;
- }
-
- /**
- * Find the index of the last LogStatement before {@code startingIndex} of type {@code type}.
- *
- * @param queryType a String that must be {@code String.equals()} to the LogStatement type
- * @param startingIndex the index to start the backward search from. Must be less than the
- * length of mLogStatementList, or an IndexOutOfBoundsException is thrown. Can be negative,
- * in which case -1 is returned.
- *
- * @return The index of the last LogStatement, -1 if none exists.
- */
- private int findLastIndexBefore(final String queryType, final int startingIndex) {
- return findLastIndexContainingKeyValueBefore(queryType, null, null, startingIndex);
- }
-
- /**
- * Find the index of the last LogStatement before {@code startingIndex} of type {@code type}
- * containing the given key-value pair.
- *
- * @param queryType a String that must be {@code String.equals()} to the LogStatement type
- * @param queryKey a String that must be {@code String.equals()} to a key in the LogStatement
- * @param queryValue an Object that must be {@code String.equals()} to the key's corresponding
- * value
- *
- * @return The index of the last LogStatement, -1 if none exists.
- */
- private int findLastIndexContainingKeyValue(final String queryType, final String queryKey,
- final Object queryValue) {
- return findLastIndexContainingKeyValueBefore(queryType, queryKey, queryValue,
- mLogStatementList.size() - 1);
- }
-
- /**
- * Find the index of the last LogStatement before {@code startingIndex} of type {@code type}
- * containing the given key-value pair.
- *
- * @param queryType a String that must be {@code String.equals()} to the LogStatement type
- * @param queryKey a String that must be {@code String.equals()} to a key in the LogStatement
- * @param queryValue an Object that must be {@code String.equals()} to the key's corresponding
- * value
- * @param startingIndex the index to start the backward search from. Must be less than the
- * length of mLogStatementList, or an IndexOutOfBoundsException is thrown. Can be negative,
- * in which case -1 is returned.
- *
- * @return The index of the last LogStatement, -1 if none exists.
- */
- private int findLastIndexContainingKeyValueBefore(final String queryType, final String queryKey,
- final Object queryValue, final int startingIndex) {
- if (startingIndex < 0) {
- return -1;
- }
- for (int index = startingIndex; index >= 0; index--) {
- final LogStatement logStatement = mLogStatementList.get(index);
- final String type = logStatement.getType();
- if (type.equals(queryType) && (queryKey == null
- || logStatement.containsKeyValuePair(queryKey, queryValue,
- mValuesList.get(index)))) {
- return index;
- }
- }
- return -1;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/LoggingUtils.java b/java/src/com/android/inputmethod/research/LoggingUtils.java
deleted file mode 100644
index 1261d6780..000000000
--- a/java/src/com/android/inputmethod/research/LoggingUtils.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.view.MotionEvent;
-
-/* package */ class LoggingUtils {
- private LoggingUtils() {
- // This utility class is not publicly instantiable.
- }
-
- /* package */ static String getMotionEventActionTypeString(final int actionType) {
- switch (actionType) {
- case MotionEvent.ACTION_CANCEL: return "CANCEL";
- case MotionEvent.ACTION_UP: return "UP";
- case MotionEvent.ACTION_DOWN: return "DOWN";
- case MotionEvent.ACTION_POINTER_UP: return "POINTER_UP";
- case MotionEvent.ACTION_POINTER_DOWN: return "POINTER_DOWN";
- case MotionEvent.ACTION_MOVE: return "MOVE";
- case MotionEvent.ACTION_OUTSIDE: return "OUTSIDE";
- default: return "ACTION_" + actionType;
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java
deleted file mode 100644
index ffdb43c15..000000000
--- a/java/src/com/android/inputmethod/research/MainLogBuffer.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.util.Log;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-
-/**
- * MainLogBuffer is a FixedLogBuffer that tracks the state of LogUnits to make privacy guarantees.
- *
- * There are three forms of privacy protection: 1) only words in the main dictionary are allowed to
- * be logged in enough detail to determine their contents, 2) only a subset of words are logged
- * in detail, such as 10%, and 3) no numbers are logged.
- *
- * This class maintains a list of LogUnits, each corresponding to a word. As the user completes
- * words, they are added here. But if the user backs up over their current word to edit a word
- * entered earlier, then it is pulled out of this LogBuffer, changes are then added to the end of
- * the LogUnit, and it is pushed back in here when the user is done. Because words may be pulled
- * back out even after they are pushed in, we must not publish the contents of this LogBuffer too
- * quickly. However, we cannot let the contents pile up either, or it will limit the editing that
- * a user can perform.
- *
- * To balance these requirements (keep history so user can edit, flush history so it does not pile
- * up), the LogBuffer is considered "complete" when the user has entered enough words to form an
- * n-gram, followed by enough additional non-detailed words (that are in the 90%, as per above).
- * Once complete, the n-gram may be published to flash storage (via the ResearchLog class).
- * However, the additional non-detailed words are retained, in case the user backspaces to edit
- * them. The MainLogBuffer then continues to add words, publishing individual non-detailed words
- * as new words arrive. After enough non-detailed words have been pushed out to account for the
- * 90% between words, the words at the front of the LogBuffer can be published as an n-gram again.
- *
- * If the words that would form the valid n-gram are not in the dictionary, then words are pushed
- * through the LogBuffer one at a time until an n-gram is found that is entirely composed of
- * dictionary words.
- *
- * If the user closes a session, then the entire LogBuffer is flushed, publishing any embedded
- * n-gram containing dictionary words.
- */
-public abstract class MainLogBuffer extends FixedLogBuffer {
- private static final String TAG = MainLogBuffer.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
-
- // Keep consistent with switch statement in Statistics.recordPublishabilityResultCode()
- public static final int PUBLISHABILITY_PUBLISHABLE = 0;
- public static final int PUBLISHABILITY_UNPUBLISHABLE_STOPPING = 1;
- public static final int PUBLISHABILITY_UNPUBLISHABLE_INCORRECT_WORD_COUNT = 2;
- public static final int PUBLISHABILITY_UNPUBLISHABLE_SAMPLED_TOO_RECENTLY = 3;
- public static final int PUBLISHABILITY_UNPUBLISHABLE_DICTIONARY_UNAVAILABLE = 4;
- public static final int PUBLISHABILITY_UNPUBLISHABLE_MAY_CONTAIN_DIGIT = 5;
- public static final int PUBLISHABILITY_UNPUBLISHABLE_NOT_IN_DICTIONARY = 6;
-
- // The size of the n-grams logged. E.g. N_GRAM_SIZE = 2 means to sample bigrams.
- public static final int N_GRAM_SIZE = 2;
-
- private final DictionaryFacilitatorForSuggest mDictionaryFacilitator;
- @UsedForTesting
- private Dictionary mDictionaryForTesting;
- private boolean mIsStopping = false;
-
- /* package for test */ int mNumWordsBetweenNGrams;
-
- // Counter for words left to suppress before an n-gram can be sampled. Reset to mMinWordPeriod
- // after a sample is taken.
- /* package for test */ int mNumWordsUntilSafeToSample;
-
- public MainLogBuffer(final int wordsBetweenSamples, final int numInitialWordsToIgnore,
- final DictionaryFacilitatorForSuggest dictionaryFacilitator) {
- super(N_GRAM_SIZE + wordsBetweenSamples);
- mNumWordsBetweenNGrams = wordsBetweenSamples;
- mNumWordsUntilSafeToSample = DEBUG ? 0 : numInitialWordsToIgnore;
- mDictionaryFacilitator = dictionaryFacilitator;
- }
-
- @UsedForTesting
- /* package for test */ void setDictionaryForTesting(final Dictionary dictionary) {
- mDictionaryForTesting = dictionary;
- }
-
- private boolean isValidDictWord(final String word) {
- if (mDictionaryForTesting != null) {
- return mDictionaryForTesting.isValidWord(word);
- }
- if (mDictionaryFacilitator != null) {
- return mDictionaryFacilitator.isValidMainDictWord(word);
- }
- return false;
- }
-
- public void setIsStopping() {
- mIsStopping = true;
- }
-
- /**
- * Determines whether the string determined by a series of LogUnits will not violate user
- * privacy if published.
- *
- * @param logUnits a LogUnit list to check for publishability
- * @param nGramSize the smallest n-gram acceptable to be published. if
- * {@link ResearchLogger#IS_LOGGING_EVERYTHING} is true, then publish if there are more than
- * {@code minNGramSize} words in the logUnits, otherwise wait. if {@link
- * ResearchLogger#IS_LOGGING_EVERYTHING} is false, then ensure that there are exactly nGramSize
- * words in the LogUnits.
- *
- * @return one of the {@code PUBLISHABILITY_*} result codes defined in this class.
- */
- private int getPublishabilityResultCode(final ArrayList<LogUnit> logUnits,
- final int nGramSize) {
- // Bypass privacy checks when debugging.
- if (ResearchLogger.IS_LOGGING_EVERYTHING) {
- if (mIsStopping) {
- return PUBLISHABILITY_UNPUBLISHABLE_STOPPING;
- }
- // Only check that it is the right length. If not, wait for later words to make
- // complete n-grams.
- int numWordsInLogUnitList = 0;
- final int length = logUnits.size();
- for (int i = 0; i < length; i++) {
- final LogUnit logUnit = logUnits.get(i);
- numWordsInLogUnitList += logUnit.getNumWords();
- }
- if (numWordsInLogUnitList >= nGramSize) {
- return PUBLISHABILITY_PUBLISHABLE;
- } else {
- return PUBLISHABILITY_UNPUBLISHABLE_INCORRECT_WORD_COUNT;
- }
- }
-
- // Check that we are not sampling too frequently. Having sampled recently might disclose
- // too much of the user's intended meaning.
- if (mNumWordsUntilSafeToSample > 0) {
- return PUBLISHABILITY_UNPUBLISHABLE_SAMPLED_TOO_RECENTLY;
- }
- // Reload the dictionary in case it has changed (e.g., because the user has changed
- // languages).
- if ((mDictionaryFacilitator == null
- || !mDictionaryFacilitator.hasInitializedMainDictionary())
- && mDictionaryForTesting == null) {
- // Main dictionary is unavailable. Since we cannot check it, we cannot tell if a
- // word is out-of-vocabulary or not. Therefore, we must judge the entire buffer
- // contents to potentially pose a privacy risk.
- return PUBLISHABILITY_UNPUBLISHABLE_DICTIONARY_UNAVAILABLE;
- }
-
- // Check each word in the buffer. If any word poses a privacy threat, we cannot upload
- // the complete buffer contents in detail.
- int numWordsInLogUnitList = 0;
- for (final LogUnit logUnit : logUnits) {
- if (!logUnit.hasOneOrMoreWords()) {
- // Digits outside words are a privacy threat.
- if (logUnit.mayContainDigit()) {
- return PUBLISHABILITY_UNPUBLISHABLE_MAY_CONTAIN_DIGIT;
- }
- } else {
- numWordsInLogUnitList += logUnit.getNumWords();
- final String[] words = logUnit.getWordsAsStringArray();
- for (final String word : words) {
- // Words not in the dictionary are a privacy threat.
- if (ResearchLogger.hasLetters(word) && !isValidDictWord(word)) {
- if (DEBUG) {
- Log.d(TAG, "\"" + word + "\" NOT SAFE!: hasLetters: "
- + ResearchLogger.hasLetters(word)
- + ", isValid: " + isValidDictWord(word));
- }
- return PUBLISHABILITY_UNPUBLISHABLE_NOT_IN_DICTIONARY;
- }
- }
- }
- }
-
- // Finally, only return true if the ngram is the right size.
- if (numWordsInLogUnitList == nGramSize) {
- return PUBLISHABILITY_PUBLISHABLE;
- } else {
- return PUBLISHABILITY_UNPUBLISHABLE_INCORRECT_WORD_COUNT;
- }
- }
-
- public void shiftAndPublishAll() throws IOException {
- final LinkedList<LogUnit> logUnits = getLogUnits();
- while (!logUnits.isEmpty()) {
- publishLogUnitsAtFrontOfBuffer();
- }
- }
-
- @Override
- protected final void onBufferFull() {
- try {
- publishLogUnitsAtFrontOfBuffer();
- } catch (final IOException e) {
- if (DEBUG) {
- Log.w(TAG, "IOException when publishing front of LogBuffer", e);
- }
- }
- }
-
- /**
- * If there is a safe n-gram at the front of this log buffer, publish it with all details, and
- * remove the LogUnits that constitute it.
- *
- * An n-gram might not be "safe" if it violates privacy controls. E.g., it might contain
- * numbers, an out-of-vocabulary word, or another n-gram may have been published recently. If
- * there is no safe n-gram, then the LogUnits up through the first word-containing LogUnit are
- * published, but without disclosing any privacy-related details, such as the word the LogUnit
- * generated, motion data, etc.
- *
- * Note that a LogUnit can hold more than one word if the user types without explicit spaces.
- * In this case, the words may be grouped together in such a way that pulling an n-gram off the
- * front would require splitting a LogUnit. Splitting a LogUnit is not possible, so this case
- * is treated just as the unsafe n-gram case. This may cause n-grams to be sampled at slightly
- * less than the target frequency.
- */
- protected final void publishLogUnitsAtFrontOfBuffer() throws IOException {
- // TODO: Refactor this method to require fewer passes through the LogUnits. Should really
- // require only one pass.
- ArrayList<LogUnit> logUnits = peekAtFirstNWords(N_GRAM_SIZE);
- final int publishabilityResultCode = getPublishabilityResultCode(logUnits, N_GRAM_SIZE);
- ResearchLogger.recordPublishabilityResultCode(publishabilityResultCode);
- if (publishabilityResultCode == MainLogBuffer.PUBLISHABILITY_PUBLISHABLE) {
- // Good n-gram at the front of the buffer. Publish it, disclosing details.
- publish(logUnits, true /* canIncludePrivateData */);
- shiftOutWords(N_GRAM_SIZE);
- mNumWordsUntilSafeToSample = mNumWordsBetweenNGrams;
- return;
- }
- // No good n-gram at front, and buffer is full. Shift out up through the first logUnit
- // with associated words (or if there is none, all the existing logUnits).
- logUnits.clear();
- LogUnit logUnit = shiftOut();
- while (logUnit != null) {
- logUnits.add(logUnit);
- final int numWords = logUnit.getNumWords();
- if (numWords > 0) {
- mNumWordsUntilSafeToSample = Math.max(0, mNumWordsUntilSafeToSample - numWords);
- break;
- }
- logUnit = shiftOut();
- }
- publish(logUnits, false /* canIncludePrivateData */);
- }
-
- /**
- * Called when a list of logUnits should be published.
- *
- * It is the subclass's responsibility to implement the publication.
- *
- * @param logUnits The list of logUnits to be published.
- * @param canIncludePrivateData Whether the private data in the logUnits can be included in
- * publication.
- *
- * @throws IOException if publication to the log file is not possible
- */
- protected abstract void publish(final ArrayList<LogUnit> logUnits,
- final boolean canIncludePrivateData) throws IOException;
-
- @Override
- protected int shiftOutWords(final int numWords) {
- final int numWordsShiftedOut = super.shiftOutWords(numWords);
- mNumWordsUntilSafeToSample = Math.max(0, mNumWordsUntilSafeToSample - numWordsShiftedOut);
- if (DEBUG) {
- Log.d(TAG, "wordsUntilSafeToSample now at " + mNumWordsUntilSafeToSample);
- }
- return numWordsShiftedOut;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/MotionEventReader.java b/java/src/com/android/inputmethod/research/MotionEventReader.java
deleted file mode 100644
index 3388645b7..000000000
--- a/java/src/com/android/inputmethod/research/MotionEventReader.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.util.JsonReader;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-
-public class MotionEventReader {
- private static final String TAG = MotionEventReader.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- // Assumes that MotionEvent.ACTION_MASK does not have all bits set.`
- private static final int UNINITIALIZED_ACTION = ~MotionEvent.ACTION_MASK;
- // No legitimate int is negative
- private static final int UNINITIALIZED_INT = -1;
- // No legitimate long is negative
- private static final long UNINITIALIZED_LONG = -1L;
- // No legitimate float is negative
- private static final float UNINITIALIZED_FLOAT = -1.0f;
-
- public ReplayData readMotionEventData(final File file) {
- final ReplayData replayData = new ReplayData();
- try {
- // Read file
- final JsonReader jsonReader = new JsonReader(new BufferedReader(new InputStreamReader(
- new FileInputStream(file))));
- jsonReader.beginArray();
- while (jsonReader.hasNext()) {
- readLogStatement(jsonReader, replayData);
- }
- jsonReader.endArray();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return replayData;
- }
-
- @UsedForTesting
- static class ReplayData {
- final ArrayList<Integer> mActions = new ArrayList<Integer>();
- final ArrayList<PointerProperties[]> mPointerPropertiesArrays
- = new ArrayList<PointerProperties[]>();
- final ArrayList<PointerCoords[]> mPointerCoordsArrays = new ArrayList<PointerCoords[]>();
- final ArrayList<Long> mTimes = new ArrayList<Long>();
- }
-
- /**
- * Read motion data from a logStatement and store it in {@code replayData}.
- *
- * Two kinds of logStatements can be read. In the first variant, the MotionEvent data is
- * represented as attributes at the top level like so:
- *
- * <pre>
- * {
- * "_ct": 1359590400000,
- * "_ut": 4381933,
- * "_ty": "MotionEvent",
- * "action": "UP",
- * "isLoggingRelated": false,
- * "x": 100,
- * "y": 200
- * }
- * </pre>
- *
- * In the second variant, there is a separate attribute for the MotionEvent that includes
- * historical data if present:
- *
- * <pre>
- * {
- * "_ct": 135959040000,
- * "_ut": 4382702,
- * "_ty": "MotionEvent",
- * "action": "MOVE",
- * "isLoggingRelated": false,
- * "motionEvent": {
- * "pointerIds": [
- * 0
- * ],
- * "xyt": [
- * {
- * "t": 4382551,
- * "d": [
- * {
- * "x": 141.25,
- * "y": 151.8485107421875,
- * "toma": 101.82337188720703,
- * "tomi": 101.82337188720703,
- * "o": 0.0
- * }
- * ]
- * },
- * {
- * "t": 4382559,
- * "d": [
- * {
- * "x": 140.7266082763672,
- * "y": 151.8485107421875,
- * "toma": 101.82337188720703,
- * "tomi": 101.82337188720703,
- * "o": 0.0
- * }
- * ]
- * }
- * ]
- * }
- * },
- * </pre>
- */
- @UsedForTesting
- /* package for test */ void readLogStatement(final JsonReader jsonReader,
- final ReplayData replayData) throws IOException {
- String logStatementType = null;
- int actionType = UNINITIALIZED_ACTION;
- int x = UNINITIALIZED_INT;
- int y = UNINITIALIZED_INT;
- long time = UNINITIALIZED_LONG;
- boolean isLoggingRelated = false;
-
- jsonReader.beginObject();
- while (jsonReader.hasNext()) {
- final String key = jsonReader.nextName();
- if (key.equals("_ty")) {
- logStatementType = jsonReader.nextString();
- } else if (key.equals("_ut")) {
- time = jsonReader.nextLong();
- } else if (key.equals("x")) {
- x = jsonReader.nextInt();
- } else if (key.equals("y")) {
- y = jsonReader.nextInt();
- } else if (key.equals("action")) {
- final String s = jsonReader.nextString();
- if (s.equals("UP")) {
- actionType = MotionEvent.ACTION_UP;
- } else if (s.equals("DOWN")) {
- actionType = MotionEvent.ACTION_DOWN;
- } else if (s.equals("MOVE")) {
- actionType = MotionEvent.ACTION_MOVE;
- }
- } else if (key.equals("loggingRelated")) {
- isLoggingRelated = jsonReader.nextBoolean();
- } else if (logStatementType != null && logStatementType.equals("MotionEvent")
- && key.equals("motionEvent")) {
- if (actionType == UNINITIALIZED_ACTION) {
- Log.e(TAG, "no actionType assigned in MotionEvent json");
- }
- // Second variant of LogStatement.
- if (isLoggingRelated) {
- jsonReader.skipValue();
- } else {
- readEmbeddedMotionEvent(jsonReader, replayData, actionType);
- }
- } else {
- if (DEBUG) {
- Log.w(TAG, "Unknown JSON key in LogStatement: " + key);
- }
- jsonReader.skipValue();
- }
- }
- jsonReader.endObject();
-
- if (logStatementType != null && time != UNINITIALIZED_LONG && x != UNINITIALIZED_INT
- && y != UNINITIALIZED_INT && actionType != UNINITIALIZED_ACTION
- && logStatementType.equals("MotionEvent") && !isLoggingRelated) {
- // First variant of LogStatement.
- final PointerProperties pointerProperties = new PointerProperties();
- pointerProperties.id = 0;
- pointerProperties.toolType = MotionEvent.TOOL_TYPE_UNKNOWN;
- final PointerProperties[] pointerPropertiesArray = {
- pointerProperties
- };
- final PointerCoords pointerCoords = new PointerCoords();
- pointerCoords.x = x;
- pointerCoords.y = y;
- pointerCoords.pressure = 1.0f;
- pointerCoords.size = 1.0f;
- final PointerCoords[] pointerCoordsArray = {
- pointerCoords
- };
- addMotionEventData(replayData, actionType, time, pointerPropertiesArray,
- pointerCoordsArray);
- }
- }
-
- private void readEmbeddedMotionEvent(final JsonReader jsonReader, final ReplayData replayData,
- final int actionType) throws IOException {
- jsonReader.beginObject();
- PointerProperties[] pointerPropertiesArray = null;
- while (jsonReader.hasNext()) { // pointerIds/xyt
- final String name = jsonReader.nextName();
- if (name.equals("pointerIds")) {
- pointerPropertiesArray = readPointerProperties(jsonReader);
- } else if (name.equals("xyt")) {
- readPointerData(jsonReader, replayData, actionType, pointerPropertiesArray);
- }
- }
- jsonReader.endObject();
- }
-
- private PointerProperties[] readPointerProperties(final JsonReader jsonReader)
- throws IOException {
- final ArrayList<PointerProperties> pointerPropertiesArrayList =
- new ArrayList<PointerProperties>();
- jsonReader.beginArray();
- while (jsonReader.hasNext()) {
- final PointerProperties pointerProperties = new PointerProperties();
- pointerProperties.id = jsonReader.nextInt();
- pointerProperties.toolType = MotionEvent.TOOL_TYPE_UNKNOWN;
- pointerPropertiesArrayList.add(pointerProperties);
- }
- jsonReader.endArray();
- return pointerPropertiesArrayList.toArray(
- new PointerProperties[pointerPropertiesArrayList.size()]);
- }
-
- private void readPointerData(final JsonReader jsonReader, final ReplayData replayData,
- final int actionType, final PointerProperties[] pointerPropertiesArray)
- throws IOException {
- if (pointerPropertiesArray == null) {
- Log.e(TAG, "PointerIDs must be given before xyt data in json for MotionEvent");
- jsonReader.skipValue();
- return;
- }
- long time = UNINITIALIZED_LONG;
- jsonReader.beginArray();
- while (jsonReader.hasNext()) { // Array of historical data
- jsonReader.beginObject();
- final ArrayList<PointerCoords> pointerCoordsArrayList = new ArrayList<PointerCoords>();
- while (jsonReader.hasNext()) { // Time/data object
- final String name = jsonReader.nextName();
- if (name.equals("t")) {
- time = jsonReader.nextLong();
- } else if (name.equals("d")) {
- jsonReader.beginArray();
- while (jsonReader.hasNext()) { // array of data per pointer
- final PointerCoords pointerCoords = readPointerCoords(jsonReader);
- if (pointerCoords != null) {
- pointerCoordsArrayList.add(pointerCoords);
- }
- }
- jsonReader.endArray();
- } else {
- jsonReader.skipValue();
- }
- }
- jsonReader.endObject();
- // Data was recorded as historical events, but must be split apart into
- // separate MotionEvents for replaying
- if (time != UNINITIALIZED_LONG) {
- addMotionEventData(replayData, actionType, time, pointerPropertiesArray,
- pointerCoordsArrayList.toArray(
- new PointerCoords[pointerCoordsArrayList.size()]));
- } else {
- Log.e(TAG, "Time not assigned in json for MotionEvent");
- }
- }
- jsonReader.endArray();
- }
-
- private PointerCoords readPointerCoords(final JsonReader jsonReader) throws IOException {
- jsonReader.beginObject();
- float x = UNINITIALIZED_FLOAT;
- float y = UNINITIALIZED_FLOAT;
- while (jsonReader.hasNext()) { // x,y
- final String name = jsonReader.nextName();
- if (name.equals("x")) {
- x = (float) jsonReader.nextDouble();
- } else if (name.equals("y")) {
- y = (float) jsonReader.nextDouble();
- } else {
- jsonReader.skipValue();
- }
- }
- jsonReader.endObject();
-
- if (Float.compare(x, UNINITIALIZED_FLOAT) == 0
- || Float.compare(y, UNINITIALIZED_FLOAT) == 0) {
- Log.w(TAG, "missing x or y value in MotionEvent json");
- return null;
- }
- final PointerCoords pointerCoords = new PointerCoords();
- pointerCoords.x = x;
- pointerCoords.y = y;
- pointerCoords.pressure = 1.0f;
- pointerCoords.size = 1.0f;
- return pointerCoords;
- }
-
- private void addMotionEventData(final ReplayData replayData, final int actionType,
- final long time, final PointerProperties[] pointerProperties,
- final PointerCoords[] pointerCoords) {
- replayData.mActions.add(actionType);
- replayData.mTimes.add(time);
- replayData.mPointerPropertiesArrays.add(pointerProperties);
- replayData.mPointerCoordsArrays.add(pointerCoords);
- }
-}
diff --git a/java/src/com/android/inputmethod/research/Replayer.java b/java/src/com/android/inputmethod/research/Replayer.java
deleted file mode 100644
index 903875f3c..000000000
--- a/java/src/com/android/inputmethod/research/Replayer.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.research.MotionEventReader.ReplayData;
-
-/**
- * Replays a sequence of motion events in realtime on the screen.
- *
- * Useful for user inspection of logged data.
- */
-public class Replayer {
- private static final String TAG = Replayer.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- private static final long START_TIME_DELAY_MS = 500;
-
- private boolean mIsReplaying = false;
- private KeyboardSwitcher mKeyboardSwitcher;
-
- private Replayer() {
- }
-
- private static final Replayer sInstance = new Replayer();
- public static Replayer getInstance() {
- return sInstance;
- }
-
- public void setKeyboardSwitcher(final KeyboardSwitcher keyboardSwitcher) {
- mKeyboardSwitcher = keyboardSwitcher;
- }
-
- private static final int MSG_MOTION_EVENT = 0;
- private static final int MSG_DONE = 1;
- private static final int COMPLETION_TIME_MS = 500;
-
- // TODO: Support historical events and multi-touch.
- public void replay(final ReplayData replayData, final Runnable callback) {
- if (mIsReplaying) {
- return;
- }
- mIsReplaying = true;
- final int numActions = replayData.mActions.size();
- if (DEBUG) {
- Log.d(TAG, "replaying " + numActions + " actions");
- }
- if (numActions == 0) {
- mIsReplaying = false;
- return;
- }
- final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
-
- // The reference time relative to the times stored in events.
- final long origStartTime = replayData.mTimes.get(0);
- // The reference time relative to which events are replayed in the present.
- final long currentStartTime = SystemClock.uptimeMillis() + START_TIME_DELAY_MS;
- // The adjustment needed to translate times from the original recorded time to the current
- // time.
- final long timeAdjustment = currentStartTime - origStartTime;
- final Handler handler = new Handler(Looper.getMainLooper()) {
- // Track the time of the most recent DOWN event, to be passed as a parameter when
- // constructing a MotionEvent. It's initialized here to the origStartTime, but this is
- // only a precaution. The value should be overwritten by the first ACTION_DOWN event
- // before the first use of the variable. Note that this may cause the first few events
- // to have incorrect {@code downTime}s.
- private long mOrigDownTime = origStartTime;
-
- @Override
- public void handleMessage(final Message msg) {
- switch (msg.what) {
- case MSG_MOTION_EVENT:
- final int index = msg.arg1;
- final int action = replayData.mActions.get(index);
- final PointerProperties[] pointerPropertiesArray =
- replayData.mPointerPropertiesArrays.get(index);
- final PointerCoords[] pointerCoordsArray =
- replayData.mPointerCoordsArrays.get(index);
- final long origTime = replayData.mTimes.get(index);
- if (action == MotionEvent.ACTION_DOWN) {
- mOrigDownTime = origTime;
- }
-
- final MotionEvent me = MotionEvent.obtain(mOrigDownTime + timeAdjustment,
- origTime + timeAdjustment, action,
- pointerPropertiesArray.length, pointerPropertiesArray,
- pointerCoordsArray, 0, 0, 1.0f, 1.0f, 0, 0, 0, 0);
- mainKeyboardView.processMotionEvent(me);
- me.recycle();
- break;
- case MSG_DONE:
- mIsReplaying = false;
- ResearchLogger.getInstance().requestIndicatorRedraw();
- break;
- }
- }
- };
-
- handler.post(new Runnable() {
- @Override
- public void run() {
- ResearchLogger.getInstance().requestIndicatorRedraw();
- }
- });
- for (int i = 0; i < numActions; i++) {
- final Message msg = Message.obtain(handler, MSG_MOTION_EVENT, i, 0);
- final long msgTime = replayData.mTimes.get(i) + timeAdjustment;
- handler.sendMessageAtTime(msg, msgTime);
- if (DEBUG) {
- Log.d(TAG, "queuing event at " + msgTime);
- }
- }
-
- final long presentDoneTime = replayData.mTimes.get(numActions - 1) + timeAdjustment
- + COMPLETION_TIME_MS;
- handler.sendMessageAtTime(Message.obtain(handler, MSG_DONE), presentDoneTime);
- if (callback != null) {
- handler.postAtTime(callback, presentDoneTime + 1);
- }
- }
-
- public boolean isReplaying() {
- return mIsReplaying;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/ReplayerService.java b/java/src/com/android/inputmethod/research/ReplayerService.java
deleted file mode 100644
index 88d9033cf..000000000
--- a/java/src/com/android/inputmethod/research/ReplayerService.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.util.Log;
-
-import com.android.inputmethod.research.MotionEventReader.ReplayData;
-
-import java.io.File;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Provide a mechanism to invoke the replayer from outside.
- *
- * In particular, makes access from a host possible through {@code adb am startservice}.
- */
-public class ReplayerService extends IntentService {
- private static final String TAG = ReplayerService.class.getSimpleName();
- private static final String EXTRA_FILENAME = "com.android.inputmethod.research.extra.FILENAME";
- private static final long MAX_REPLAY_TIME = TimeUnit.SECONDS.toMillis(60);
-
- public ReplayerService() {
- super(ReplayerService.class.getSimpleName());
- }
-
- @Override
- protected void onHandleIntent(final Intent intent) {
- final String filename = intent.getStringExtra(EXTRA_FILENAME);
- if (filename == null) return;
-
- final ReplayData replayData = new MotionEventReader().readMotionEventData(
- new File(filename));
- synchronized (this) {
- Replayer.getInstance().replay(replayData, new Runnable() {
- @Override
- public void run() {
- synchronized (ReplayerService.this) {
- ReplayerService.this.notify();
- }
- }
- });
- try {
- wait(MAX_REPLAY_TIME);
- } catch (InterruptedException e) {
- Log.e(TAG, "Timeout while replaying.", e);
- }
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/research/ResearchLog.java b/java/src/com/android/inputmethod/research/ResearchLog.java
deleted file mode 100644
index 46e620ae5..000000000
--- a/java/src/com/android/inputmethod/research/ResearchLog.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.Context;
-import android.util.JsonWriter;
-import android.util.Log;
-
-import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.concurrent.Callable;
-import java.util.concurrent.Executors;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Logs the use of the LatinIME keyboard.
- *
- * This class logs operations on the IME keyboard, including what the user has typed. Data is
- * written to a {@link JsonWriter}, which will write to a local file.
- *
- * The JsonWriter is created on-demand by calling {@link #getInitializedJsonWriterLocked}.
- *
- * This class uses an executor to perform file-writing operations on a separate thread. It also
- * tries to avoid creating unnecessary files if there is nothing to write. It also handles
- * flushing, making sure it happens, but not too frequently.
- *
- * This functionality is off by default. See
- * {@link ProductionFlag#USES_DEVELOPMENT_ONLY_DIAGNOSTICS}.
- */
-public class ResearchLog {
- // TODO: Automatically initialize the JsonWriter rather than requiring the caller to manage it.
- private static final String TAG = ResearchLog.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- private static final long FLUSH_DELAY_IN_MS = TimeUnit.SECONDS.toMillis(5);
-
- /* package */ final ScheduledExecutorService mExecutor;
- /* package */ final File mFile;
- private final Context mContext;
-
- // Earlier implementations used a dummy JsonWriter that just swallowed what it was given, but
- // this was tricky to do well, because JsonWriter throws an exception if it is passed more than
- // one top-level object.
- private JsonWriter mJsonWriter = null;
-
- // true if at least one byte of data has been written out to the log file. This must be
- // remembered because JsonWriter requires that calls matching calls to beginObject and
- // endObject, as well as beginArray and endArray, and the file is opened lazily, only when
- // it is certain that data will be written. Alternatively, the matching call exceptions
- // could be caught, but this might suppress other errors.
- private boolean mHasWrittenData = false;
-
- public ResearchLog(final File outputFile, final Context context) {
- mExecutor = Executors.newSingleThreadScheduledExecutor();
- mFile = outputFile;
- mContext = context;
- }
-
- /**
- * Returns true if this is a FeedbackLog.
- *
- * FeedbackLogs record only the data associated with a Feedback dialog. Instead of normal
- * logging, they contain a LogStatement with the complete feedback string and optionally a
- * recording of the user's supplied demo of the problem.
- */
- public boolean isFeedbackLog() {
- return false;
- }
-
- /**
- * Waits for any publication requests to finish and closes the {@link JsonWriter} used for
- * output.
- *
- * See class comment for details about {@code JsonWriter} construction.
- *
- * @param onClosed run after the close() operation has completed asynchronously
- */
- private synchronized void close(final Runnable onClosed) {
- mExecutor.submit(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- try {
- if (mJsonWriter == null) return null;
- // TODO: This is necessary to avoid an exception. Better would be to not even
- // open the JsonWriter if the file is not even opened unless there is valid data
- // to write.
- if (!mHasWrittenData) {
- mJsonWriter.beginArray();
- }
- mJsonWriter.endArray();
- mHasWrittenData = false;
- mJsonWriter.flush();
- mJsonWriter.close();
- if (DEBUG) {
- Log.d(TAG, "closed " + mFile);
- }
- } catch (final Exception e) {
- Log.d(TAG, "error when closing ResearchLog:", e);
- } finally {
- // Marking the file as read-only signals that this log file is ready to be
- // uploaded.
- if (mFile != null && mFile.exists()) {
- mFile.setWritable(false, false);
- }
- if (onClosed != null) {
- onClosed.run();
- }
- }
- return null;
- }
- });
- removeAnyScheduledFlush();
- mExecutor.shutdown();
- }
-
- /**
- * Block until the research log has shut down and spooled out all output or {@code timeout}
- * occurs.
- *
- * @param timeout time to wait for close in milliseconds
- */
- public void blockingClose(final long timeout) {
- close(null);
- awaitTermination(timeout, TimeUnit.MILLISECONDS);
- }
-
- /**
- * Waits for publication requests to finish, closes the JsonWriter, but then deletes the backing
- * output file.
- *
- * @param onAbort run after the abort() operation has completed asynchronously
- */
- private synchronized void abort(final Runnable onAbort) {
- mExecutor.submit(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- try {
- if (mJsonWriter == null) return null;
- if (mHasWrittenData) {
- // TODO: This is necessary to avoid an exception. Better would be to not
- // even open the JsonWriter if the file is not even opened unless there is
- // valid data to write.
- if (!mHasWrittenData) {
- mJsonWriter.beginArray();
- }
- mJsonWriter.endArray();
- mJsonWriter.close();
- mHasWrittenData = false;
- }
- } finally {
- if (mFile != null) {
- mFile.delete();
- }
- if (onAbort != null) {
- onAbort.run();
- }
- }
- return null;
- }
- });
- removeAnyScheduledFlush();
- mExecutor.shutdown();
- }
-
- /**
- * Block until the research log has aborted or {@code timeout} occurs.
- *
- * @param timeout time to wait for close in milliseconds
- */
- public void blockingAbort(final long timeout) {
- abort(null);
- awaitTermination(timeout, TimeUnit.MILLISECONDS);
- }
-
- @UsedForTesting
- public void awaitTermination(final long delay, final TimeUnit timeUnit) {
- try {
- if (!mExecutor.awaitTermination(delay, timeUnit)) {
- Log.e(TAG, "ResearchLog executor timed out while awaiting terminaion");
- }
- } catch (final InterruptedException e) {
- Log.e(TAG, "ResearchLog executor interrupted while awaiting terminaion", e);
- }
- }
-
- /* package */ synchronized void flush() {
- removeAnyScheduledFlush();
- mExecutor.submit(mFlushCallable);
- }
-
- private final Callable<Object> mFlushCallable = new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- if (mJsonWriter != null) mJsonWriter.flush();
- return null;
- }
- };
-
- private ScheduledFuture<Object> mFlushFuture;
-
- private void removeAnyScheduledFlush() {
- if (mFlushFuture != null) {
- mFlushFuture.cancel(false);
- mFlushFuture = null;
- }
- }
-
- private void scheduleFlush() {
- removeAnyScheduledFlush();
- mFlushFuture = mExecutor.schedule(mFlushCallable, FLUSH_DELAY_IN_MS, TimeUnit.MILLISECONDS);
- }
-
- /**
- * Queues up {@code logUnit} to be published in the background.
- *
- * @param logUnit the {@link LogUnit} to be published
- * @param canIncludePrivateData whether private data in the LogUnit should be included
- */
- public synchronized void publish(final LogUnit logUnit, final boolean canIncludePrivateData) {
- try {
- mExecutor.submit(new Callable<Object>() {
- @Override
- public Object call() throws Exception {
- logUnit.publishTo(ResearchLog.this, canIncludePrivateData);
- scheduleFlush();
- return null;
- }
- });
- } catch (final RejectedExecutionException e) {
- // TODO: Add code to record loss of data, and report.
- if (DEBUG) {
- Log.d(TAG, "ResearchLog.publish() rejecting scheduled execution", e);
- }
- }
- }
-
- /**
- * Return a JsonWriter for this ResearchLog. It is initialized the first time this method is
- * called. The cached value is returned in future calls.
- *
- * @throws IOException if opening the JsonWriter is not possible
- */
- public JsonWriter getInitializedJsonWriterLocked() throws IOException {
- if (mJsonWriter != null) return mJsonWriter;
- if (mFile == null) throw new FileNotFoundException();
- try {
- final JsonWriter jsonWriter = createJsonWriter(mContext, mFile);
- if (jsonWriter == null) throw new IOException("Could not create JsonWriter");
-
- jsonWriter.beginArray();
- mJsonWriter = jsonWriter;
- mHasWrittenData = true;
- return mJsonWriter;
- } catch (final IOException e) {
- if (DEBUG) {
- Log.w(TAG, "Exception when creating JsonWriter", e);
- Log.w(TAG, "Closing JsonWriter");
- }
- if (mJsonWriter != null) mJsonWriter.close();
- mJsonWriter = null;
- throw e;
- }
- }
-
- /**
- * Create the JsonWriter to write the ResearchLog to.
- *
- * This method may be overriden in testing to redirect the output.
- */
- /* package for test */ JsonWriter createJsonWriter(final Context context, final File file)
- throws IOException {
- return new JsonWriter(new BufferedWriter(new OutputStreamWriter(
- context.openFileOutput(file.getName(), Context.MODE_PRIVATE))));
- }
-}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogDirectory.java b/java/src/com/android/inputmethod/research/ResearchLogDirectory.java
deleted file mode 100644
index d156068d6..000000000
--- a/java/src/com/android/inputmethod/research/ResearchLogDirectory.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.Context;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileFilter;
-
-/**
- * Manages log files.
- *
- * This class handles all aspects where and how research log data is stored. This includes
- * generating log filenames in the correct place with the correct names, and cleaning up log files
- * under this directory.
- */
-public class ResearchLogDirectory {
- public static final String TAG = ResearchLogDirectory.class.getSimpleName();
- /* package */ static final String LOG_FILENAME_PREFIX = "researchLog";
- private static final String FILENAME_SUFFIX = ".txt";
- private static final String USER_RECORDING_FILENAME_PREFIX = "recording";
-
- private static final ReadOnlyLogFileFilter sUploadableLogFileFilter =
- new ReadOnlyLogFileFilter();
-
- private final File mFilesDir;
-
- static class ReadOnlyLogFileFilter implements FileFilter {
- @Override
- public boolean accept(final File pathname) {
- return pathname.getName().startsWith(ResearchLogDirectory.LOG_FILENAME_PREFIX)
- && !pathname.canWrite();
- }
- }
-
- /**
- * Creates a new ResearchLogDirectory, creating the storage directory if it does not exist.
- */
- public ResearchLogDirectory(final Context context) {
- mFilesDir = getLoggingDirectory(context);
- if (mFilesDir == null) {
- throw new NullPointerException("No files directory specified");
- }
- if (!mFilesDir.exists()) {
- mFilesDir.mkdirs();
- }
- }
-
- private File getLoggingDirectory(final Context context) {
- // TODO: Switch to using a subdirectory of getFilesDir().
- return context.getFilesDir();
- }
-
- /**
- * Get an array of log files that are ready for uploading.
- *
- * A file is ready for uploading if it is marked as read-only.
- *
- * @return the array of uploadable files
- */
- public File[] getUploadableLogFiles() {
- try {
- return mFilesDir.listFiles(sUploadableLogFileFilter);
- } catch (final SecurityException e) {
- Log.e(TAG, "Could not cleanup log directory, permission denied", e);
- return new File[0];
- }
- }
-
- public void cleanupLogFilesOlderThan(final long time) {
- try {
- for (final File file : mFilesDir.listFiles()) {
- final String filename = file.getName();
- if ((filename.startsWith(LOG_FILENAME_PREFIX)
- || filename.startsWith(USER_RECORDING_FILENAME_PREFIX))
- && (file.lastModified() < time)) {
- file.delete();
- }
- }
- } catch (final SecurityException e) {
- Log.e(TAG, "Could not cleanup log directory, permission denied", e);
- }
- }
-
- public File getLogFilePath(final long time, final long nanoTime) {
- return new File(mFilesDir, getUniqueFilename(LOG_FILENAME_PREFIX, time, nanoTime));
- }
-
- public File getUserRecordingFilePath(final long time, final long nanoTime) {
- return new File(mFilesDir, getUniqueFilename(USER_RECORDING_FILENAME_PREFIX, time,
- nanoTime));
- }
-
- private static String getUniqueFilename(final String prefix, final long time,
- final long nanoTime) {
- return prefix + "-" + time + "-" + nanoTime + FILENAME_SUFFIX;
- }
-}
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
deleted file mode 100644
index d907dd1b0..000000000
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ /dev/null
@@ -1,1885 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Paint.Style;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.SystemClock;
-import android.preference.PreferenceManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.inputmethod.CompletionInfo;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputConnection;
-import android.widget.Toast;
-
-import com.android.inputmethod.keyboard.Key;
-import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.KeyboardView;
-import com.android.inputmethod.keyboard.MainKeyboardView;
-import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest;
-import com.android.inputmethod.latin.LatinIME;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.RichInputConnection;
-import com.android.inputmethod.latin.SuggestedWords;
-import com.android.inputmethod.latin.define.ProductionFlag;
-import com.android.inputmethod.latin.utils.InputTypeUtils;
-import com.android.inputmethod.latin.utils.StringUtils;
-import com.android.inputmethod.latin.utils.TextRange;
-import com.android.inputmethod.research.MotionEventReader.ReplayData;
-import com.android.inputmethod.research.ui.SplashScreen;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-
-// TODO: Add a unit test for every "logging" method (i.e. that is called from the IME and calls
-// enqueueEvent to record a LogStatement).
-/**
- * Logs the use of the LatinIME keyboard.
- *
- * This class logs operations on the IME keyboard, including what the user has typed.
- * Data is stored locally in a file in app-specific storage.
- *
- * This functionality is off by default. See
- * {@link ProductionFlag#USES_DEVELOPMENT_ONLY_DIAGNOSTICS}.
- */
-public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChangeListener,
- SplashScreen.UserConsentListener {
- // TODO: This class has grown quite large and combines several concerns that should be
- // separated. The following refactorings will be applied as soon as possible after adding
- // support for replaying historical events, fixing some replay bugs, adding some ui constraints
- // on the feedback dialog, and adding the survey dialog.
- // TODO: Refactor. Move feedback screen code into separate class.
- // TODO: Refactor. Move logging invocations into their own class.
- // TODO: Refactor. Move currentLogUnit management into separate class.
- private static final String TAG = ResearchLogger.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- private static final boolean DEBUG_REPLAY_AFTER_FEEDBACK = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- // Whether the feedback dialog preserves the editable text across invocations. Should be false
- // for normal research builds so users do not have to delete the same feedback string they
- // entered earlier. Should be true for builds internal to a development team so when the text
- // field holds a channel name, the developer does not have to re-enter it when using the
- // feedback mechanism to generate multiple tests.
- private static final boolean FEEDBACK_DIALOG_SHOULD_PRESERVE_TEXT_FIELD = false;
- /* package */ static boolean sIsLogging = false;
- private static final int OUTPUT_FORMAT_VERSION = 6;
- // Whether all words should be recorded, leaving unsampled word between bigrams. Useful for
- // testing.
- /* package for test */ static final boolean IS_LOGGING_EVERYTHING = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- // The number of words between n-grams to omit from the log.
- private static final int NUMBER_OF_WORDS_BETWEEN_SAMPLES =
- IS_LOGGING_EVERYTHING ? 0 : (DEBUG ? 2 : 18);
-
- // Whether to show an indicator on the screen that logging is on. Currently a very small red
- // dot in the lower right hand corner. Most users should not notice it.
- private static final boolean IS_SHOWING_INDICATOR = true;
- // Change the default indicator to something very visible. Currently two red vertical bars on
- // either side of they keyboard.
- private static final boolean IS_SHOWING_INDICATOR_CLEARLY = false ||
- (IS_LOGGING_EVERYTHING && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG);
- // FEEDBACK_WORD_BUFFER_SIZE should add 1 because it must also hold the feedback LogUnit itself.
- public static final int FEEDBACK_WORD_BUFFER_SIZE = (Integer.MAX_VALUE - 1) + 1;
-
- // The special output text to invoke a research feedback dialog.
- public static final String RESEARCH_KEY_OUTPUT_TEXT = ".research.";
-
- // constants related to specific log points
- private static final int[] WHITESPACE_SEPARATORS =
- StringUtils.toSortedCodePointArray(" \t\n\r");
- private static final int MAX_INPUTVIEW_LENGTH_TO_CAPTURE = 8192; // must be >=1
- private static final String PREF_RESEARCH_SAVED_CHANNEL = "pref_research_saved_channel";
-
- private static final long RESEARCHLOG_CLOSE_TIMEOUT_IN_MS = TimeUnit.SECONDS.toMillis(5);
- private static final long RESEARCHLOG_ABORT_TIMEOUT_IN_MS = TimeUnit.SECONDS.toMillis(5);
- private static final long DURATION_BETWEEN_DIR_CLEANUP_IN_MS = TimeUnit.DAYS.toMillis(1);
- private static final long MAX_LOGFILE_AGE_IN_MS = TimeUnit.DAYS.toMillis(4);
-
- private static final ResearchLogger sInstance = new ResearchLogger();
- private static String sAccountType = null;
- private static String sAllowedAccountDomain = null;
- private ResearchLog mMainResearchLog; // always non-null after init() is called
- // mFeedbackLog records all events for the session, private or not (excepting
- // passwords). It is written to permanent storage only if the user explicitly commands
- // the system to do so.
- // LogUnits are queued in the LogBuffers and published to the ResearchLogs when words are
- // complete.
- /* package for test */ MainLogBuffer mMainLogBuffer; // always non-null after init() is called
- /* package */ ResearchLog mUserRecordingLog;
- /* package */ LogBuffer mUserRecordingLogBuffer;
- private File mUserRecordingFile = null;
-
- private boolean mIsPasswordView = false;
- private SharedPreferences mPrefs;
-
- // digits entered by the user are replaced with this codepoint.
- /* package for test */ static final int DIGIT_REPLACEMENT_CODEPOINT =
- Character.codePointAt("\uE000", 0); // U+E000 is in the "private-use area"
- // U+E001 is in the "private-use area"
- /* package for test */ static final String WORD_REPLACEMENT_STRING = "\uE001";
- protected static final int SUSPEND_DURATION_IN_MINUTES = 1;
-
- // used to check whether words are not unique
- private DictionaryFacilitatorForSuggest mDictionaryFacilitator;
- private MainKeyboardView mMainKeyboardView;
- // TODO: Check whether a superclass can be used instead of LatinIME.
- /* package for test */ LatinIME mLatinIME;
- private final Statistics mStatistics;
- private final MotionEventReader mMotionEventReader = new MotionEventReader();
- private final Replayer mReplayer = Replayer.getInstance();
- private ResearchLogDirectory mResearchLogDirectory;
- private SplashScreen mSplashScreen;
-
- private Intent mUploadNowIntent;
-
- /* package for test */ LogUnit mCurrentLogUnit = new LogUnit();
-
- // Gestured or tapped words may be committed after the gesture of the next word has started.
- // To ensure that the gesture data of the next word is not associated with the previous word,
- // thereby leaking private data, we store the time of the down event that started the second
- // gesture, and when committing the earlier word, split the LogUnit.
- private long mSavedDownEventTime;
- private Bundle mFeedbackDialogBundle = null;
- // Whether the feedback dialog is visible, and the user is typing into it. Normal logging is
- // not performed on text that the user types into the feedback dialog.
- private boolean mInFeedbackDialog = false;
- private Handler mUserRecordingTimeoutHandler;
- private static final long USER_RECORDING_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(30);
-
- // Stores a temporary LogUnit while generating a phantom space. Needed because phantom spaces
- // are issued out-of-order, immediately before the characters generated by other operations that
- // have already outputted LogStatements.
- private LogUnit mPhantomSpaceLogUnit = null;
-
- private ResearchLogger() {
- mStatistics = Statistics.getInstance();
- }
-
- public static ResearchLogger getInstance() {
- return sInstance;
- }
-
- public void init(final LatinIME latinIME, final KeyboardSwitcher keyboardSwitcher) {
- assert latinIME != null;
- mLatinIME = latinIME;
- mPrefs = PreferenceManager.getDefaultSharedPreferences(latinIME);
- mPrefs.registerOnSharedPreferenceChangeListener(this);
-
- // Initialize fields from preferences
- sIsLogging = ResearchSettings.readResearchLoggerEnabledFlag(mPrefs);
-
- // Initialize fields from resources
- final Resources res = latinIME.getResources();
- sAccountType = res.getString(R.string.research_account_type);
- sAllowedAccountDomain = res.getString(R.string.research_allowed_account_domain);
-
- // Initialize directory manager
- mResearchLogDirectory = new ResearchLogDirectory(mLatinIME);
- cleanLogDirectoryIfNeeded(mResearchLogDirectory, System.currentTimeMillis());
-
- // Initialize log buffers
- resetLogBuffers();
-
- // Initialize external services
- mUploadNowIntent = new Intent(mLatinIME, UploaderService.class);
- mUploadNowIntent.putExtra(UploaderService.EXTRA_UPLOAD_UNCONDITIONALLY, true);
- if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
- UploaderService.cancelAndRescheduleUploadingService(mLatinIME,
- true /* needsRescheduling */);
- }
- mReplayer.setKeyboardSwitcher(keyboardSwitcher);
- }
-
- private void resetLogBuffers() {
- mMainResearchLog = new ResearchLog(mResearchLogDirectory.getLogFilePath(
- System.currentTimeMillis(), System.nanoTime()), mLatinIME);
- final int numWordsToIgnore = new Random().nextInt(NUMBER_OF_WORDS_BETWEEN_SAMPLES + 1);
- mMainLogBuffer = new MainLogBuffer(NUMBER_OF_WORDS_BETWEEN_SAMPLES, numWordsToIgnore,
- mDictionaryFacilitator) {
- @Override
- protected void publish(final ArrayList<LogUnit> logUnits,
- boolean canIncludePrivateData) {
- canIncludePrivateData |= IS_LOGGING_EVERYTHING;
- for (final LogUnit logUnit : logUnits) {
- if (DEBUG) {
- final String wordsString = logUnit.getWordsAsString();
- Log.d(TAG, "onPublish: '" + wordsString
- + "', hc: " + logUnit.containsUserDeletions()
- + ", cipd: " + canIncludePrivateData);
- }
- for (final String word : logUnit.getWordsAsStringArray()) {
- final boolean isDictionaryWord = mDictionaryFacilitator != null
- && mDictionaryFacilitator.isValidMainDictWord(word);
- mStatistics.recordWordEntered(
- isDictionaryWord, logUnit.containsUserDeletions());
- }
- }
- publishLogUnits(logUnits, mMainResearchLog, canIncludePrivateData);
- }
- };
- }
-
- private void cleanLogDirectoryIfNeeded(final ResearchLogDirectory researchLogDirectory,
- final long now) {
- final long lastCleanupTime = ResearchSettings.readResearchLastDirCleanupTime(mPrefs);
- if (now - lastCleanupTime < DURATION_BETWEEN_DIR_CLEANUP_IN_MS) return;
- final long oldestAllowedFileTime = now - MAX_LOGFILE_AGE_IN_MS;
- mResearchLogDirectory.cleanupLogFilesOlderThan(oldestAllowedFileTime);
- ResearchSettings.writeResearchLastDirCleanupTime(mPrefs, now);
- }
-
- public void mainKeyboardView_onAttachedToWindow(final MainKeyboardView mainKeyboardView) {
- mMainKeyboardView = mainKeyboardView;
- maybeShowSplashScreen();
- }
-
- public void mainKeyboardView_onDetachedFromWindow() {
- mMainKeyboardView = null;
- }
-
- public void onDestroy() {
- if (mPrefs != null) {
- mPrefs.unregisterOnSharedPreferenceChangeListener(this);
- }
- }
-
- private void maybeShowSplashScreen() {
- if (ResearchSettings.readHasSeenSplash(mPrefs)) return;
- if (mSplashScreen != null && mSplashScreen.isShowing()) return;
- if (mMainKeyboardView == null) return;
- final IBinder windowToken = mMainKeyboardView.getWindowToken();
- if (windowToken == null) return;
-
- mSplashScreen = new SplashScreen(mLatinIME, this);
- mSplashScreen.showSplashScreen(windowToken);
- }
-
- @Override
- public void onSplashScreenUserClickedOk() {
- if (mPrefs == null) {
- mPrefs = PreferenceManager.getDefaultSharedPreferences(mLatinIME);
- if (mPrefs == null) return;
- }
- sIsLogging = true;
- ResearchSettings.writeResearchLoggerEnabledFlag(mPrefs, true);
- ResearchSettings.writeHasSeenSplash(mPrefs, true);
- restart();
- }
-
- private void checkForEmptyEditor() {
- if (mLatinIME == null) {
- return;
- }
- final InputConnection ic = mLatinIME.getCurrentInputConnection();
- if (ic == null) {
- return;
- }
- final CharSequence textBefore = ic.getTextBeforeCursor(1, 0);
- if (!TextUtils.isEmpty(textBefore)) {
- mStatistics.setIsEmptyUponStarting(false);
- return;
- }
- final CharSequence textAfter = ic.getTextAfterCursor(1, 0);
- if (!TextUtils.isEmpty(textAfter)) {
- mStatistics.setIsEmptyUponStarting(false);
- return;
- }
- if (textBefore != null && textAfter != null) {
- mStatistics.setIsEmptyUponStarting(true);
- }
- }
-
- private void start() {
- if (DEBUG) {
- Log.d(TAG, "start called");
- }
- maybeShowSplashScreen();
- requestIndicatorRedraw();
- mStatistics.reset();
- checkForEmptyEditor();
- }
-
- /* package */ void stop() {
- if (DEBUG) {
- Log.d(TAG, "stop called");
- }
- // Commit mCurrentLogUnit before closing.
- commitCurrentLogUnit();
-
- try {
- mMainLogBuffer.shiftAndPublishAll();
- } catch (final IOException e) {
- Log.w(TAG, "IOException when publishing LogBuffer", e);
- }
- logStatistics();
- commitCurrentLogUnit();
- mMainLogBuffer.setIsStopping();
- try {
- mMainLogBuffer.shiftAndPublishAll();
- } catch (final IOException e) {
- Log.w(TAG, "IOException when publishing LogBuffer", e);
- }
- mMainResearchLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
-
- resetLogBuffers();
- cancelFeedbackDialog();
- }
-
- public void abort() {
- if (DEBUG) {
- Log.d(TAG, "abort called");
- }
- mMainLogBuffer.clear();
- mMainResearchLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
-
- resetLogBuffers();
- }
-
- private void restart() {
- stop();
- start();
- }
-
- @Override
- public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
- if (key == null || prefs == null) {
- return;
- }
- requestIndicatorRedraw();
- mPrefs = prefs;
- prefsChanged(prefs);
- }
-
- public void onResearchKeySelected(final LatinIME latinIME) {
- mCurrentLogUnit.removeResearchButtonInvocation();
- if (mInFeedbackDialog) {
- Toast.makeText(latinIME, R.string.research_please_exit_feedback_form,
- Toast.LENGTH_LONG).show();
- return;
- }
- presentFeedbackDialog(latinIME);
- }
-
- public void presentFeedbackDialogFromSettings() {
- if (mLatinIME != null) {
- presentFeedbackDialog(mLatinIME);
- }
- }
-
- public void presentFeedbackDialog(final LatinIME latinIME) {
- if (isMakingUserRecording()) {
- saveRecording();
- }
- mInFeedbackDialog = true;
-
- final Intent intent = new Intent();
- intent.setClass(mLatinIME, FeedbackActivity.class);
- if (mFeedbackDialogBundle == null) {
- // Restore feedback field with channel name
- final Bundle bundle = new Bundle();
- bundle.putBoolean(FeedbackFragment.KEY_INCLUDE_ACCOUNT_NAME, true);
- bundle.putBoolean(FeedbackFragment.KEY_HAS_USER_RECORDING, false);
- if (FEEDBACK_DIALOG_SHOULD_PRESERVE_TEXT_FIELD) {
- final String savedChannelName = mPrefs.getString(PREF_RESEARCH_SAVED_CHANNEL, "");
- bundle.putString(FeedbackFragment.KEY_FEEDBACK_STRING, savedChannelName);
- }
- mFeedbackDialogBundle = bundle;
- }
- intent.putExtras(mFeedbackDialogBundle);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- latinIME.startActivity(intent);
- }
-
- public void setFeedbackDialogBundle(final Bundle bundle) {
- mFeedbackDialogBundle = bundle;
- }
-
- public void startRecording() {
- final Resources res = mLatinIME.getResources();
- Toast.makeText(mLatinIME,
- res.getString(R.string.research_feedback_demonstration_instructions),
- Toast.LENGTH_LONG).show();
- startRecordingInternal();
- }
-
- private void startRecordingInternal() {
- if (mUserRecordingLog != null) {
- mUserRecordingLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
- }
- mUserRecordingFile = mResearchLogDirectory.getUserRecordingFilePath(
- System.currentTimeMillis(), System.nanoTime());
- mUserRecordingLog = new ResearchLog(mUserRecordingFile, mLatinIME);
- mUserRecordingLogBuffer = new LogBuffer();
- resetRecordingTimer();
- }
-
- private boolean isMakingUserRecording() {
- return mUserRecordingLog != null;
- }
-
- private void resetRecordingTimer() {
- if (mUserRecordingTimeoutHandler == null) {
- mUserRecordingTimeoutHandler = new Handler();
- }
- clearRecordingTimer();
- mUserRecordingTimeoutHandler.postDelayed(mRecordingHandlerTimeoutRunnable,
- USER_RECORDING_TIMEOUT_MS);
- }
-
- private void clearRecordingTimer() {
- mUserRecordingTimeoutHandler.removeCallbacks(mRecordingHandlerTimeoutRunnable);
- }
-
- private Runnable mRecordingHandlerTimeoutRunnable = new Runnable() {
- @Override
- public void run() {
- cancelRecording();
- requestIndicatorRedraw();
- final Resources res = mLatinIME.getResources();
- Toast.makeText(mLatinIME, res.getString(R.string.research_feedback_recording_failure),
- Toast.LENGTH_LONG).show();
- }
- };
-
- private void cancelRecording() {
- if (mUserRecordingLog != null) {
- mUserRecordingLog.blockingAbort(RESEARCHLOG_ABORT_TIMEOUT_IN_MS);
- }
- mUserRecordingLog = null;
- mUserRecordingLogBuffer = null;
- if (mFeedbackDialogBundle != null) {
- mFeedbackDialogBundle.putBoolean("HasRecording", false);
- }
- }
-
- private void saveRecording() {
- commitCurrentLogUnit();
- publishLogBuffer(mUserRecordingLogBuffer, mUserRecordingLog, true);
- mUserRecordingLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
- mUserRecordingLog = null;
- mUserRecordingLogBuffer = null;
-
- if (mFeedbackDialogBundle != null) {
- mFeedbackDialogBundle.putBoolean(FeedbackFragment.KEY_HAS_USER_RECORDING, true);
- }
- clearRecordingTimer();
- }
-
- // TODO: currently unreachable. Remove after being sure enable/disable is
- // not needed.
- /*
- public void enableOrDisable(final boolean showEnable, final LatinIME latinIME) {
- if (showEnable) {
- if (!sIsLogging) {
- setLoggingAllowed(true);
- }
- resumeLogging();
- Toast.makeText(latinIME,
- R.string.research_notify_session_logging_enabled,
- Toast.LENGTH_LONG).show();
- } else {
- Toast toast = Toast.makeText(latinIME,
- R.string.research_notify_session_log_deleting,
- Toast.LENGTH_LONG);
- toast.show();
- boolean isLogDeleted = abort();
- final long currentTime = System.currentTimeMillis();
- final long resumeTime = currentTime
- + TimeUnit.MINUTES.toMillis(SUSPEND_DURATION_IN_MINUTES);
- suspendLoggingUntil(resumeTime);
- toast.cancel();
- Toast.makeText(latinIME, R.string.research_notify_logging_suspended,
- Toast.LENGTH_LONG).show();
- }
- }
- */
-
- /**
- * Get the name of the first allowed account on the device.
- *
- * Allowed accounts must be in the domain given by ALLOWED_ACCOUNT_DOMAIN.
- *
- * @return The user's account name.
- */
- public String getAccountName() {
- if (sAccountType == null || sAccountType.isEmpty()) {
- return null;
- }
- if (sAllowedAccountDomain == null || sAllowedAccountDomain.isEmpty()) {
- return null;
- }
- final AccountManager manager = AccountManager.get(mLatinIME);
- // Filter first by account type.
- final Account[] accounts = manager.getAccountsByType(sAccountType);
-
- for (final Account account : accounts) {
- if (DEBUG) {
- Log.d(TAG, account.name);
- }
- final String[] parts = account.name.split("@");
- if (parts.length > 1 && parts[1].equals(sAllowedAccountDomain)) {
- return parts[0];
- }
- }
- return null;
- }
-
- private static final LogStatement LOGSTATEMENT_FEEDBACK =
- new LogStatement("UserFeedback", false, false, "contents", "accountName", "recording");
- public void sendFeedback(final String feedbackContents, final boolean includeHistory,
- final boolean isIncludingAccountName, final boolean isIncludingRecording) {
- String recording = "";
- if (isIncludingRecording) {
- // Try to read recording from recently written json file
- if (mUserRecordingFile != null) {
- FileChannel channel = null;
- try {
- channel = new FileInputStream(mUserRecordingFile).getChannel();
- final MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0,
- channel.size());
- // Android's openFileOutput() creates the file, so we use Android's default
- // Charset (UTF-8) here to read it.
- recording = Charset.defaultCharset().decode(buffer).toString();
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Could not find recording file", e);
- } catch (IOException e) {
- Log.e(TAG, "Error reading recording file", e);
- } finally {
- if (channel != null) {
- try {
- channel.close();
- } catch (IOException e) {
- Log.e(TAG, "Error closing recording file", e);
- }
- }
- }
- }
- }
- final LogUnit feedbackLogUnit = new LogUnit();
- final String accountName = isIncludingAccountName ? getAccountName() : "";
- feedbackLogUnit.addLogStatement(LOGSTATEMENT_FEEDBACK, SystemClock.uptimeMillis(),
- feedbackContents, accountName, recording);
-
- final ResearchLog feedbackLog = new FeedbackLog(mResearchLogDirectory.getLogFilePath(
- System.currentTimeMillis(), System.nanoTime()), mLatinIME);
- final LogBuffer feedbackLogBuffer = new LogBuffer();
- feedbackLogBuffer.shiftIn(feedbackLogUnit);
- publishLogBuffer(feedbackLogBuffer, feedbackLog, true /* isIncludingPrivateData */);
- feedbackLog.blockingClose(RESEARCHLOG_CLOSE_TIMEOUT_IN_MS);
- uploadNow();
-
- if (isIncludingRecording && DEBUG_REPLAY_AFTER_FEEDBACK) {
- final Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- final ReplayData replayData =
- mMotionEventReader.readMotionEventData(mUserRecordingFile);
- mReplayer.replay(replayData, null);
- }
- }, TimeUnit.SECONDS.toMillis(1));
- }
-
- if (FEEDBACK_DIALOG_SHOULD_PRESERVE_TEXT_FIELD) {
- // Use feedback string as a channel name to label feedback strings. Here we record the
- // string for prepopulating the field next time.
- final String channelName = feedbackContents;
- if (mPrefs == null) {
- return;
- }
- mPrefs.edit().putString(PREF_RESEARCH_SAVED_CHANNEL, channelName).apply();
- }
- }
-
- public void uploadNow() {
- if (DEBUG) {
- Log.d(TAG, "calling uploadNow()");
- }
- mLatinIME.startService(mUploadNowIntent);
- }
-
- public void onLeavingSendFeedbackDialog() {
- mInFeedbackDialog = false;
- }
-
- private void cancelFeedbackDialog() {
- if (isMakingUserRecording()) {
- cancelRecording();
- }
- mInFeedbackDialog = false;
- }
-
- public void initDictionary(final DictionaryFacilitatorForSuggest dictionaryFacilitator) {
- mDictionaryFacilitator = dictionaryFacilitator;
- // MainLogBuffer now has an out-of-date Suggest object. Close down MainLogBuffer and create
- // a new one.
- if (mMainLogBuffer != null) {
- restart();
- }
- }
-
- private void setIsPasswordView(boolean isPasswordView) {
- mIsPasswordView = isPasswordView;
- }
-
- /**
- * Returns true if logging is permitted.
- *
- * This method is called when adding a LogStatement to a LogUnit, and when adding a LogUnit to a
- * ResearchLog. It is checked in both places in case conditions change between these times, and
- * as a defensive measure in case refactoring changes the logging pipeline.
- */
- private boolean isAllowedToLogTo(final ResearchLog researchLog) {
- // Logging is never allowed in these circumstances
- if (mIsPasswordView) return false;
- if (!sIsLogging) return false;
- if (mInFeedbackDialog) {
- // The FeedbackDialog is up. Normal logging should not happen (the user might be trying
- // out things while the dialog is up, and their reporting of an issue may not be
- // representative of what they normally type). However, after the user has finished
- // entering their feedback, the logger packs their comments and an encoded version of
- // any demonstration of the issue into a special "FeedbackLog". So if the FeedbackLog
- // is the destination, we do want to allow logging to it.
- return researchLog.isFeedbackLog();
- }
- // No other exclusions. Logging is permitted.
- return true;
- }
-
- public void requestIndicatorRedraw() {
- if (!IS_SHOWING_INDICATOR) {
- return;
- }
- if (mMainKeyboardView == null) {
- return;
- }
- mMainKeyboardView.invalidateAllKeys();
- }
-
- private boolean isReplaying() {
- return mReplayer.isReplaying();
- }
-
- private int getIndicatorColor() {
- if (isMakingUserRecording()) {
- return Color.YELLOW;
- }
- if (isReplaying()) {
- return Color.GREEN;
- }
- return Color.RED;
- }
-
- public void paintIndicator(KeyboardView view, Paint paint, Canvas canvas, int width,
- int height) {
- // TODO: Reimplement using a keyboard background image specific to the ResearchLogger
- // and remove this method.
- // The check for MainKeyboardView ensures that the indicator only decorates the main
- // keyboard, not every keyboard.
- if (IS_SHOWING_INDICATOR && (isAllowedToLogTo(mMainResearchLog) || isReplaying())
- && view instanceof MainKeyboardView) {
- final int savedColor = paint.getColor();
- paint.setColor(getIndicatorColor());
- final Style savedStyle = paint.getStyle();
- paint.setStyle(Style.STROKE);
- final float savedStrokeWidth = paint.getStrokeWidth();
- if (IS_SHOWING_INDICATOR_CLEARLY) {
- paint.setStrokeWidth(5);
- canvas.drawLine(0, 0, 0, height, paint);
- canvas.drawLine(width, 0, width, height, paint);
- } else {
- // Put a tiny dot on the screen so a knowledgeable user can check whether it is
- // enabled. The dot is actually a zero-width, zero-height rectangle, placed at the
- // lower-right corner of the canvas, painted with a non-zero border width.
- paint.setStrokeWidth(3);
- canvas.drawRect(width - 1, height - 1, width, height, paint);
- }
- paint.setColor(savedColor);
- paint.setStyle(savedStyle);
- paint.setStrokeWidth(savedStrokeWidth);
- }
- }
-
- /**
- * Buffer a research log event, flagging it as privacy-sensitive.
- */
- private synchronized void enqueueEvent(final LogStatement logStatement,
- final Object... values) {
- enqueueEvent(mCurrentLogUnit, logStatement, values);
- }
-
- private synchronized void enqueueEvent(final LogUnit logUnit, final LogStatement logStatement,
- final Object... values) {
- assert values.length == logStatement.getKeys().length;
- if (isAllowedToLogTo(mMainResearchLog) && logUnit != null) {
- final long time = SystemClock.uptimeMillis();
- logUnit.addLogStatement(logStatement, time, values);
- }
- }
-
- private void setCurrentLogUnitContainsDigitFlag() {
- mCurrentLogUnit.setMayContainDigit();
- }
-
- private void setCurrentLogUnitContainsUserDeletions() {
- mCurrentLogUnit.setContainsUserDeletions();
- }
-
- private void setCurrentLogUnitCorrectionType(final int correctionType) {
- mCurrentLogUnit.setCorrectionType(correctionType);
- }
-
- /* package for test */ void commitCurrentLogUnit() {
- if (DEBUG) {
- Log.d(TAG, "commitCurrentLogUnit" + (mCurrentLogUnit.hasOneOrMoreWords() ?
- ": " + mCurrentLogUnit.getWordsAsString() : ""));
- }
- if (!mCurrentLogUnit.isEmpty()) {
- mMainLogBuffer.shiftIn(mCurrentLogUnit);
- if (mUserRecordingLogBuffer != null) {
- mUserRecordingLogBuffer.shiftIn(mCurrentLogUnit);
- }
- mCurrentLogUnit = new LogUnit();
- } else {
- if (DEBUG) {
- Log.d(TAG, "Warning: tried to commit empty log unit.");
- }
- }
- }
-
- private static final LogStatement LOGSTATEMENT_UNCOMMIT_CURRENT_LOGUNIT =
- new LogStatement("UncommitCurrentLogUnit", false, false);
- public void uncommitCurrentLogUnit(final String expectedWord,
- final boolean dumpCurrentLogUnit) {
- // The user has deleted this word and returned to the previous. Check that the word in the
- // logUnit matches the expected word. If so, restore the last log unit committed to be the
- // current logUnit. I.e., pull out the last LogUnit from all the LogBuffers, and make
- // it the mCurrentLogUnit so the new edits are captured with the word. Optionally dump the
- // contents of mCurrentLogUnit (useful if they contain deletions of the next word that
- // should not be reported to protect user privacy)
- //
- // Note that we don't use mLastLogUnit here, because it only goes one word back and is only
- // needed for reverts, which only happen one back.
- final LogUnit oldLogUnit = mMainLogBuffer.peekLastLogUnit();
-
- // Check that expected word matches. It's ok if both strings are null, because this is the
- // case where the LogUnit is storing a non-word, e.g. a separator.
- if (oldLogUnit != null) {
- // Because the word is stored in the LogUnit with digits scrubbed, the comparison must
- // be made on a scrubbed version of the expectedWord as well.
- final String scrubbedExpectedWord = scrubDigitsFromString(expectedWord);
- final String oldLogUnitWords = oldLogUnit.getWordsAsString();
- if (!TextUtils.equals(scrubbedExpectedWord, oldLogUnitWords)) return;
- }
-
- // Uncommit, merging if necessary.
- mMainLogBuffer.unshiftIn();
- if (oldLogUnit != null && !dumpCurrentLogUnit) {
- oldLogUnit.append(mCurrentLogUnit);
- mSavedDownEventTime = Long.MAX_VALUE;
- }
- if (oldLogUnit == null) {
- mCurrentLogUnit = new LogUnit();
- } else {
- mCurrentLogUnit = oldLogUnit;
- }
- enqueueEvent(LOGSTATEMENT_UNCOMMIT_CURRENT_LOGUNIT);
- if (DEBUG) {
- Log.d(TAG, "uncommitCurrentLogUnit (dump=" + dumpCurrentLogUnit + ") back to "
- + (mCurrentLogUnit.hasOneOrMoreWords() ? ": '"
- + mCurrentLogUnit.getWordsAsString() + "'" : ""));
- }
- }
-
- /**
- * Publish all the logUnits in the logBuffer, without doing any privacy filtering.
- */
- /* package for test */ void publishLogBuffer(final LogBuffer logBuffer,
- final ResearchLog researchLog, final boolean canIncludePrivateData) {
- publishLogUnits(logBuffer.getLogUnits(), researchLog, canIncludePrivateData);
- }
-
- private static final LogStatement LOGSTATEMENT_LOG_SEGMENT_OPENING =
- new LogStatement("logSegmentStart", false, false, "isIncludingPrivateData");
- private static final LogStatement LOGSTATEMENT_LOG_SEGMENT_CLOSING =
- new LogStatement("logSegmentEnd", false, false);
- /**
- * Publish all LogUnits in a list.
- *
- * Any privacy checks should be performed before calling this method.
- */
- /* package for test */ void publishLogUnits(final List<LogUnit> logUnits,
- final ResearchLog researchLog, final boolean canIncludePrivateData) {
- final LogUnit openingLogUnit = new LogUnit();
- if (logUnits.isEmpty()) return;
- if (!isAllowedToLogTo(researchLog)) return;
- // LogUnits not containing private data, such as contextual data for the log, do not require
- // logSegment boundary statements.
- if (canIncludePrivateData) {
- openingLogUnit.addLogStatement(LOGSTATEMENT_LOG_SEGMENT_OPENING,
- SystemClock.uptimeMillis(), canIncludePrivateData);
- researchLog.publish(openingLogUnit, true /* isIncludingPrivateData */);
- }
- for (LogUnit logUnit : logUnits) {
- if (DEBUG) {
- Log.d(TAG, "publishLogBuffer: " + (logUnit.hasOneOrMoreWords()
- ? logUnit.getWordsAsString() : "<wordless>")
- + ", correction?: " + logUnit.containsUserDeletions());
- }
- researchLog.publish(logUnit, canIncludePrivateData);
- }
- if (canIncludePrivateData) {
- final LogUnit closingLogUnit = new LogUnit();
- closingLogUnit.addLogStatement(LOGSTATEMENT_LOG_SEGMENT_CLOSING,
- SystemClock.uptimeMillis());
- researchLog.publish(closingLogUnit, true /* isIncludingPrivateData */);
- }
- }
-
- public static boolean hasLetters(final String word) {
- final int length = word.length();
- for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
- final int codePoint = word.codePointAt(i);
- if (Character.isLetter(codePoint)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Commit the portion of mCurrentLogUnit before maxTime as a worded logUnit.
- *
- * After this operation completes, mCurrentLogUnit will hold any logStatements that happened
- * after maxTime.
- */
- /* package for test */ void commitCurrentLogUnitAsWord(final String word, final long maxTime,
- final boolean isBatchMode) {
- if (word == null) {
- return;
- }
- if (word.length() > 0 && hasLetters(word)) {
- mCurrentLogUnit.setWords(word);
- }
- final LogUnit newLogUnit = mCurrentLogUnit.splitByTime(maxTime);
- enqueueCommitText(word, isBatchMode);
- commitCurrentLogUnit();
- mCurrentLogUnit = newLogUnit;
- }
-
- /**
- * Record the time of a MotionEvent.ACTION_DOWN.
- *
- * Warning: Not thread safe. Only call from the main thread.
- */
- private void setSavedDownEventTime(final long time) {
- mSavedDownEventTime = time;
- }
-
- public void onWordFinished(final String word, final boolean isBatchMode) {
- commitCurrentLogUnitAsWord(word, mSavedDownEventTime, isBatchMode);
- mSavedDownEventTime = Long.MAX_VALUE;
- }
-
- private static int scrubDigitFromCodePoint(int codePoint) {
- return Character.isDigit(codePoint) ? DIGIT_REPLACEMENT_CODEPOINT : codePoint;
- }
-
- /* package for test */ static String scrubDigitsFromString(final String s) {
- if (s == null) return null;
- StringBuilder sb = null;
- final int length = s.length();
- for (int i = 0; i < length; i = s.offsetByCodePoints(i, 1)) {
- final int codePoint = Character.codePointAt(s, i);
- if (Character.isDigit(codePoint)) {
- if (sb == null) {
- sb = new StringBuilder(length);
- sb.append(s.substring(0, i));
- }
- sb.appendCodePoint(DIGIT_REPLACEMENT_CODEPOINT);
- } else {
- if (sb != null) {
- sb.appendCodePoint(codePoint);
- }
- }
- }
- if (sb == null) {
- return s;
- } else {
- return sb.toString();
- }
- }
-
- private String scrubWord(String word) {
- if (mDictionaryFacilitator != null && mDictionaryFacilitator.isValidMainDictWord(word)) {
- return word;
- }
- return WORD_REPLACEMENT_STRING;
- }
-
- // Specific logging methods follow below. The comments for each logging method should
- // indicate what specific method is logged, and how to trigger it from the user interface.
- //
- // Logging methods can be generally classified into two flavors, "UserAction", which should
- // correspond closely to an event that is sensed by the IME, and is usually generated
- // directly by the user, and "SystemResponse" which corresponds to an event that the IME
- // generates, often after much processing of user input. SystemResponses should correspond
- // closely to user-visible events.
- // TODO: Consider exposing the UserAction classification in the log output.
-
- /**
- * Log a call to LatinIME.onStartInputViewInternal().
- *
- * UserAction: called each time the keyboard is opened up.
- */
- private static final LogStatement LOGSTATEMENT_LATIN_IME_ON_START_INPUT_VIEW_INTERNAL =
- new LogStatement("LatinImeOnStartInputViewInternal", false, false, "uuid",
- "packageName", "inputType", "imeOptions", "fieldId", "display", "model",
- "prefs", "versionCode", "versionName", "outputFormatVersion", "logEverything",
- "isDevTeamBuild");
- public static void latinIME_onStartInputViewInternal(final EditorInfo editorInfo,
- final SharedPreferences prefs) {
- final ResearchLogger researchLogger = getInstance();
- if (editorInfo != null) {
- final boolean isPassword = InputTypeUtils.isPasswordInputType(editorInfo.inputType)
- || InputTypeUtils.isVisiblePasswordInputType(editorInfo.inputType);
- getInstance().setIsPasswordView(isPassword);
- researchLogger.start();
- final Context context = researchLogger.mLatinIME;
- try {
- final PackageInfo packageInfo;
- packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
- 0);
- final Integer versionCode = packageInfo.versionCode;
- final String versionName = packageInfo.versionName;
- final String uuid = ResearchSettings.readResearchLoggerUuid(researchLogger.mPrefs);
- researchLogger.enqueueEvent(LOGSTATEMENT_LATIN_IME_ON_START_INPUT_VIEW_INTERNAL,
- uuid, editorInfo.packageName, Integer.toHexString(editorInfo.inputType),
- Integer.toHexString(editorInfo.imeOptions), editorInfo.fieldId,
- Build.DISPLAY, Build.MODEL, prefs, versionCode, versionName,
- OUTPUT_FORMAT_VERSION, IS_LOGGING_EVERYTHING,
- researchLogger.isDevTeamBuild());
- // Commit the logUnit so the LatinImeOnStartInputViewInternal event is in its own
- // logUnit at the beginning of the log.
- researchLogger.commitCurrentLogUnit();
- } catch (final NameNotFoundException e) {
- Log.e(TAG, "NameNotFound", e);
- }
- }
- }
-
- // TODO: Update this heuristic pattern to something more reliable. Developer builds tend to
- // have the developer name and year embedded.
- private static final Pattern developerBuildRegex = Pattern.compile("[A-Za-z]\\.20[1-9]");
- private boolean isDevTeamBuild() {
- try {
- final PackageInfo packageInfo;
- packageInfo = mLatinIME.getPackageManager().getPackageInfo(mLatinIME.getPackageName(),
- 0);
- final String versionName = packageInfo.versionName;
- return developerBuildRegex.matcher(versionName).find();
- } catch (final NameNotFoundException e) {
- Log.e(TAG, "Could not determine package name", e);
- return false;
- }
- }
-
- /**
- * Log a change in preferences.
- *
- * UserAction: called when the user changes the settings.
- */
- private static final LogStatement LOGSTATEMENT_PREFS_CHANGED =
- new LogStatement("PrefsChanged", false, false, "prefs");
- public static void prefsChanged(final SharedPreferences prefs) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_PREFS_CHANGED, prefs);
- }
-
- /**
- * Log a call to MainKeyboardView.processMotionEvent().
- *
- * UserAction: called when the user puts their finger onto the screen (ACTION_DOWN).
- *
- */
- private static final LogStatement LOGSTATEMENT_MAIN_KEYBOARD_VIEW_PROCESS_MOTION_EVENT =
- new LogStatement("MotionEvent", true, false, "action",
- LogStatement.KEY_IS_LOGGING_RELATED, "motionEvent");
- public static void mainKeyboardView_processMotionEvent(final MotionEvent me) {
- if (me == null) {
- return;
- }
- final int action = me.getActionMasked();
- final long eventTime = me.getEventTime();
- final String actionString = LoggingUtils.getMotionEventActionTypeString(action);
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_MAIN_KEYBOARD_VIEW_PROCESS_MOTION_EVENT,
- actionString, false /* IS_LOGGING_RELATED */, MotionEvent.obtain(me));
- if (action == MotionEvent.ACTION_DOWN) {
- // Subtract 1 from eventTime so the down event is included in the later
- // LogUnit, not the earlier (the test is for inequality).
- researchLogger.setSavedDownEventTime(eventTime - 1);
- }
- // Refresh the timer in case we are capturing user feedback.
- if (researchLogger.isMakingUserRecording()) {
- researchLogger.resetRecordingTimer();
- }
- }
-
- /**
- * Log a call to LatinIME.onCodeInput().
- *
- * SystemResponse: The main processing step for entering text. Called when the user performs a
- * tap, a flick, a long press, releases a gesture, or taps a punctuation suggestion.
- */
- private static final LogStatement LOGSTATEMENT_LATIN_IME_ON_CODE_INPUT =
- new LogStatement("LatinImeOnCodeInput", true, false, "code", "x", "y");
- public static void latinIME_onCodeInput(final int code, final int x, final int y) {
- final long time = SystemClock.uptimeMillis();
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATIN_IME_ON_CODE_INPUT,
- Constants.printableCode(scrubDigitFromCodePoint(code)), x, y);
- if (Character.isDigit(code)) {
- researchLogger.setCurrentLogUnitContainsDigitFlag();
- }
- researchLogger.mStatistics.recordChar(code, time);
- }
- /**
- * Log a call to LatinIME.onDisplayCompletions().
- *
- * SystemResponse: The IME has displayed application-specific completions. They may show up
- * in the suggestion strip, such as a landscape phone.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_ONDISPLAYCOMPLETIONS =
- new LogStatement("LatinIMEOnDisplayCompletions", true, true,
- "applicationSpecifiedCompletions");
- public static void latinIME_onDisplayCompletions(
- final CompletionInfo[] applicationSpecifiedCompletions) {
- // Note; passing an array as a single element in a vararg list. Must create a new
- // dummy array around it or it will get expanded.
- getInstance().enqueueEvent(LOGSTATEMENT_LATINIME_ONDISPLAYCOMPLETIONS,
- new Object[] { applicationSpecifiedCompletions });
- }
-
- /**
- * The IME is finishing; it is either being destroyed, or is about to be hidden.
- *
- * UserAction: The user has performed an action that has caused the IME to be closed. They may
- * have focused on something other than a text field, or explicitly closed it.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_ONFINISHINPUTVIEWINTERNAL =
- new LogStatement("LatinIMEOnFinishInputViewInternal", false, false, "isTextTruncated",
- "text");
- public static void latinIME_onFinishInputViewInternal(final boolean finishingInput) {
- // The finishingInput flag is set in InputMethodService. It is true if called from
- // doFinishInput(), which can be called as part of doStartInput(). This can happen at times
- // when the IME is not closing, such as when powering up. The finishinInput flag is false
- // if called from finishViews(), which is called from hideWindow() and onDestroy(). These
- // are the situations in which we want to finish up the researchLog.
- if (!finishingInput) {
- final ResearchLogger researchLogger = getInstance();
- // Assume that OUTPUT_ENTIRE_BUFFER is only true when we don't care about privacy (e.g.
- // during a live user test), so the normal isPotentiallyPrivate and
- // isPotentiallyRevealing flags do not apply
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONFINISHINPUTVIEWINTERNAL,
- true /* isTextTruncated */, "" /* text */);
- researchLogger.commitCurrentLogUnit();
- getInstance().stop();
- }
- }
-
- /**
- * Log a call to LatinIME.onUpdateSelection().
- *
- * UserAction/SystemResponse: The user has moved the cursor or selection. This function may
- * be called, however, when the system has moved the cursor, say by inserting a character.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_ONUPDATESELECTION =
- new LogStatement("LatinIMEOnUpdateSelection", true, false, "lastSelectionStart",
- "lastSelectionEnd", "oldSelStart", "oldSelEnd", "newSelStart", "newSelEnd",
- "composingSpanStart", "composingSpanEnd", "expectingUpdateSelection",
- "expectingUpdateSelectionFromLogger", "context");
- public static void latinIME_onUpdateSelection(final int lastSelectionStart,
- final int lastSelectionEnd, final int oldSelStart, final int oldSelEnd,
- final int newSelStart, final int newSelEnd, final int composingSpanStart,
- final int composingSpanEnd, final RichInputConnection connection) {
- String word = "";
- if (connection != null) {
- TextRange range = connection.getWordRangeAtCursor(WHITESPACE_SEPARATORS, 1);
- if (range != null) {
- word = range.mWord.toString();
- }
- }
- final ResearchLogger researchLogger = getInstance();
- final String scrubbedWord = researchLogger.scrubWord(word);
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONUPDATESELECTION, lastSelectionStart,
- lastSelectionEnd, oldSelStart, oldSelEnd, newSelStart, newSelEnd,
- composingSpanStart, composingSpanEnd, false /* expectingUpdateSelection */,
- false /* expectingUpdateSelectionFromLogger */, scrubbedWord);
- }
-
- /**
- * Log a call to LatinIME.onTextInput().
- *
- * SystemResponse: Raw text is added to the TextView.
- */
- public static void latinIME_onTextInput(final String text, final boolean isBatchMode) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.commitCurrentLogUnitAsWord(text, Long.MAX_VALUE, isBatchMode);
- }
-
- /**
- * Log a revert of onTextInput() (known in the IME as "EnteredText").
- *
- * SystemResponse: Remove the LogUnit recording the textInput
- */
- public static void latinIME_handleBackspace_cancelTextInput(final String text) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.uncommitCurrentLogUnit(text, true /* dumpCurrentLogUnit */);
- }
-
- /**
- * Log a call to LatinIME.pickSuggestionManually().
- *
- * UserAction: The user has chosen a specific word from the suggestion strip.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_PICKSUGGESTIONMANUALLY =
- new LogStatement("LatinIMEPickSuggestionManually", true, false, "replacedWord", "index",
- "suggestion", "x", "y", "isBatchMode", "score", "kind", "sourceDict");
- /**
- * Log a call to LatinIME.pickSuggestionManually().
- *
- * @param replacedWord the typed word that this manual suggestion replaces. May not be null.
- * @param index the index in the suggestion strip
- * @param suggestion the committed suggestion. May not be null.
- * @param isBatchMode whether this was input in batch mode, aka gesture.
- * @param score the internal score of the suggestion, as output by the dictionary
- * @param kind the kind of suggestion, as one of the SuggestedWordInfo#KIND_* constants
- * @param sourceDict the source origin of this word, as one of the Dictionary#TYPE_* constants.
- */
- public static void latinIME_pickSuggestionManually(final String replacedWord,
- final int index, final String suggestion, final boolean isBatchMode,
- final int score, final int kind, final String sourceDict) {
- final ResearchLogger researchLogger = getInstance();
- // Note : suggestion can't be null here, because it's only called in a place where it
- // can't be null.
- if (!replacedWord.equals(suggestion.toString())) {
- // The user chose something other than what was already there.
- researchLogger.setCurrentLogUnitContainsUserDeletions();
- researchLogger.setCurrentLogUnitCorrectionType(LogUnit.CORRECTIONTYPE_TYPO);
- }
- final String scrubbedWord = scrubDigitsFromString(suggestion);
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PICKSUGGESTIONMANUALLY,
- scrubDigitsFromString(replacedWord), index,
- scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
- Constants.SUGGESTION_STRIP_COORDINATE, isBatchMode, score, kind, sourceDict);
- researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode);
- researchLogger.mStatistics.recordManualSuggestion(SystemClock.uptimeMillis());
- }
-
- /**
- * Log a call to LatinIME.punctuationSuggestion().
- *
- * UserAction: The user has chosen punctuation from the punctuation suggestion strip.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION =
- new LogStatement("LatinIMEPunctuationSuggestion", false, false, "index", "suggestion",
- "x", "y", "isPrediction");
- public static void latinIME_punctuationSuggestion(final int index, final String suggestion,
- final boolean isBatchMode, final boolean isPrediction) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PUNCTUATIONSUGGESTION, index, suggestion,
- Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE,
- isPrediction);
- researchLogger.commitCurrentLogUnitAsWord(suggestion, Long.MAX_VALUE, isBatchMode);
- }
-
- /**
- * Log a call to LatinIME.sendKeyCodePoint().
- *
- * SystemResponse: The IME is inserting text into the TextView for non-word-constituent,
- * strings (separators, numbers, other symbols).
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_SENDKEYCODEPOINT =
- new LogStatement("LatinIMESendKeyCodePoint", true, false, "code");
- public static void latinIME_sendKeyCodePoint(final int code) {
- final ResearchLogger researchLogger = getInstance();
- final LogUnit phantomSpaceLogUnit = researchLogger.mPhantomSpaceLogUnit;
- if (phantomSpaceLogUnit == null) {
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_SENDKEYCODEPOINT,
- Constants.printableCode(scrubDigitFromCodePoint(code)));
- if (Character.isDigit(code)) {
- researchLogger.setCurrentLogUnitContainsDigitFlag();
- }
- researchLogger.commitCurrentLogUnit();
- } else {
- researchLogger.enqueueEvent(phantomSpaceLogUnit, LOGSTATEMENT_LATINIME_SENDKEYCODEPOINT,
- Constants.printableCode(scrubDigitFromCodePoint(code)));
- if (Character.isDigit(code)) {
- phantomSpaceLogUnit.setMayContainDigit();
- }
- researchLogger.mMainLogBuffer.shiftIn(phantomSpaceLogUnit);
- if (researchLogger.mUserRecordingLogBuffer != null) {
- researchLogger.mUserRecordingLogBuffer.shiftIn(phantomSpaceLogUnit);
- }
- researchLogger.mPhantomSpaceLogUnit = null;
- }
- }
-
- /**
- * Log a call to LatinIME.promotePhantomSpace().
- *
- * SystemResponse: The IME is inserting a real space in place of a phantom space.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_PROMOTEPHANTOMSPACE =
- new LogStatement("LatinIMEPromotePhantomSpace", false, false);
- public static void latinIME_promotePhantomSpace() {
- // A phantom space is always added before the text that triggered it. The triggering text
- // and the events that created it will be in mCurrentLogUnit, but the phantom space should
- // be in its own LogUnit, committed before the triggering text. Although it is created
- // here, it is not added to the LogBuffer until the following call to
- // latinIME_sendKeyCodePoint, because SENDKEYCODEPOINT LogStatement also must go into that
- // LogUnit.
- final ResearchLogger researchLogger = getInstance();
- researchLogger.mPhantomSpaceLogUnit = new LogUnit();
- researchLogger.enqueueEvent(researchLogger.mPhantomSpaceLogUnit,
- LOGSTATEMENT_LATINIME_PROMOTEPHANTOMSPACE);
- }
-
- /**
- * Log a call to LatinIME.swapSwapperAndSpace().
- *
- * SystemResponse: A symbol has been swapped with a space character. E.g. punctuation may swap
- * if a soft space is inserted after a word.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE =
- new LogStatement("LatinIMESwapSwapperAndSpace", false, false, "originalCharacters",
- "charactersAfterSwap");
- public static void latinIME_swapSwapperAndSpace(final CharSequence originalCharacters,
- final String charactersAfterSwap) {
- final ResearchLogger researchLogger = getInstance();
- final LogUnit logUnit;
- logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
- if (logUnit != null) {
- researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_SWAPSWAPPERANDSPACE,
- originalCharacters, charactersAfterSwap);
- }
- }
-
- /**
- * Log a call to LatinIME.maybeDoubleSpacePeriod().
- *
- * SystemResponse: Two spaces have been replaced by period space.
- */
- public static void latinIME_maybeDoubleSpacePeriod(final String text,
- final boolean isBatchMode) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.commitCurrentLogUnitAsWord(text, Long.MAX_VALUE, isBatchMode);
- }
-
- /**
- * Log a call to MainKeyboardView.onLongPress().
- *
- * UserAction: The user has performed a long-press on a key.
- */
- private static final LogStatement LOGSTATEMENT_MAINKEYBOARDVIEW_ONLONGPRESS =
- new LogStatement("MainKeyboardViewOnLongPress", false, false);
- public static void mainKeyboardView_onLongPress() {
- getInstance().enqueueEvent(LOGSTATEMENT_MAINKEYBOARDVIEW_ONLONGPRESS);
- }
-
- /**
- * Log a call to MainKeyboardView.setKeyboard().
- *
- * SystemResponse: The IME has switched to a new keyboard (e.g. French, English).
- * This is typically called right after LatinIME.onStartInputViewInternal (when starting a new
- * IME), but may happen at other times if the user explicitly requests a keyboard change.
- */
- private static final LogStatement LOGSTATEMENT_MAINKEYBOARDVIEW_SETKEYBOARD =
- new LogStatement("MainKeyboardViewSetKeyboard", false, false, "elementId", "locale",
- "orientation", "width", "modeName", "action", "navigateNext",
- "navigatePrevious", "clobberSettingsKey", "passwordInput",
- "supportsSwitchingToShortcutIme", "hasShortcutKey", "languageSwitchKeyEnabled",
- "isMultiLine", "tw", "th",
- "keys");
- public static void mainKeyboardView_setKeyboard(final Keyboard keyboard,
- final int orientation) {
- final KeyboardId kid = keyboard.mId;
- final boolean isPasswordView = kid.passwordInput();
- final ResearchLogger researchLogger = getInstance();
- researchLogger.setIsPasswordView(isPasswordView);
- researchLogger.enqueueEvent(LOGSTATEMENT_MAINKEYBOARDVIEW_SETKEYBOARD,
- KeyboardId.elementIdToName(kid.mElementId),
- kid.mLocale + ":" + kid.mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
- orientation, kid.mWidth, KeyboardId.modeName(kid.mMode), kid.imeAction(),
- kid.navigateNext(), kid.navigatePrevious(), kid.mClobberSettingsKey,
- isPasswordView, kid.mSupportsSwitchingToShortcutIme, kid.mHasShortcutKey,
- kid.mLanguageSwitchKeyEnabled, kid.isMultiLine(), keyboard.mOccupiedWidth,
- keyboard.mOccupiedHeight, keyboard.getSortedKeys());
- }
-
- /**
- * Log a call to LatinIME.revertCommit().
- *
- * SystemResponse: The IME has reverted commited text. This happens when the user enters
- * a word, commits it by pressing space or punctuation, and then reverts the commit by hitting
- * backspace.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_REVERTCOMMIT =
- new LogStatement("LatinIMERevertCommit", true, false, "committedWord",
- "originallyTypedWord", "separatorString");
- public static void latinIME_revertCommit(final String committedWord,
- final String originallyTypedWord, final boolean isBatchMode,
- final String separatorString) {
- // TODO: Prioritize adding a unit test for this method (as it is especially complex)
- // TODO: Update the UserRecording LogBuffer as well as the MainLogBuffer
- final ResearchLogger researchLogger = getInstance();
- //
- // 1. Remove separator LogUnit
- final LogUnit lastLogUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
- // Check that we're not at the beginning of input
- if (lastLogUnit == null) return;
- // Check that we're after a separator
- if (lastLogUnit.getWordsAsString() != null) return;
- // Remove separator
- final LogUnit separatorLogUnit = researchLogger.mMainLogBuffer.unshiftIn();
-
- // 2. Add revert LogStatement
- final LogUnit revertedLogUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
- if (revertedLogUnit == null) return;
- if (!revertedLogUnit.getWordsAsString().equals(scrubDigitsFromString(committedWord))) {
- // Any word associated with the reverted LogUnit has already had its digits scrubbed, so
- // any digits in the committedWord argument must also be scrubbed for an accurate
- // comparison.
- return;
- }
- researchLogger.enqueueEvent(revertedLogUnit, LOGSTATEMENT_LATINIME_REVERTCOMMIT,
- committedWord, originallyTypedWord, separatorString);
-
- // 3. Update the word associated with the LogUnit
- revertedLogUnit.setWords(originallyTypedWord);
- revertedLogUnit.setContainsUserDeletions();
-
- // 4. Re-add the separator LogUnit
- researchLogger.mMainLogBuffer.shiftIn(separatorLogUnit);
-
- // 5. Record stats
- researchLogger.mStatistics.recordRevertCommit(SystemClock.uptimeMillis());
- }
-
- /**
- * Log a call to PointerTracker.callListenerOnCancelInput().
- *
- * UserAction: The user has canceled the input, e.g., by pressing down, but then removing
- * outside the keyboard area.
- * TODO: Verify
- */
- private static final LogStatement LOGSTATEMENT_POINTERTRACKER_CALLLISTENERONCANCELINPUT =
- new LogStatement("PointerTrackerCallListenerOnCancelInput", false, false);
- public static void pointerTracker_callListenerOnCancelInput() {
- getInstance().enqueueEvent(LOGSTATEMENT_POINTERTRACKER_CALLLISTENERONCANCELINPUT);
- }
-
- /**
- * Log a call to PointerTracker.callListenerOnCodeInput().
- *
- * SystemResponse: The user has entered a key through the normal tapping mechanism.
- * LatinIME.onCodeInput will also be called.
- */
- private static final LogStatement LOGSTATEMENT_POINTERTRACKER_CALLLISTENERONCODEINPUT =
- new LogStatement("PointerTrackerCallListenerOnCodeInput", true, false, "code",
- "outputText", "x", "y", "ignoreModifierKey", "altersCode", "isEnabled");
- public static void pointerTracker_callListenerOnCodeInput(final Key key, final int x,
- final int y, final boolean ignoreModifierKey, final boolean altersCode,
- final int code) {
- if (key != null) {
- String outputText = key.getOutputText();
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_POINTERTRACKER_CALLLISTENERONCODEINPUT,
- Constants.printableCode(scrubDigitFromCodePoint(code)),
- outputText == null ? null : scrubDigitsFromString(outputText.toString()),
- x, y, ignoreModifierKey, altersCode, key.isEnabled());
- }
- }
-
- /**
- * Log a call to PointerTracker.callListenerCallListenerOnRelease().
- *
- * UserAction: The user has released their finger or thumb from the screen.
- */
- private static final LogStatement LOGSTATEMENT_POINTERTRACKER_CALLLISTENERONRELEASE =
- new LogStatement("PointerTrackerCallListenerOnRelease", true, false, "code",
- "withSliding", "ignoreModifierKey", "isEnabled");
- public static void pointerTracker_callListenerOnRelease(final Key key, final int primaryCode,
- final boolean withSliding, final boolean ignoreModifierKey) {
- if (key != null) {
- getInstance().enqueueEvent(LOGSTATEMENT_POINTERTRACKER_CALLLISTENERONRELEASE,
- Constants.printableCode(scrubDigitFromCodePoint(primaryCode)), withSliding,
- ignoreModifierKey, key.isEnabled());
- }
- }
-
- /**
- * Log a call to PointerTracker.onDownEvent().
- *
- * UserAction: The user has pressed down on a key.
- * TODO: Differentiate with LatinIME.processMotionEvent.
- */
- private static final LogStatement LOGSTATEMENT_POINTERTRACKER_ONDOWNEVENT =
- new LogStatement("PointerTrackerOnDownEvent", true, false, "deltaT", "distanceSquared");
- public static void pointerTracker_onDownEvent(long deltaT, int distanceSquared) {
- getInstance().enqueueEvent(LOGSTATEMENT_POINTERTRACKER_ONDOWNEVENT, deltaT,
- distanceSquared);
- }
-
- /**
- * Log a call to PointerTracker.onMoveEvent().
- *
- * UserAction: The user has moved their finger while pressing on the screen.
- * TODO: Differentiate with LatinIME.processMotionEvent().
- */
- private static final LogStatement LOGSTATEMENT_POINTERTRACKER_ONMOVEEVENT =
- new LogStatement("PointerTrackerOnMoveEvent", true, false, "x", "y", "lastX", "lastY");
- public static void pointerTracker_onMoveEvent(final int x, final int y, final int lastX,
- final int lastY) {
- getInstance().enqueueEvent(LOGSTATEMENT_POINTERTRACKER_ONMOVEEVENT, x, y, lastX, lastY);
- }
-
- /**
- * Log a call to RichInputConnection.commitCompletion().
- *
- * SystemResponse: The IME has committed a completion. A completion is an application-
- * specific suggestion that is presented in a pop-up menu in the TextView.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_COMMITCOMPLETION =
- new LogStatement("RichInputConnectionCommitCompletion", true, false, "completionInfo");
- public static void richInputConnection_commitCompletion(final CompletionInfo completionInfo) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_COMMITCOMPLETION,
- completionInfo);
- }
-
- /**
- * Log a call to RichInputConnection.revertDoubleSpacePeriod().
- *
- * SystemResponse: The IME has reverted ". ", which had previously replaced two typed spaces.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_REVERTDOUBLESPACEPERIOD =
- new LogStatement("RichInputConnectionRevertDoubleSpacePeriod", false, false);
- public static void richInputConnection_revertDoubleSpacePeriod() {
- final ResearchLogger researchLogger = getInstance();
- // An extra LogUnit is added for the period; this is removed here because of the revert.
- researchLogger.uncommitCurrentLogUnit(null, true /* dumpCurrentLogUnit */);
- // TODO: This will probably be lost as the user backspaces further. Figure out how to put
- // it into the right logUnit.
- researchLogger.enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_REVERTDOUBLESPACEPERIOD);
- }
-
- /**
- * Log a call to RichInputConnection.revertSwapPunctuation().
- *
- * SystemResponse: The IME has reverted a punctuation swap.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_REVERTSWAPPUNCTUATION =
- new LogStatement("RichInputConnectionRevertSwapPunctuation", false, false);
- public static void richInputConnection_revertSwapPunctuation() {
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_REVERTSWAPPUNCTUATION);
- }
-
- /**
- * Log a call to LatinIME.commitCurrentAutoCorrection().
- *
- * SystemResponse: The IME has committed an auto-correction. An auto-correction changes the raw
- * text input to another word (or words) that the user more likely desired to type.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION =
- new LogStatement("LatinIMECommitCurrentAutoCorrection", true, true, "typedWord",
- "autoCorrection", "separatorString");
- public static void latinIme_commitCurrentAutoCorrection(final String typedWord,
- final String autoCorrection, final String separatorString, final boolean isBatchMode,
- final SuggestedWords suggestedWords) {
- final String scrubbedTypedWord = scrubDigitsFromString(typedWord);
- final String scrubbedAutoCorrection = scrubDigitsFromString(autoCorrection);
- final ResearchLogger researchLogger = getInstance();
- researchLogger.mCurrentLogUnit.initializeSuggestions(suggestedWords);
- researchLogger.onWordFinished(scrubbedAutoCorrection, isBatchMode);
-
- // Add the autocorrection logStatement at the end of the logUnit for the committed word.
- // We have to do this after calling commitCurrentLogUnitAsWord, because it may split the
- // current logUnit, and then we have to peek to get the logUnit reference back.
- final LogUnit logUnit = researchLogger.mMainLogBuffer.peekLastLogUnit();
- // TODO: Add test to confirm that the commitCurrentAutoCorrection log statement should
- // always be added to logUnit (if non-null) and not mCurrentLogUnit.
- researchLogger.enqueueEvent(logUnit, LOGSTATEMENT_LATINIME_COMMITCURRENTAUTOCORRECTION,
- scrubbedTypedWord, scrubbedAutoCorrection, separatorString);
- }
-
- private boolean isExpectingCommitText = false;
-
- /**
- * Log a call to RichInputConnection.commitText().
- *
- * SystemResponse: The IME is committing text. This happens after the user has typed a word
- * and then a space or punctuation key.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTIONCOMMITTEXT =
- new LogStatement("RichInputConnectionCommitText", true, false, "newCursorPosition");
- public static void richInputConnection_commitText(final String committedWord,
- final int newCursorPosition, final boolean isBatchMode) {
- final ResearchLogger researchLogger = getInstance();
- // Only include opening and closing logSegments if private data is included
- final String scrubbedWord = scrubDigitsFromString(committedWord);
- if (!researchLogger.isExpectingCommitText) {
- researchLogger.enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTIONCOMMITTEXT,
- newCursorPosition);
- researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode);
- }
- researchLogger.isExpectingCommitText = false;
- }
-
- /**
- * Shared events for logging committed text.
- *
- * The "CommitTextEventHappened" LogStatement is written to the log even if privacy rules
- * indicate that the word contents should not be logged. It has no contents, and only serves to
- * record the event and thereby make it easier to calculate word-level statistics even when the
- * word contents are unknown.
- */
- private static final LogStatement LOGSTATEMENT_COMMITTEXT =
- new LogStatement("CommitText", true /* isPotentiallyPrivate */,
- false /* isPotentiallyRevealing */, "committedText", "isBatchMode");
- private static final LogStatement LOGSTATEMENT_COMMITTEXT_EVENT_HAPPENED =
- new LogStatement("CommitTextEventHappened", false /* isPotentiallyPrivate */,
- false /* isPotentiallyRevealing */);
- private void enqueueCommitText(final String word, final boolean isBatchMode) {
- // Event containing the word; will be published only if privacy checks pass
- enqueueEvent(LOGSTATEMENT_COMMITTEXT, word, isBatchMode);
- // Event not containing the word; will always be published
- enqueueEvent(LOGSTATEMENT_COMMITTEXT_EVENT_HAPPENED);
- }
-
- /**
- * Log a call to RichInputConnection.deleteSurroundingText().
- *
- * SystemResponse: The IME has deleted text.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT =
- new LogStatement("RichInputConnectionDeleteSurroundingText", true, false,
- "beforeLength", "afterLength");
- public static void richInputConnection_deleteSurroundingText(final int beforeLength,
- final int afterLength) {
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_DELETESURROUNDINGTEXT,
- beforeLength, afterLength);
- }
-
- /**
- * Log a call to RichInputConnection.finishComposingText().
- *
- * SystemResponse: The IME has left the composing text as-is.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_FINISHCOMPOSINGTEXT =
- new LogStatement("RichInputConnectionFinishComposingText", false, false);
- public static void richInputConnection_finishComposingText() {
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_FINISHCOMPOSINGTEXT);
- }
-
- /**
- * Log a call to RichInputConnection.performEditorAction().
- *
- * SystemResponse: The IME is invoking an action specific to the editor.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_PERFORMEDITORACTION =
- new LogStatement("RichInputConnectionPerformEditorAction", false, false,
- "imeActionId");
- public static void richInputConnection_performEditorAction(final int imeActionId) {
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_PERFORMEDITORACTION,
- imeActionId);
- }
-
- /**
- * Log a call to RichInputConnection.sendKeyEvent().
- *
- * SystemResponse: The IME is telling the TextView that a key is being pressed through an
- * alternate channel.
- * TODO: only for hardware keys?
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_SENDKEYEVENT =
- new LogStatement("RichInputConnectionSendKeyEvent", true, false, "eventTime", "action",
- "code");
- public static void richInputConnection_sendKeyEvent(final KeyEvent keyEvent) {
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_SENDKEYEVENT,
- keyEvent.getEventTime(), keyEvent.getAction(), keyEvent.getKeyCode());
- }
-
- /**
- * Log a call to RichInputConnection.setComposingText().
- *
- * SystemResponse: The IME is setting the composing text. Happens each time a character is
- * entered.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_SETCOMPOSINGTEXT =
- new LogStatement("RichInputConnectionSetComposingText", true, true, "text",
- "newCursorPosition");
- public static void richInputConnection_setComposingText(final CharSequence text,
- final int newCursorPosition) {
- if (text == null) {
- throw new RuntimeException("setComposingText is null");
- }
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_SETCOMPOSINGTEXT, text,
- newCursorPosition);
- }
-
- /**
- * Log a call to RichInputConnection.setSelection().
- *
- * SystemResponse: The IME is requesting that the selection change. User-initiated selection-
- * change requests do not go through this method -- it's only when the system wants to change
- * the selection.
- */
- private static final LogStatement LOGSTATEMENT_RICHINPUTCONNECTION_SETSELECTION =
- new LogStatement("RichInputConnectionSetSelection", true, false, "from", "to");
- public static void richInputConnection_setSelection(final int from, final int to) {
- getInstance().enqueueEvent(LOGSTATEMENT_RICHINPUTCONNECTION_SETSELECTION, from, to);
- }
-
- /**
- * Log a call to SuddenJumpingTouchEventHandler.onTouchEvent().
- *
- * SystemResponse: The IME has filtered input events in case of an erroneous sensor reading.
- */
- private static final LogStatement LOGSTATEMENT_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT =
- new LogStatement("SuddenJumpingTouchEventHandlerOnTouchEvent", true, false,
- "motionEvent");
- public static void suddenJumpingTouchEventHandler_onTouchEvent(final MotionEvent me) {
- if (me != null) {
- getInstance().enqueueEvent(LOGSTATEMENT_SUDDENJUMPINGTOUCHEVENTHANDLER_ONTOUCHEVENT,
- MotionEvent.obtain(me));
- }
- }
-
- /**
- * Log a call to SuggestionsView.setSuggestions().
- *
- * SystemResponse: The IME is setting the suggestions in the suggestion strip.
- */
- private static final LogStatement LOGSTATEMENT_SUGGESTIONSTRIPVIEW_SETSUGGESTIONS =
- new LogStatement("SuggestionStripViewSetSuggestions", true, true, "suggestedWords");
- public static void suggestionStripView_setSuggestions(final SuggestedWords suggestedWords) {
- if (suggestedWords != null) {
- getInstance().enqueueEvent(LOGSTATEMENT_SUGGESTIONSTRIPVIEW_SETSUGGESTIONS,
- suggestedWords);
- }
- }
-
- /**
- * The user has indicated a particular point in the log that is of interest.
- *
- * UserAction: From direct menu invocation.
- */
- private static final LogStatement LOGSTATEMENT_USER_TIMESTAMP =
- new LogStatement("UserTimestamp", false, false);
- public void userTimestamp() {
- getInstance().enqueueEvent(LOGSTATEMENT_USER_TIMESTAMP);
- }
-
- /**
- * Log a call to LatinIME.onEndBatchInput().
- *
- * SystemResponse: The system has completed a gesture.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_ONENDBATCHINPUT =
- new LogStatement("LatinIMEOnEndBatchInput", true, false, "enteredText",
- "enteredWordPos", "suggestedWords");
- public static void latinIME_onEndBatchInput(final CharSequence enteredText,
- final int enteredWordPos, final SuggestedWords suggestedWords) {
- final ResearchLogger researchLogger = getInstance();
- if (!TextUtils.isEmpty(enteredText) && hasLetters(enteredText.toString())) {
- researchLogger.mCurrentLogUnit.setWords(enteredText.toString());
- }
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONENDBATCHINPUT, enteredText,
- enteredWordPos, suggestedWords);
- researchLogger.mCurrentLogUnit.initializeSuggestions(suggestedWords);
- researchLogger.mStatistics.recordGestureInput(enteredText.length(),
- SystemClock.uptimeMillis());
- }
-
- private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE =
- new LogStatement("LatinIMEHandleBackspace", true, false, "numCharacters");
- /**
- * Log a call to LatinIME.handleBackspace() that is not a batch delete.
- *
- * UserInput: The user is deleting one or more characters by hitting the backspace key once.
- * The covers single character deletes as well as deleting selections.
- *
- * @param numCharacters how many characters the backspace operation deleted
- * @param shouldUncommitLogUnit whether to uncommit the last {@code LogUnit} in the
- * {@code LogBuffer}
- */
- public static void latinIME_handleBackspace(final int numCharacters,
- final boolean shouldUncommitLogUnit) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE, numCharacters);
- if (shouldUncommitLogUnit) {
- ResearchLogger.getInstance().uncommitCurrentLogUnit(
- null, true /* dumpCurrentLogUnit */);
- }
- }
-
- /**
- * Log a call to LatinIME.handleBackspace() that is a batch delete.
- *
- * UserInput: The user is deleting a gestured word by hitting the backspace key once.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH =
- new LogStatement("LatinIMEHandleBackspaceBatch", true, false, "deletedText",
- "numCharacters");
- public static void latinIME_handleBackspace_batch(final CharSequence deletedText,
- final int numCharacters) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLEBACKSPACE_BATCH, deletedText,
- numCharacters);
- researchLogger.mStatistics.recordGestureDelete(deletedText.length(),
- SystemClock.uptimeMillis());
- researchLogger.uncommitCurrentLogUnit(deletedText.toString(),
- false /* dumpCurrentLogUnit */);
- }
-
- /**
- * Log a long interval between user operation.
- *
- * UserInput: The user has not done anything for a while.
- */
- private static final LogStatement LOGSTATEMENT_ONUSERPAUSE = new LogStatement("OnUserPause",
- false, false, "intervalInMs");
- public static void onUserPause(final long interval) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_ONUSERPAUSE, interval);
- }
-
- /**
- * Record the current time in case the LogUnit is later split.
- *
- * If the current logUnit is split, then tapping, motion events, etc. before this time should
- * be assigned to one LogUnit, and events after this time should go into the following LogUnit.
- */
- public static void recordTimeForLogUnitSplit() {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.setSavedDownEventTime(SystemClock.uptimeMillis());
- researchLogger.mSavedDownEventTime = Long.MAX_VALUE;
- }
-
- /**
- * Log a call to LatinIME.handleSeparator()
- *
- * SystemResponse: The system is inserting a separator character, possibly performing auto-
- * correction or other actions appropriate at the end of a word.
- */
- private static final LogStatement LOGSTATEMENT_LATINIME_HANDLESEPARATOR =
- new LogStatement("LatinIMEHandleSeparator", false, false, "primaryCode",
- "isComposingWord");
- public static void latinIME_handleSeparator(final int primaryCode,
- final boolean isComposingWord) {
- final ResearchLogger researchLogger = getInstance();
- researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_HANDLESEPARATOR, primaryCode,
- isComposingWord);
- }
-
- /**
- * Call this method when the logging system has attempted publication of an n-gram.
- *
- * Statistics are gathered about the success or failure.
- *
- * @param publishabilityResultCode a result code as defined by
- * {@code MainLogBuffer.PUBLISHABILITY_*}
- */
- static void recordPublishabilityResultCode(final int publishabilityResultCode) {
- final ResearchLogger researchLogger = getInstance();
- final Statistics statistics = researchLogger.mStatistics;
- statistics.recordPublishabilityResultCode(publishabilityResultCode);
- }
-
- /**
- * Log statistics.
- *
- * ContextualData, recorded at the end of a session.
- */
- private static final LogStatement LOGSTATEMENT_STATISTICS =
- new LogStatement("Statistics", false, false, "charCount", "letterCount", "numberCount",
- "spaceCount", "deleteOpsCount", "wordCount", "isEmptyUponStarting",
- "isEmptinessStateKnown", "averageTimeBetweenKeys", "averageTimeBeforeDelete",
- "averageTimeDuringRepeatedDelete", "averageTimeAfterDelete",
- "dictionaryWordCount", "splitWordsCount", "gestureInputCount",
- "gestureCharsCount", "gesturesDeletedCount", "manualSuggestionsCount",
- "revertCommitsCount", "correctedWordsCount", "autoCorrectionsCount",
- "publishableCount", "unpublishableStoppingCount",
- "unpublishableIncorrectWordCount", "unpublishableSampledTooRecentlyCount",
- "unpublishableDictionaryUnavailableCount", "unpublishableMayContainDigitCount",
- "unpublishableNotInDictionaryCount");
- private static void logStatistics() {
- final ResearchLogger researchLogger = getInstance();
- final Statistics statistics = researchLogger.mStatistics;
- researchLogger.enqueueEvent(LOGSTATEMENT_STATISTICS, statistics.mCharCount,
- statistics.mLetterCount, statistics.mNumberCount, statistics.mSpaceCount,
- statistics.mDeleteKeyCount, statistics.mWordCount, statistics.mIsEmptyUponStarting,
- statistics.mIsEmptinessStateKnown, statistics.mKeyCounter.getAverageTime(),
- statistics.mBeforeDeleteKeyCounter.getAverageTime(),
- statistics.mDuringRepeatedDeleteKeysCounter.getAverageTime(),
- statistics.mAfterDeleteKeyCounter.getAverageTime(),
- statistics.mDictionaryWordCount, statistics.mSplitWordsCount,
- statistics.mGesturesInputCount, statistics.mGesturesCharsCount,
- statistics.mGesturesDeletedCount, statistics.mManualSuggestionsCount,
- statistics.mRevertCommitsCount, statistics.mCorrectedWordsCount,
- statistics.mAutoCorrectionsCount, statistics.mPublishableCount,
- statistics.mUnpublishableStoppingCount, statistics.mUnpublishableIncorrectWordCount,
- statistics.mUnpublishableSampledTooRecently,
- statistics.mUnpublishableDictionaryUnavailable,
- statistics.mUnpublishableMayContainDigit, statistics.mUnpublishableNotInDictionary);
- }
-}
diff --git a/java/src/com/android/inputmethod/research/ResearchSettings.java b/java/src/com/android/inputmethod/research/ResearchSettings.java
deleted file mode 100644
index c0bc03fde..000000000
--- a/java/src/com/android/inputmethod/research/ResearchSettings.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.content.SharedPreferences;
-
-import java.util.UUID;
-
-public final class ResearchSettings {
- public static final String PREF_RESEARCH_LOGGER_UUID = "pref_research_logger_uuid";
- public static final String PREF_RESEARCH_LOGGER_ENABLED_FLAG =
- "pref_research_logger_enabled_flag";
- public static final String PREF_RESEARCH_LOGGER_HAS_SEEN_SPLASH =
- "pref_research_logger_has_seen_splash";
- public static final String PREF_RESEARCH_LAST_DIR_CLEANUP_TIME =
- "pref_research_last_dir_cleanup_time";
-
- private ResearchSettings() {
- // Intentional empty constructor for singleton.
- }
-
- public static String readResearchLoggerUuid(final SharedPreferences prefs) {
- if (prefs.contains(PREF_RESEARCH_LOGGER_UUID)) {
- return prefs.getString(PREF_RESEARCH_LOGGER_UUID, null);
- }
- // Generate a random string as uuid if not yet set
- final String newUuid = UUID.randomUUID().toString();
- prefs.edit().putString(PREF_RESEARCH_LOGGER_UUID, newUuid).apply();
- return newUuid;
- }
-
- public static boolean readResearchLoggerEnabledFlag(final SharedPreferences prefs) {
- return prefs.getBoolean(PREF_RESEARCH_LOGGER_ENABLED_FLAG, false);
- }
-
- public static void writeResearchLoggerEnabledFlag(final SharedPreferences prefs,
- final boolean isEnabled) {
- prefs.edit().putBoolean(PREF_RESEARCH_LOGGER_ENABLED_FLAG, isEnabled).apply();
- }
-
- public static boolean readHasSeenSplash(final SharedPreferences prefs) {
- return prefs.getBoolean(PREF_RESEARCH_LOGGER_HAS_SEEN_SPLASH, false);
- }
-
- public static void writeHasSeenSplash(final SharedPreferences prefs,
- final boolean hasSeenSplash) {
- prefs.edit().putBoolean(PREF_RESEARCH_LOGGER_HAS_SEEN_SPLASH, hasSeenSplash).apply();
- }
-
- public static long readResearchLastDirCleanupTime(final SharedPreferences prefs) {
- return prefs.getLong(PREF_RESEARCH_LAST_DIR_CLEANUP_TIME, 0L);
- }
-
- public static void writeResearchLastDirCleanupTime(final SharedPreferences prefs,
- final long lastDirCleanupTime) {
- prefs.edit().putLong(PREF_RESEARCH_LAST_DIR_CLEANUP_TIME, lastDirCleanupTime).apply();
- }
-}
diff --git a/java/src/com/android/inputmethod/research/Statistics.java b/java/src/com/android/inputmethod/research/Statistics.java
deleted file mode 100644
index fd323a104..000000000
--- a/java/src/com/android/inputmethod/research/Statistics.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.util.Log;
-
-import com.android.inputmethod.latin.Constants;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.util.concurrent.TimeUnit;
-
-public class Statistics {
- private static final String TAG = Statistics.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
-
- // TODO: Cleanup comments to only including those giving meaningful information.
- // Number of characters entered during a typing session
- int mCharCount;
- // Number of letter characters entered during a typing session
- int mLetterCount;
- // Number of number characters entered
- int mNumberCount;
- // Number of space characters entered
- int mSpaceCount;
- // Number of delete operations entered (taps on the backspace key)
- int mDeleteKeyCount;
- // Number of words entered during a session.
- int mWordCount;
- // Number of words found in the dictionary.
- int mDictionaryWordCount;
- // Number of words split and spaces automatically entered.
- int mSplitWordsCount;
- // Number of words entered during a session.
- int mCorrectedWordsCount;
- // Number of gestures that were input.
- int mGesturesInputCount;
- // Number of gestures that were deleted.
- int mGesturesDeletedCount;
- // Total number of characters in words entered by gesture.
- int mGesturesCharsCount;
- // Number of manual suggestions chosen.
- int mManualSuggestionsCount;
- // Number of times that autocorrection was invoked.
- int mAutoCorrectionsCount;
- // Number of times a commit was reverted in this session.
- int mRevertCommitsCount;
- // Whether the text field was empty upon editing
- boolean mIsEmptyUponStarting;
- boolean mIsEmptinessStateKnown;
-
- // Counts of how often an n-gram is collected or not, and the reasons for the decision.
- // Keep consistent with publishability result code list in MainLogBuffer
- int mPublishableCount;
- int mUnpublishableStoppingCount;
- int mUnpublishableIncorrectWordCount;
- int mUnpublishableSampledTooRecently;
- int mUnpublishableDictionaryUnavailable;
- int mUnpublishableMayContainDigit;
- int mUnpublishableNotInDictionary;
-
- // Timers to count average time to enter a key, first press a delete key,
- // between delete keys, and then to return typing after a delete key.
- final AverageTimeCounter mKeyCounter = new AverageTimeCounter();
- final AverageTimeCounter mBeforeDeleteKeyCounter = new AverageTimeCounter();
- final AverageTimeCounter mDuringRepeatedDeleteKeysCounter = new AverageTimeCounter();
- final AverageTimeCounter mAfterDeleteKeyCounter = new AverageTimeCounter();
-
- static class AverageTimeCounter {
- int mCount;
- int mTotalTime;
-
- public void reset() {
- mCount = 0;
- mTotalTime = 0;
- }
-
- public void add(long deltaTime) {
- mCount++;
- mTotalTime += deltaTime;
- }
-
- public int getAverageTime() {
- if (mCount == 0) {
- return 0;
- }
- return mTotalTime / mCount;
- }
- }
-
- // To account for the interruptions when the user's attention is directed elsewhere, times
- // longer than MIN_TYPING_INTERMISSION are not counted when estimating this statistic.
- public static final long MIN_TYPING_INTERMISSION = TimeUnit.SECONDS.toMillis(2);
- public static final long MIN_DELETION_INTERMISSION = TimeUnit.SECONDS.toMillis(10);
-
- // The last time that a tap was performed
- private long mLastTapTime;
- // The type of the last keypress (delete key or not)
- boolean mIsLastKeyDeleteKey;
-
- private static final Statistics sInstance = new Statistics();
-
- public static Statistics getInstance() {
- return sInstance;
- }
-
- private Statistics() {
- reset();
- }
-
- public void reset() {
- mCharCount = 0;
- mLetterCount = 0;
- mNumberCount = 0;
- mSpaceCount = 0;
- mDeleteKeyCount = 0;
- mWordCount = 0;
- mDictionaryWordCount = 0;
- mSplitWordsCount = 0;
- mCorrectedWordsCount = 0;
- mGesturesInputCount = 0;
- mGesturesDeletedCount = 0;
- mManualSuggestionsCount = 0;
- mRevertCommitsCount = 0;
- mAutoCorrectionsCount = 0;
- mIsEmptyUponStarting = true;
- mIsEmptinessStateKnown = false;
- mKeyCounter.reset();
- mBeforeDeleteKeyCounter.reset();
- mDuringRepeatedDeleteKeysCounter.reset();
- mAfterDeleteKeyCounter.reset();
- mGesturesCharsCount = 0;
- mGesturesDeletedCount = 0;
- mPublishableCount = 0;
- mUnpublishableStoppingCount = 0;
- mUnpublishableIncorrectWordCount = 0;
- mUnpublishableSampledTooRecently = 0;
- mUnpublishableDictionaryUnavailable = 0;
- mUnpublishableMayContainDigit = 0;
- mUnpublishableNotInDictionary = 0;
-
- mLastTapTime = 0;
- mIsLastKeyDeleteKey = false;
- }
-
- public void recordChar(int codePoint, long time) {
- if (DEBUG) {
- Log.d(TAG, "recordChar() called");
- }
- if (codePoint == Constants.CODE_DELETE) {
- mDeleteKeyCount++;
- recordUserAction(time, true /* isDeletion */);
- } else {
- mCharCount++;
- if (Character.isDigit(codePoint)) {
- mNumberCount++;
- }
- if (Character.isLetter(codePoint)) {
- mLetterCount++;
- }
- if (Character.isSpaceChar(codePoint)) {
- mSpaceCount++;
- }
- recordUserAction(time, false /* isDeletion */);
- }
- }
-
- public void recordWordEntered(final boolean isDictionaryWord,
- final boolean containsCorrection) {
- mWordCount++;
- if (isDictionaryWord) {
- mDictionaryWordCount++;
- }
- if (containsCorrection) {
- mCorrectedWordsCount++;
- }
- }
-
- public void recordSplitWords() {
- mSplitWordsCount++;
- }
-
- public void recordGestureInput(final int numCharsEntered, final long time) {
- mGesturesInputCount++;
- mGesturesCharsCount += numCharsEntered;
- recordUserAction(time, false /* isDeletion */);
- }
-
- public void setIsEmptyUponStarting(final boolean isEmpty) {
- mIsEmptyUponStarting = isEmpty;
- mIsEmptinessStateKnown = true;
- }
-
- public void recordGestureDelete(final int length, final long time) {
- mGesturesDeletedCount++;
- recordUserAction(time, true /* isDeletion */);
- }
-
- public void recordManualSuggestion(final long time) {
- mManualSuggestionsCount++;
- recordUserAction(time, false /* isDeletion */);
- }
-
- public void recordAutoCorrection(final long time) {
- mAutoCorrectionsCount++;
- recordUserAction(time, false /* isDeletion */);
- }
-
- public void recordRevertCommit(final long time) {
- mRevertCommitsCount++;
- recordUserAction(time, true /* isDeletion */);
- }
-
- private void recordUserAction(final long time, final boolean isDeletion) {
- final long delta = time - mLastTapTime;
- if (isDeletion) {
- if (delta < MIN_DELETION_INTERMISSION) {
- if (mIsLastKeyDeleteKey) {
- mDuringRepeatedDeleteKeysCounter.add(delta);
- } else {
- mBeforeDeleteKeyCounter.add(delta);
- }
- } else {
- ResearchLogger.onUserPause(delta);
- }
- } else {
- if (mIsLastKeyDeleteKey && delta < MIN_DELETION_INTERMISSION) {
- mAfterDeleteKeyCounter.add(delta);
- } else if (!mIsLastKeyDeleteKey && delta < MIN_TYPING_INTERMISSION) {
- mKeyCounter.add(delta);
- } else {
- ResearchLogger.onUserPause(delta);
- }
- }
- mIsLastKeyDeleteKey = isDeletion;
- mLastTapTime = time;
- }
-
- public void recordPublishabilityResultCode(final int publishabilityResultCode) {
- // Keep consistent with publishability result code list in MainLogBuffer
- switch (publishabilityResultCode) {
- case MainLogBuffer.PUBLISHABILITY_PUBLISHABLE:
- mPublishableCount++;
- break;
- case MainLogBuffer.PUBLISHABILITY_UNPUBLISHABLE_STOPPING:
- mUnpublishableStoppingCount++;
- break;
- case MainLogBuffer.PUBLISHABILITY_UNPUBLISHABLE_INCORRECT_WORD_COUNT:
- mUnpublishableIncorrectWordCount++;
- break;
- case MainLogBuffer.PUBLISHABILITY_UNPUBLISHABLE_SAMPLED_TOO_RECENTLY:
- mUnpublishableSampledTooRecently++;
- break;
- case MainLogBuffer.PUBLISHABILITY_UNPUBLISHABLE_DICTIONARY_UNAVAILABLE:
- mUnpublishableDictionaryUnavailable++;
- break;
- case MainLogBuffer.PUBLISHABILITY_UNPUBLISHABLE_MAY_CONTAIN_DIGIT:
- mUnpublishableMayContainDigit++;
- break;
- case MainLogBuffer.PUBLISHABILITY_UNPUBLISHABLE_NOT_IN_DICTIONARY:
- mUnpublishableNotInDictionary++;
- break;
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/research/Uploader.java b/java/src/com/android/inputmethod/research/Uploader.java
deleted file mode 100644
index c7ea3e69d..000000000
--- a/java/src/com/android/inputmethod/research/Uploader.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.os.BatteryManager;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.define.ProductionFlag;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-/**
- * Manages the uploading of ResearchLog files.
- */
-public final class Uploader {
- private static final String TAG = Uploader.class.getSimpleName();
- private static final boolean DEBUG = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- // Set IS_INHIBITING_AUTO_UPLOAD to true for local testing
- private static final boolean IS_INHIBITING_UPLOAD = false
- && ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS_DEBUG;
- private static final int BUF_SIZE = 1024 * 8;
-
- private final Context mContext;
- private final ResearchLogDirectory mResearchLogDirectory;
- private final URL mUrl;
-
- public Uploader(final Context context) {
- mContext = context;
- mResearchLogDirectory = new ResearchLogDirectory(context);
-
- final String urlString = context.getString(R.string.research_logger_upload_url);
- if (TextUtils.isEmpty(urlString)) {
- mUrl = null;
- return;
- }
- URL url = null;
- try {
- url = new URL(urlString);
- } catch (final MalformedURLException e) {
- Log.e(TAG, "Bad URL for uploading", e);
- }
- mUrl = url;
- }
-
- public boolean isPossibleToUpload() {
- return hasUploadingPermission() && mUrl != null && !IS_INHIBITING_UPLOAD;
- }
-
- private boolean hasUploadingPermission() {
- final PackageManager packageManager = mContext.getPackageManager();
- return packageManager.checkPermission(Manifest.permission.INTERNET,
- mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED;
- }
-
- public boolean isConvenientToUpload() {
- return isExternallyPowered() && hasWifiConnection();
- }
-
- private boolean isExternallyPowered() {
- final Intent intent = mContext.registerReceiver(null, new IntentFilter(
- Intent.ACTION_BATTERY_CHANGED));
- final int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
- return pluggedState == BatteryManager.BATTERY_PLUGGED_AC
- || pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
- }
-
- private boolean hasWifiConnection() {
- final ConnectivityManager manager =
- (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- final NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
- return wifiInfo.isConnected();
- }
-
- public void doUpload() {
- final File[] files = mResearchLogDirectory.getUploadableLogFiles();
- if (files == null) return;
- for (final File file : files) {
- uploadFile(file);
- }
- }
-
- private void uploadFile(final File file) {
- if (DEBUG) {
- Log.d(TAG, "attempting upload of " + file.getAbsolutePath());
- }
- final int contentLength = (int) file.length();
- HttpURLConnection connection = null;
- InputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(file);
- connection = (HttpURLConnection) mUrl.openConnection();
- connection.setRequestMethod("PUT");
- connection.setDoOutput(true);
- connection.setFixedLengthStreamingMode(contentLength);
- final OutputStream outputStream = connection.getOutputStream();
- uploadContents(fileInputStream, outputStream);
- if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
- Log.d(TAG, "upload failed: " + connection.getResponseCode());
- final InputStream netInputStream = connection.getInputStream();
- final BufferedReader reader = new BufferedReader(new InputStreamReader(
- netInputStream));
- String line;
- while ((line = reader.readLine()) != null) {
- Log.d(TAG, "| " + reader.readLine());
- }
- reader.close();
- return;
- }
- file.delete();
- if (DEBUG) {
- Log.d(TAG, "upload successful");
- }
- } catch (final IOException e) {
- Log.e(TAG, "Exception uploading file", e);
- } finally {
- if (fileInputStream != null) {
- try {
- fileInputStream.close();
- } catch (final IOException e) {
- Log.e(TAG, "Exception closing uploaded file", e);
- }
- }
- if (connection != null) {
- connection.disconnect();
- }
- }
- }
-
- private static void uploadContents(final InputStream is, final OutputStream os)
- throws IOException {
- // TODO: Switch to NIO.
- final byte[] buf = new byte[BUF_SIZE];
- int numBytesRead;
- while ((numBytesRead = is.read(buf)) != -1) {
- os.write(buf, 0, numBytesRead);
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/research/UploaderService.java b/java/src/com/android/inputmethod/research/UploaderService.java
deleted file mode 100644
index fd3f2f60e..000000000
--- a/java/src/com/android/inputmethod/research/UploaderService.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research;
-
-import android.app.AlarmManager;
-import android.app.IntentService;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.SystemClock;
-
-/**
- * Service to invoke the uploader.
- *
- * Can be regularly invoked, invoked on boot, etc.
- */
-public final class UploaderService extends IntentService {
- private static final String TAG = UploaderService.class.getSimpleName();
- public static final long RUN_INTERVAL = AlarmManager.INTERVAL_HOUR;
- public static final String EXTRA_UPLOAD_UNCONDITIONALLY = UploaderService.class.getName()
- + ".extra.UPLOAD_UNCONDITIONALLY";
-
- public UploaderService() {
- super("Research Uploader Service");
- }
-
- @Override
- protected void onHandleIntent(final Intent intent) {
- // We may reach this point either because the alarm fired, or because the system explicitly
- // requested that an Upload occur. In the latter case, we want to cancel the alarm in case
- // it's about to fire.
- cancelAndRescheduleUploadingService(this, false /* needsRescheduling */);
-
- final Uploader uploader = new Uploader(this);
- if (!uploader.isPossibleToUpload()) return;
- if (isUploadingUnconditionally(intent.getExtras()) || uploader.isConvenientToUpload()) {
- uploader.doUpload();
- }
- cancelAndRescheduleUploadingService(this, true /* needsRescheduling */);
- }
-
- private boolean isUploadingUnconditionally(final Bundle bundle) {
- if (bundle == null) return false;
- if (bundle.containsKey(EXTRA_UPLOAD_UNCONDITIONALLY)) {
- return bundle.getBoolean(EXTRA_UPLOAD_UNCONDITIONALLY);
- }
- return false;
- }
-
- /**
- * Arrange for the UploaderService to be run on a regular basis.
- *
- * Any existing scheduled invocation of UploaderService is removed and optionally rescheduled.
- * This may cause problems if this method is called so often that no scheduled invocation is
- * ever run. But if the delay is short enough that it will go off when the user is sleeping,
- * then there should be no starvation.
- *
- * @param context {@link Context} object
- * @param needsRescheduling whether to schedule a future intent to be delivered to this service
- */
- public static void cancelAndRescheduleUploadingService(final Context context,
- final boolean needsRescheduling) {
- final Intent intent = new Intent(context, UploaderService.class);
- final PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
- final AlarmManager alarmManager = (AlarmManager) context.getSystemService(
- Context.ALARM_SERVICE);
- alarmManager.cancel(pendingIntent);
- if (needsRescheduling) {
- alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
- + UploaderService.RUN_INTERVAL, pendingIntent);
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/research/ui/SplashScreen.java b/java/src/com/android/inputmethod/research/ui/SplashScreen.java
deleted file mode 100644
index 78ed668d1..000000000
--- a/java/src/com/android/inputmethod/research/ui/SplashScreen.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.research.ui;
-
-import android.app.AlertDialog.Builder;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.Intent;
-import android.inputmethodservice.InputMethodService;
-import android.net.Uri;
-import android.os.IBinder;
-import android.view.Window;
-import android.view.WindowManager.LayoutParams;
-
-import com.android.inputmethod.latin.R.string;
-
-/**
- * Show a dialog when the user first opens the keyboard.
- *
- * The splash screen is a modal dialog box presented when the user opens this keyboard for the first
- * time. It is useful for giving specific warnings that must be shown to the user before use.
- *
- * While the splash screen does share with the setup wizard the common goal of presenting
- * information to the user before use, they are presented at different times and with different
- * capabilities. The setup wizard is launched by tapping on the icon, and walks the user through
- * the setup process. It can, however, be bypassed by enabling the keyboard from Settings directly.
- * The splash screen cannot be bypassed, and is therefore more appropriate for obtaining user
- * consent.
- */
-public class SplashScreen {
- public interface UserConsentListener {
- public void onSplashScreenUserClickedOk();
- }
-
- final UserConsentListener mListener;
- final Dialog mSplashDialog;
-
- public SplashScreen(final InputMethodService inputMethodService,
- final UserConsentListener listener) {
- mListener = listener;
- final Builder builder = new Builder(inputMethodService)
- .setTitle(string.research_splash_title)
- .setMessage(string.research_splash_content)
- .setPositiveButton(android.R.string.yes,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mListener.onSplashScreenUserClickedOk();
- mSplashDialog.dismiss();
- }
- })
- .setNegativeButton(android.R.string.no,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final String packageName = inputMethodService.getPackageName();
- final Uri packageUri = Uri.parse("package:" + packageName);
- final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE,
- packageUri);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- inputMethodService.startActivity(intent);
- }
- })
- .setCancelable(true)
- .setOnCancelListener(
- new OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- inputMethodService.requestHideSelf(0);
- }
- });
- mSplashDialog = builder.create();
- }
-
- /**
- * Show the splash screen.
- *
- * The user must consent to the terms presented in the SplashScreen before they can use the
- * keyboard. If they cancel instead, they are given the option to uninstall the keybard.
- *
- * @param windowToken {@link IBinder} to attach dialog to
- */
- public void showSplashScreen(final IBinder windowToken) {
- final Window window = mSplashDialog.getWindow();
- final LayoutParams lp = window.getAttributes();
- lp.token = windowToken;
- lp.type = LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
- window.setAttributes(lp);
- window.addFlags(LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- mSplashDialog.show();
- }
-
- public boolean isShowing() {
- return mSplashDialog.isShowing();
- }
-}